Java 企业级应用开发 part 2 - J2EE part 2

MyBatis 注解的使用

  • annotations

@Select

WorkerMapper.java
1
2
3
4
5
6
7
8
9
package com.itheima.dao;

import com.itheima.pojo.Worker;
import org.apache.ibatis.annotations.*;

public interface WorkerMapper {
@Select("select * from tb_worker where id = #{id}")
Worker selectWorker(int id);
}

这是一个 DAO 层,通过 interface 的形式直接在函数签名上标注 annotation,进行查询,通过如下方式,从 session 上首先获取 mapper,随后调用接口进行查询操作

1
2
3
4
5
6
7
8
9
10
public void findWorkerByIdTest() {
// 1.通过工具类获取SqlSession对象
SqlSession session = MyBatisUtils.getSession();
WorkerMapper mapper = session.getMapper(WorkerMapper.class);
// 2.使用WorkerMapper对象查询id为1的员工的信息
Worker worker = mapper.selectWorker(1);
System.out.println(worker.toString());
// 3.关闭SqlSession
session.close();
}

对于 @Insert @Update @Delete 等注解也是类似的使用方法

@Param

WorkerMapper.java
1
2
3
4
5
6
7
8
9
package com.itheima.dao;

import com.itheima.pojo.Worker;
import org.apache.ibatis.annotations.*;

public interface WorkerMapper {
@Select("select * from tb_worker where id = #{param01} and name = #{param02}")
Worker selectWorkerByIdAndName(@Param("param01") int id, @Param("param02") String name);
}

@Param 注解标注后面跟着的形参的参数名称,用于注入 SQL 语句中,依旧可以通过类似的方法进行调用

1
2
3
4
5
6
7
8
9
public void selectWorkerByIdAndNameTest() {
// 1.通过工具类生成SqlSession对象
SqlSession session = MyBatisUtils.getSession();
WorkerMapper mapper = session.getMapper(WorkerMapper.class);
// 2.查询id为3姓名为王五的员工的信息
Worker worker = mapper.selectWorkerByIdAndName(3, "王五");
System.out.println(worker.toString());
session.close();
}

@Results & @One

通过 @One 来实现一对一查询的注解

PersonMapper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.itheima.dao;

import com.itheima.pojo.Person;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

public interface PersonMapper {
@Select("select * from tb_person where id=#{id}")
@Results({@Result(column = "card_id", property = "card",
one = @One(select =
"com.itheima.dao.IdCardMapper.selectIdCardById"))})
Person selectPersonById(int id);
}

首先,使用 @Results 以及 @Result 实际上是 result map,我们通过 column 指定外键的数据库字段,以及结果映射到的成员名 property,最后通过 one 参数指定具体的对象
这个例子中,我们通过 @One 指定了一个 select 查询,其将使用 @Result 中的 column 参数值进行查询,因此这里是二次查询

这里的 @Results 内没有完整指定所有字段,实际上是因为 MyBatis 有自动映射,这里只手工指定 card 成员的映射

事实上我们可以通过连接查询的方式一次获取并封装

1
2
3
4
5
6
7
8
9
10
11
@Select("SELECT p.id, p.name, p.age, p.sex, p.card_id, c.id AS card_id, c.CODE AS card_code FROM tb_person p LEFT JOIN tb_idcard c ON p.card_id = c.id WHERE p.id = #{id}")
@Results({
// 直接映射关联的 IdCard 对象,无需二次查询
@Result(
property = "card",
javaType = IdCard.class,
column = "card_id",
one = @One(resultMap = "com.itheima.dao.IdCardMapper.IdCardResultMap")
)
})
Person selectPersonByIdOneShot(int id);

其中 IdCardResultMap 定义如下

IdCardMapper.java
1
2
3
4
5
6
7
8
public interface IdCardMapper {
@Results(id = "IdCardResultMap", value = {
@Result(column = "card_id", property = "id"),
@Result(column = "card_code", property = "code")
})
@Select("select * from tb_idcard where id=#{id}")
IdCard selectIdCardById(int id);
}

这里修饰的函数实际上任意的,只是因为 @Results 注解需要一个 id 来标识这个 result map,因此这里直接放在了查询函数上,当然也可以放在接口的任意位置

这里直接就用 @Results 定义 result map 了

@Many

可以通过 @Many 来实现一对多查询

UsersMapper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.itheima.dao;

import com.itheima.pojo.Users;
import org.apache.ibatis.annotations.*;

public interface UsersMapper {
@Select("select * from tb_user where id=#{id} ")
@Results({@Result(id = true, column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "address", property = "address"),
@Result(column = "id", property = "ordersList",
many = @Many(select =
"com.itheima.dao.OrdersMapper.selectOrdersByUserId"))})
Users selectUserById(int id);
}

通过在 @Result 注解内指定 many 参数,并使用 @Many 注解指定查询方法来实现一对多查询,查询方法的参数会自动传入 column 参数值,因此这里是二次查询

不过我们也可以通过连接查询的方式一次获取并封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.itheima.dao;

import com.itheima.pojo.Users;
import org.apache.ibatis.annotations.*;

public interface UsersMapper {
@Select("select *, o.id as ord_id from tb_user as u, tb_orders as o where u.id = #{id}and u.id = o.user_id ")
@Results({@Result(id = true, column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "address", property = "address"),
@Result(column = "ord_id", property = "ordersList",
many = @Many(resultMap = "com.itheima.mapper.OrdersMapper.OrdersResultMap"))})
Users selectUserByIdOneShot(int id);
}

其中 OrdersResultMap 定义如下

1
2
3
4
<resultMap type="Orders" id="OrdersResultMap">
<id property="id" column="ord_id"/>
<result property="number" column="number"/>
</resultMap>

也可以通过 @many 实现多对多查询

OrdersMapper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.itheima.dao;

import com.itheima.pojo.Orders;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface OrdersMapper {
@Select("select * from tb_orders where id=#{id} ")
@Results({@Result(id = true, column = "id", property = "id"),
@Result(column = "number", property = "number"),
@Result(column = "id", property = "productList",
many = @Many(select =
"com.itheima.dao.ProductMapper.selectProductByOrdersId"))})
Orders selectOrdersById(int id);
}

通过在 @Result 注解内指定 many 参数,并使用 @Many 注解指定查询方法来实现一对多查询,查询方法的参数会自动传入 column 参数值,因此这里也是二次查询

同样的,我们也可以通过连接查询的方式一次获取并封装

1
2
3
4
5
6
@Select("select *, p.id as prd_id from tb_orders as o,tb_product as p where o.id = #{id} and p.id = o.id ")
@Results({@Result(id = true, column = "id", property = "id"),
@Result(column = "number", property = "number"),
@Result(column = "prd_id", property = "productList",
many = @Many(resultMap = "com.itheima.dao.ProductMapper.ProductResultMap"))})
Orders selectOrdersByIdOneShot(int id);

其中 ProductResultMap 定义如下

ProductMapper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.itheima.dao;

import com.itheima.pojo.Product;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface ProductMapper {
@Results(id = "ProductResultMap", value = {@Result(column = "prd_id", property = "id"),
@Result(column = "NAME", property = "name"),
@Result(column = "price", property = "price")
})
@Select("select * from tb_product where id in (select product_id from " +
"tb_ordersitem where orders_id = #{id} )")
List<Product> selectProductByOrdersId(int orders_id);
}