sunny123456

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  1796 随笔 :: 22 文章 :: 24 评论 :: 226万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

mybatis注解多表查询

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

多表查询离不开resultMap。

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

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

public @interface Results {
    String id() default "";
 
    Result[] value() default {};
}
public @interface Result {
    boolean id() default false;
 
    String column() default "";
 
    String property() default "";
 
    Class<?> javaType() default void.class;
 
    JdbcType jdbcType() default JdbcType.UNDEFINED;
 
    Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;
 
    One one() default @One;
 
    Many many() default @Many;
}
public @interface One {
    String select() default "";
 
    FetchType fetchType() default FetchType.DEFAULT;
}
public @interface Many {
    String select() default "";
 
    FetchType fetchType() default FetchType.DEFAULT;
}
public enum FetchType {
    LAZY,
    EAGER,
    DEFAULT;
 
    private FetchType() {
    }
}

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

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

运行结果:

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

一对多:

@Results(id = "userMap",value = {
            @Result(id = true,property = "id",column = "id"),
            @Result(property = "name",column = "name"),
            @Result(property = "accounts" ,column = "id",many = @Many(
                    select = "dao.IAccountDao.findByUid",fetchType = FetchType.LAZY
            ))
    })
    @Select("select * from users where id = #{id}")
    User findById(Integer id);
 
  @org.junit.Test
    public void test(){
        IUserDao userDao = session.getMapper(IUserDao.class);
        User byId = userDao.findById(1);
        System.out.println(byId);
        List<Account> accounts = byId.getAccounts();
        for (Account account : accounts) {
            System.out.println(account);
        }
    }

运行结果:

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

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

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

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

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

mybatis注解开启缓存。

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

二级缓存开启(注解):

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

还有该接口上增加注解:

@CacheNamespace(blocking = true)
public interface IUserDao

即可。

https://blog.csdn.net/weixin_46083389/article/details/113591329
posted on   sunny123456  阅读(337)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示