sunny123456

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

mybatis注解多表查询

回忆:mybatis的多表查询在XML中有两种方式,一是根据根据SQL结果封装对象,二是根据调用其他接口方法的查询结果来封装对象。

多表查询离不开resultMap。

  1. //此注解作用是引用其他的ResultMap的id值
  2. public @interface ResultMap {
  3. String[] value();
  4. }

这个不是ResultMap,那么是什么呢?想一想,咱们XML配置时是resultmap+id+result。所以,是@Results。

  1. public @interface Results {
  2. String id() default "";
  3. Result[] value() default {};
  4. }
  5. public @interface Result {
  6. boolean id() default false;
  7. String column() default "";
  8. String property() default "";
  9. Class<?> javaType() default void.class;
  10. JdbcType jdbcType() default JdbcType.UNDEFINED;
  11. Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;
  12. One one() default @One;
  13. Many many() default @Many;
  14. }
  15. public @interface One {
  16. String select() default "";
  17. FetchType fetchType() default FetchType.DEFAULT;
  18. }
  19. public @interface Many {
  20. String select() default "";
  21. FetchType fetchType() default FetchType.DEFAULT;
  22. }
  23. public enum FetchType {
  24. LAZY,
  25. EAGER,
  26. DEFAULT;
  27. private FetchType() {
  28. }
  29. }

我们观察这些注解定义的含义。results定义一个resultMap的id,方便@ResultMap引用。其属性@Result来定义数据库的列名称和属性之间的对应关系,对应列设置id=true。其中one对应association。many对应collection。其中的select标签对应其他接口的方法,fetchType对应(懒)加载方式。

  1. //接口中的代码
  2. @Results(id = "accountMap",value = {
  3. @Result(column ="id",property = "id",id = true),
  4. @Result(column = "uid",property = "uid"),
  5. @Result(column = "money",property = "money"),
  6. @Result(property = "user",column = "uid", one = @One(select = "dao.IUserDao.findById",fetchType = FetchType.EAGER))
  7. })
  8. @Select(value = "select * from account where id = #{id}")
  9. Account findById(Integer id);
  10. //测试代码
  11. @org.junit.Test
  12. public void test() throws IOException {
  13. // 4,使用SqlSession获取dao的代理对象
  14. IAccountDao accountDao = session.getMapper(IAccountDao.class);
  15. // 5,执行dao方法
  16. Account accountDaoById = accountDao.findById(1);
  17. System.out.println(accountDaoById);
  18. System.out.println(accountDaoById.getUser());
  19. }

运行结果:

我们可以看到,mybatis应用注解开发时,摒弃了XML中根据根据SQL结果封装对象,而是采用了引用其他接口的方法。这样开发更显得简单。

一对多:

  1. @Results(id = "userMap",value = {
  2. @Result(id = true,property = "id",column = "id"),
  3. @Result(property = "name",column = "name"),
  4. @Result(property = "accounts" ,column = "id",many = @Many(
  5. select = "dao.IAccountDao.findByUid",fetchType = FetchType.LAZY
  6. ))
  7. })
  8. @Select("select * from users where id = #{id}")
  9. User findById(Integer id);
  10. @org.junit.Test
  11. public void test(){
  12. IUserDao userDao = session.getMapper(IUserDao.class);
  13. User byId = userDao.findById(1);
  14. System.out.println(byId);
  15. List<Account> accounts = byId.getAccounts();
  16. for (Account account : accounts) {
  17. System.out.println(account);
  18. }
  19. }

运行结果:

是不是看起来和用起来更加简单啊!这就是应用注解的好处。

多对多的代码和这个差不多,就是两个@Result的属性都应该是many=@Many。

值得注意的是:当一个对象中属性是一个list时,往往这个属性的fetchType=FetchType.Lazy。

懒加载首先要在mybatis配置文件中配置settings哦!

  1. <settings>
  2. <!--延迟加载总开关-->
  3. <setting name="lazyLoadingEnabled" value="true"/>
  4. <!--侵入式延迟加载开关-->
  5. <!--3.4.1版本之前默认是true,之后默认是false-->
  6. <setting name="aggressiveLazyLoading" value="false"/>
  7. <!-- 不加这个可能有点问题-->
  8. <setting name="lazyLoadTriggerMethods" value=""/>
  9. </settings>

mybatis注解开启缓存。

一级缓存不用开启,默认开启。

二级缓存开启(注解):

<setting name="cacheEnabled" value="true"/>

还有该接口上增加注解:

  1. @CacheNamespace(blocking = true)
  2. public interface IUserDao

即可。

https://blog.csdn.net/weixin_46083389/article/details/113591329
posted on 2022-03-23 21:50  sunny123456  阅读(328)  评论(0编辑  收藏  举报