Mybatis新手进阶知识点,老鸟请走开
ORM全称:object relation mapping,译为:对象关系映射。Java原生的与数据库连接的方式是JDBC,每次操作需要以下6个步骤
ORM框架是将对象和数据库表字段建立映射,并提供CRUD操作的API的框架。
- 加载数据库驱动
- 创建连接
- 创建一个Statement
- 执行SQL
- 处理结果集
- 关闭连接
- Hibernate 全自动ORM框架,弱化sql, 甚至不需要考虑建表,Hibernate会根据对象生成表甚至中间表。CURD一般不需要写sql。用起来方便,用好很难,有些老的项目还在用。
- Mybatis半自动ORM框架,本文的主角,被广泛使用,它支持自定义 SQL、存储过程以及高级映射。前身是ibatis, 另外还有一个在此基础上封装的号称为简化开发而生的框架MyBatis-Plus。提供通用的CURD,一般操作不需要写sql。
- JPA是大spring旗下ORM框架,特点是根据方法名就能自动实现方法逻辑,你敢信?不信可以看看这篇文章《简单才是美! SpringBoot+JPA》
嵌套查询
在resultMap
中嵌套一个查询。通过标签的
select
属性完成。select
的值是另一个查询的id,
column
属性为关联字段,用来实现关联查询。
- 根据user_id查询user
select * from `user` where user_id = #{userId}
- 中嵌套一个id为selectAddressByUserId的查询,查询这个用户的地址。
- id为selectAddressByUserId的查询:根据用户id查询地址详情:
select * from address where user_id = #{userId}
上面的查询会有N+1的问题,就是执行两遍查询,可以使用联表查询解决这个问题,结果集同样是使用映射,
标签+
resultMap
属性。具体写法如下:
- association标签的resultMap属性指向address的resultMap
- 联表查询sql
select * from `user` u join address a on u.user_id and a.user_id where u.user_id = #{userId}
换成
,实现一个人有多个女朋友的一对多关联查询。myabtis会自动合并重复的user,girlFriends作为集合映射到user的girlFriends属性。
懒加载
除了联表查询解决N+1的问题,mybatis的懒加载似乎更好,拿第一个嵌套查询的栗子来说,如果开启了懒加载,
在不使用address的时候,只会执行查询user的sql,不会执行查询address的sql。
只有在使用中get了address属性才会执行查询address的sql,使用起来也很见简单:
- yml配置
mybatis: mapper-locations: classpath:mapper/*Mapper.xml configuration: ##开启懒加载 lazy-loading-enabled: true ##false:按需加载 aggressive-lazy-loading: false ##触发加载的方法名 lazy-load-trigger-methods:
- 加上
fetchType="lazy"
的属性即可。
- 如果报错No serializer found for class org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory..
序列化问题需要在实体类上添加注解@JsonIgnoreProperties(value = https://www.it610.com/article/{"handler"})
- 如果懒加载失败:检查是否是lombok中的@Data注解的toString()导致的
- 检查全局配置是否正确
- 还有在idea失败,在eclipce成功的。。。
一级缓存,一次请求查询两次数据,第二次从缓存中取,mybatis默认开启
二级缓存,多次请求查询同一个数据,都能从缓存中取,需要手动开启
- 开启全局配置:
mybatis: mapper-locations: classpath:mapper/*Mapper.xml ##开启二级缓存 cache-enabled: true
- 添加useCache="true"属性。
select user_id, name, email from user where user_id = #{userId,jdbcType=INTEGER}
有时候我们在入库和出库的时候对字段做一些处理,
比如不支持utf8mb4的数据库存储emoji表情之前需要转义成utf8支持的unicode字符编码,出库后需要转化成emoji表情。
又或者用户的密码不能明文保存到数据库,入库需要进行一些加密操作。
mybatis的类型处理器,就可以在入库和出库前对数据做一些操作。
下面举个栗子将邮箱入库Base64加密,出库Base64解密。
- 自定义类型处理器类继承
BaseTypeHandler
抽象类。
public class MyHandler extends BaseTypeHandler { //入库加密 @Override public void setNonNullParameter(PreparedStatement preparedStatement, int i, String s, JdbcType jdbcType) throws SQLException { preparedStatement.setString(i,Base64Utils.encodeToString(s.getBytes())); } //出库解密 @Override public String getNullableResult(ResultSet resultSet, String columnName) throws SQLException { String column = resultSet.getString(columnName); return new String(Base64Utils.decode(column.getBytes())); } @Override public String getNullableResult(ResultSet resultSet, int i) throws SQLException { System.out.println(resultSet); return null; } @Override public String getNullableResult(CallableStatement callableStatement, int i) throws SQLException { System.out.println(callableStatement); return null; } }
- 【Mybatis新手进阶知识点,老鸟请走开】字段添加
typeHandler
属性,并指向自定义类型处理器类的路径
推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- mybatisplus如何在xml的连表查询中使用queryWrapper
- mybatisplus|mybatisplus where QueryWrapper加括号嵌套查询方式
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- 松软可口易消化,无需烤箱超简单,新手麻麻也能轻松成功~
- 推荐系统论文进阶|CTR预估 论文精读(十一)--Deep Interest Evolution Network(DIEN)
- 普通人进阶的三个过程-很多人都知道,但却本末倒置
- 易效能进阶课程笔记29
- C语言进阶栈帧示例详解教程