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
即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)