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

即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值