10 Mybatis注解开发 多表查询
复杂关系映射的注解说明
@Results 注解
代替的是标签<resultMap>
该注解中可以使用单个@Result 注解,也可以使用@Result 集合
@Results({@Result(),@Result()})或@Results(@Result())
@Result 注解
代替了 <id> 标签和<result> 标签
@Result 中 属性介绍:
id 是否是主键字段
column 数据库的列名
property 需要装配的属性名
one 需要使用的@One 注解(@Result(one=@One)()))
many 需要使用的@Many 注解(@Result(many=@many)()))
@One 注解(一对一)
代替了<assocation> 标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
@One 注解属性介绍:
select 指定用的 来多表查询的 sqlmapper
fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。。
使用格式:
@Result(column=" ",property="",one=@One(select=""))
@Many 注解(多对一)
代替了<Collection> 标签, 是是多表查询的关键,在注解中用来指定子查询返回对象集合。
注意:聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的 javaType
(一般为 ArrayList)但是注解中可以不定义;
使用格式:
@Result(property="",column="",many=@Many(select=""))
一对一关联映射
查询所有的账户以及他关联的用户信息,一个账户只能对应一个唯一的用户
在Account实体类中加入User
@Data
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//一个账户只可能对应一个用户
private User user;
}
定义Account的mapper
public interface AccountMapper {
//采用延迟加载
@Select("select * from account")
@Results(id = "accountMap",
value = {
@Result(id = true, column = "id", property = "id"),
@Result(column = "uid", property = "uid"),
@Result(column = "money", property = "money"),
@Result(column = "uid",property = "user",one = @One(select = "com.it.mapper.UserMapper.findById",fetchType = FetchType.LAZY))
}
)
List< Account> findAll();
}
解析
@Result(column = "uid",property = "user",one = @One(select = "com.it.mapper.UserMapper.findById",fetchType = FetchType.LAZY))
- @One(select = "com.it.mapper.UserMapper.findById",fetchType = - FetchType.LAZY)) 调用usermapper中的根据id查询的方法,懒加载
- column = "uid" 将account的uid作为查询参数
- property = "user" 查到一个user对象的封装到user属性中
usermapper 中用一个通过userid查询user的接口
@Select("select * from user where id = #{uid}")
@ResultMap("userMap")
User findById(Integer userId);
查询情况
@Test
public void testFindAll(){
List<Account> accounts = accountMapper.findAll();
}
只发出了一条查询语句
输出account
@Test
public void testFindAll(){
List<Account> accounts = accountMapper.findAll();
for(Account a:accounts){
System.out.println(a);
}
}
image.png
此时延迟加载执行了
一对多关联映射
一个用户可以有多个账户
在User实体类中添加Account 的集合
@Data
public class User implements Serializable {
private Integer userId;
private String userName;
private Date userBirthday;
private String userSex;
private String userAddress;
private List<Account> accounts;
}
//查询所有用户以及他关联的账户
@Select("select * from user")
@Results(id="userAccountMap",
value = {
@Result(id = true,column = "id",property="userId"),
@Result(column="username",property="userName"),
@Result(column="sex",property="userSex"),
@Result(column="address",property="userAddress"),
@Result(column="birthday",property="userBirthday"),
@Result(column = "id",property = "accounts",many = @Many(
select = "com.it.mapper.AccountMapper.findByUid",
fetchType = FetchType.LAZY
))
})
List<User> findUserAccountAll();
AccountMapper
@Select("select * from account where uid = #{uid}")
List<Account> findByUid(Integer uid);
查出user 的id之后,再调用accountMapper中的根据uid查询account的方法,去查出account封装到accounts中
@Test
public void testFindAll(){
List<User> users = userMapper.findUserAccountAll();
}
image.png
懒加载,只查询了user没有去查account
当我们输出account时
@Test
public void testFindAll(){
List<User> users = userMapper.findUserAccountAll();
for (User u:users){
System.out.println(u);
}
}
image.png
基于注解的二级缓存
SqlMapperConfig.xml中开启
<!-- 配置二级缓存 -->
<settings>
<!-- 开启二级缓存的支持 -->
<setting name="cacheEnabled" value="true"/>
</settings>
在mapper接口类中添加二级缓存注解
@CacheNamespace(blocking=true)//mybatis 基于注解方式实现配置二级缓存
public interface UserMapper {