Mybatis入门到精通系列

10 Mybatis注解开发 多表查询

2020-04-25  本文已影响0人  better_future

复杂关系映射的注解说明

@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))

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 {
上一篇 下一篇

猜你喜欢

热点阅读