关于MyBatis-Plus,其实我是没有系统学习过,只是在做项目的时候,碰到不懂的去百度,逐步去了解MyBatis-Plus里,所以其实在我的记忆里对于MyBatis-Plus是十分混乱的,有时候同样的东西每次看到都会去各种反复百度。今天我将借着这个机会重启一下MyBatis-Plus。
1.1 MyBatis与JPA的对比
我自己的了解是jpa的前身是著名的ssh中的h——>Hibernate。
我目前为止只了解过一些皮毛,jpa的对于单表的简单查询确实简单方便又实用,但是同时,对于多表关联和复杂查询,起码目前为止,要么把复杂查询拆成多个简单查询。
1.2 MP
官方网址: https://mp.baomidou.com/
建立项目流程
1.3 lombok
在java项目中充斥着太多不友好的代码:POJO的getter/setter/toString;异常处理;I/O流的关闭操作等等,这些样板代码既没有技术含量,又影响着代码的美观,Lombok应运而生。
2.1 通用传统模式简介及通用mapper新增方法
warn模式 —在DAO层包下 —格式
将实体类及其各层与数据库通通配置好,根据以下mp提供的方法进行开发。
2.2 常用注解
@Tablename 表名注解 数据库表名改变了结果实体类可不变名
@Tableld 标记在实体类字段上方 表示表的主键 代表默认值 //指向表中的id @TableId(value = "id", type = IdType.AUTO)
@TableField
//指向表中user_id字段,点表中的字段与所使用的字段不一样时使用,比如user_id(表)和userId(用)
@TableField("user_id")
private Integer userId;
@TableName("uc_cust_lock")
public class CustLock {
/**
* 标识
*/
@IdField
@TableField("cust_lock_id")
private String custLockId;
/**
* 经纪人id
*/
@TableField("broker_user_id")
private String brokerUserId;
/**
* 组织id(经纪人所属组织id)
*/
@TableField("org_id")
private String orgId;
// get,set...省略
}
2.3 排除非表字段的三种方式
为防止实体类的字段在数据库不存在:
1.使用关键字 transient 不参与序列化变化.
插入成功 该字段被忽略
2.static标识为静态变量.(如果需要被序列化时候.)
需要在实体类写一个静态的get set方法 在逻辑上用类调用
3.@TableField(exist=false) 对应数据库中是否存在.
用对象调用 表明该字段在数据库不存在
3.1 查询方法-普通查询
一 、根据id查询
二、 根据id批量列表查询
三、根绝map对象查询
注意字段名和数据库字段名是否符合
3.2 条件构造器查询
条件构造器的各种使用:
https://mp.baomidou.com/guide/wrapper.html#abstractwrapper
例子:
3.3 select不列出全部字段
3.4 condition作用
3.5 实体作为条件构造器构造方法的参数
实体安排什么参数条, 按照此条件来查询
3.6 AllEq用法
说明:
QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父类
用于生成 sql 的 where 条件, entity 属性也用于生成 sql 的 where 条件
注意: entity 生成的 where 条件与 使用各个 api 生成的 where 条件**没有任何关联行为**
### [#](https://mp.baomidou.com/guide/wrapper.html#alleq)allEq
allEq(Map<R, V> params)
allEq(Map<R, V> params, boolean null2IsNull)
allEq(boolean condition, Map<R, V> params, boolean null2IsNull)
3.7 lambda条件构造器
官网说法:
获取 LambdaWrapper:
在QueryWrapper中是获取LambdaQueryWrapper
在UpdateWrapper中是获取LambdaUpdateWrapper
4.1 自定义sql
需求来源:
在使用了mybatis-plus之后, 自定义SQL的同时也想使用Wrapper的便利应该怎么办? 在mybatis-plus版本3.0.7得到了完美解决 版本需要大于或等于3.0.7, 以下两种方案取其一即可
Service.java
mysqlMapper.getAll(Wrappers.<MysqlData>lambdaQuery().eq(MysqlData::getGroup, 1));
//方案一 注解方式 Mapper.java
@Select("select * from mysql_data ${ew.customSqlSegment}")
List<MysqlData> getAll(@Param(Constants.WRAPPER) Wrapper wrapper);
//方案二 XML形式 Mapper.xml
<select id="getAll" resultType="MysqlData">
SELECT * FROM mysql_data ${ew.customSqlSegment}
</select>
4.2 分页查询
分页展示:
https://gitee.com/baomidou/mybatis-plus-samples/tree/master/mybatis-plus-sample-pagination
<!-- spring xml 方式 -->
<property name="plugins">
<array>
<bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor">
<property name="sqlParser" ref="自定义解析类、可以没有"/>
<property name="dialectClazz" value="自定义方言类、可以没有"/>
<!-- COUNT SQL 解析.可以没有 -->
<property name="countSqlParser" ref="countSqlParser"/>
</bean>
</array>
</property>
<bean id="countSqlParser" class="com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize">
<!-- 设置为 true 可以优化部分 left join 的sql -->
<property name="optimizeJoin" value="true"/>
</bean>
//Spring boot方式
@EnableTransactionManagement
@Configuration
@MapperScan("com.baomidou.cloud.service.*.mapper*")
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}
XML 自定义分页
public interface UserMapper {//可以继承或者不继承BaseMapper
/**
* <p>
* 查询 : 根据state状态查询用户列表,分页显示
* </p>
*
* @param page 分页对象,xml中可以从里面进行取值,传递参数 Page 即自动分页,必须放在第一位(你可以继承Page实现自己的分页对象)
* @param state 状态
* @return 分页对象
*/
IPage<User> selectPageVo(Page<?> page, Integer state);
}
UserMapper.xml 等同于编写一个普通 list 查询,mybatis-plus 自动替你分页
<select id="selectPageVo" resultType="com.baomidou.cloud.entity.UserVo">
SELECT id,name FROM user WHERE state=#{state}
</select>
UserServiceImpl.java 调用分页方法
public IPage<User> selectUserPage(Page<User> page, Integer state) {
// 不进行 count sql 优化,解决 MP 无法自动优化 SQL 问题,这时候你需要自己查询 count 部分
// page.setOptimizeCountSql(false);
// 当 total 为小于 0 或者设置 setSearchCount(false) 分页插件不会进行 count 查询
// 要点!! 分页返回的对象与传入的对象是同一个
return userMapper.selectPageVo(page, state);
}
6.1 AR模式
AR模式简单的说就是直接用实体操作数据库
一是实体需要继承Model类,二是必须存在对应的原始mapper并继承baseMapper并且可以使用的前提下,才能使用此 AR 模式。
6.2 主题策略
主键生成策略必须使用INPUT
支持父类定义@KeySequence子类继承使用
内置支持:
DB2KeyGenerator
H2KeyGenerator
KingbaseKeyGenerator
OracleKeyGenerator
PostgreKeyGenerator
如果内置支持不满足你的需求,可实现IKeyGenerator接口来进行扩展.
@KeySequence(value = "SEQ_ORACLE_STRING_KEY", clazz = String.class)
public class YourEntity {
@TableId(value = "ID_STR", type = IdType.INPUT)
private String idStr;
}