<>MyBatis-plus
<>1. 概述:
MyBatis-Plus是一个MyBatis的增强工具,
在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。MyBatis-Plus提供了通用的mapper和批量、逻辑删除、分页等操作。从MyBatis-
Plus的特性及使用,到对ldea中的快速开发插件MyBatisX也进行了功能的演示。对ldea中的快速开发插件MyBatisX也进行了功能的演示。对ldea中的快速开发插件MyBatisX也进行了功能的演示。
<>2.框架原理:
<>3.基本Mapper的crud
* 新增的方法就只有一个 | - int insert(T entity); // 插入一条记录 * 删除的方法 4 个 | - int deleteById
(Serializable id); // 根据 ID 删除 | - int deleteByMap(@Param(Constants.COLUMN_MAP)
Map<String, Object> columnMap); // 根据 columnMap 条件,删除记录 | - int delete(@Param(
Constants.WRAPPER) Wrapper<T> queryWrapper); // queryWrapper 实体对象封装操作类(可以为
null,里面的 entity 用于生成 where 语句) | - int deleteBatchIds(@Param(Constants.
COLLECTION) Collection<? extends Serializable> idList); // idList 主键ID列表(不能为
null 以及 empty) * 修改的方法 2 个 | - int updateById(@Param(Constants.ENTITY) T entity)
; // 根据 ID 修改 | - int update(@Param(Constants.ENTITY) T entity, @Param(Constants
.WRAPPER) Wrapper<T> updateWrapper); // 实体对象 (set 条件值,可以为 null) 实体对象封装操作类(可以为
null,里面的 entity 用于生成 where 语句) * 查询的方法 10 个 | - T selectById(Serializable id);
// 根据 ID 查询 | - List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<?
extends Serializable> idList); // idList 主键ID列表(不能为 null 以及 empty) | - List<T>
selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); //
查询(根据 columnMap 条件) | - default T selectOne(@Param(Constants.WRAPPER) Wrapper<T>
queryWrapper) // queryWrapper 实体对象封装操作类(可以为 null) 注意:多条数据会报异常 | - Long
selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 根据 Wrapper
条件,查询总记录数 | - List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T>
queryWrapper); // queryWrapper 实体对象封装操作类(可以为 null) | - List<Map<String, Object>>
selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);//实体对象封装操作类(可以为
null) | - List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T>
queryWrapper); // 根据 Wrapper 条件,查询全部记录
<>4.通用service的Crud
通用 Service CRUD 封装IService接口,进一步封装 CRUD 采用 get 查询单行、 remove 删除、 list 查询集合、
page 分页前缀命名方式区分 Mapper 层避免混淆。
* 新增的方法 | - default int count() // 查询总记录数 | - default boolean save(T entity)
// 插入一条记录(选择字段,策略插入) | - default boolean saveBatch(Collection<T> entityList) //
插入(批量) | - boolean saveBatch(Collection<T> entityList, int batchSize); //
插入批次数量 默认是1000 | - default boolean saveOrUpdateBatch(Collection<T> entityList)
// 批量修改插入 ,有id 就是修改,没有就是新增 .......
<>5.常用的注解
@TableName(value = "`user`") mybatis-plus: global-config: db-config: # 配置
MyBatis-Plus操作表的默认前缀 table-prefix: t_ id-type: auto @TableId(value = "id", type
= IdType.AUTO) @TableField(value = "`name`") @TableLogic // 逻辑删除
值描述
IdType.ASSIGN_ID(默 认)基于雪花算法的策略生成数据id,与数据库id是否设置自增无关
IdType.AUTO使用数据库的自增策略,注意,该类型请确保数据库设置了id自增, 否则无效
IdType.ASSIGN_UUID分配UUID (主键类型为 string)
INput用户输入ID
<>6.雪花算法
雪花算法是由Twitter公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的主键的有序性。
①核心思想:
长度共64bit(一个long型)。
首先是一个符号位,1bit标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负 数是1,所以id一般是正数,最高位是0。
41bit时间截(毫秒级),存储的是时间截的差值(当前时间截 - 开始时间截),结果约等于69.73年。
10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID,可以部署在1024个节点)。
12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID)。
②优点:整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞,并且效率较高。
<>7.条件构造器
Wrapper : 条件构造抽象类,最顶端父类
| - AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
| - QueryWrapper : 查询条件封装
| - UpdateWrapper : Update 条件封装
| - AbstractLambdaWrapper : 使用Lambda 语法
| - LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
| - LambdaUpdateWrapper : Lambda 更新封装Wrapper
| -eq : 等于 = 例: eq("name", "老王")--->name = '老王' | allEq | -ne : 不等于 <> 例: ne(
"name", "老王")--->name <> '老王' | -gt : 大于 > 例: ge("age", 18)--->age > 18 | ge :
大于等于| -lt : 小于 < | le 小于等于 | -between: BETWEEN 值1 AND 值2 between("age", 18, 30)
--->age between 18 and 30 | -like: LIKE '%值%' | -isNull: 例: isNull("name")--->
name isnull | -in :例: in("age",{1,2,3})--->age in (1,2,3) | - inSql 字段 IN (
sql语句) inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6) | - groupBy | -
orderByAsc orderByDesc or and| queryWapper select
lambad表达式的可以优先的执行:
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); // lambad
表达式中的条件会优先的进行执行 queryWrapper.like("name", "a") .and(userQueryWrapper ->
userQueryWrapper.eq("age", 20).isNotNull("email")); User user = new User(); user
.setName("zhangasn"); user.setAge(2); int result = userMapper.update(user,
queryWrapper); System.out.println("result = " + result);
<>1.实现子查询
//查询id小于等于3的用户信息 //SELECT id,username AS name,age,email,is_deleted FROM t_user
WHERE (id IN (select id from t_user where id <= 3)) QueryWrapper<User>
queryWrapper= new QueryWrapper<>(); queryWrapper.inSql("id", "select id from
t_user where id <= 3"); List<User> list = userMapper.selectList(queryWrapper);
list.forEach(System.out::println);
<>2.组装select子句
//查询用户信息的username和age字段 //SELECT username,age FROM t_user QueryWrapper<User>
queryWrapper= new QueryWrapper<>(); queryWrapper.select("username", "age");
//selectMaps()返回Map集合列表,通常配合select()使用,避免User对象中没有被查询到的列值 为null List<Map<String,
Object>> maps = userMapper.selectMaps(queryWrapper); maps.forEach(System.out::
println);
<>3.updateWapper用法
@Test public void test07() { //将(年龄大于20或邮箱为null)并且用户名中包含有a的用户信息修改
//组装set子句以及修改条件 UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
//lambda表达式内的逻辑优先运算 updateWrapper .set("age", 18) .set("email",
"[email protected]") .like("username", "a") .and(i -> i.gt("age", 20).or().isNull
("email")); //这里必须要创建User对象,否则无法应用自动填充。如果没有自动填充,可以设置为null //UPDATE t_user SET
username=?, age=?,email=? WHERE (username LIKE ? AND (age > ? OR email IS NULL))
//User user = new User(); //user.setName("张三"); //int result =
userMapper.update(user, updateWrapper); //UPDATE t_user SET age=?,email=? WHERE
(username LIKE ? AND (age > ? OR email IS NULL)) int result = userMapper.update(
null, updateWrapper); System.out.println(result); }
<>4.组装条件Condition
@Test public void test08UseCondition() { //定义查询条件,有可能为null(用户未输入或未选择) String
username= null; Integer ageBegin = 10; Integer ageEnd = 24; QueryWrapper<User>
queryWrapper= new QueryWrapper<>();
//StringUtils.isNotBlank()判断某字符串是否不为空且长度不为0且不由空白符(whitespace) 构成 queryWrapper.
like(StringUtils.isNotBlank(username), "username", "a") .ge(ageBegin != null,
"age", ageBegin) .le(ageEnd != null, "age", ageEnd); //SELECT id,username AS
name,age,email,is_deleted FROM t_user WHERE (age >= ? AND age <= ?) List<User>
users= userMapper.selectList(queryWrapper); users.forEach(System.out::println);
}
<>5.LambdaQueryWrapper 和 LambdaUpdateWrapper 的使用
@Test public void test09() { //定义查询条件,有可能为null(用户未输入) String username = "a";
Integer ageBegin = 10; Integer ageEnd = 24; LambdaQueryWrapper<User>
queryWrapper= new LambdaQueryWrapper<>(); //避免使用字符串表示字段,防止运行时错误 queryWrapper .
like(StringUtils.isNotBlank(username), User::getName, username) .ge(ageBegin !=
null, User::getAge, ageBegin) .le(ageEnd != null, User::getAge, ageEnd); List<
User> users = userMapper.selectList(queryWrapper); users.forEach(System.out::
println); } @Test public void test10() { //组装set子句 LambdaUpdateWrapper<User>
updateWrapper= new LambdaUpdateWrapper<>(); updateWrapper .set(User::getAge, 18)
.set(User::getEmail, "[email protected]") .like(User::getName, "a") .and(i -> i.
lt(User::getAge, 24).or().isNull(User::getEmail)); //lambda 表达式内的逻辑优先运算 User
user= new User(); int result = userMapper.update(user, updateWrapper); System.
out.println("受影响的行数:" + result); }
<>8.插件
<>分页插件
@Configuration @MapperScan("com.atguigu.mybatisplus.mapper") //可以将主类中的注解移到此处
public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor
mybatisPlusInterceptor(){ MybatisPlusInterceptor interceptor = new
MybatisPlusInterceptor(); // 添加的分页插件 interceptor.addInnerInterceptor(new
PaginationInnerInterceptor(DbType.MYSQL)); // 添加乐观锁插件 interceptor.
addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor;
} }
<>乐观锁和悲观锁
数据库中添加version字段 ,取出记录时,获取当前version ,需要添加乐观锁插件配置。这样就可以加上了版本号,给操作加上了锁。
<>通用枚举
@Getter public enum SexEnum { MAN(1, "男"), WOMAN(2, "女"); private String
sexName; @EnumValue // 这个和数据库相关联起来 private Integer sex; SexEnum(Integer sex,
String sexName) { this.sexName = sexName; this.sex = sex; } } 添加配置: mybatis-plus
: type-enums-package: com.wang.enums
<>9.多数据源的功能
spring: # 配置数据源信息 datasource: dynamic: # 设置默认的数据源或者数据源组,默认值即为master primary:
master# 严格匹配数据源,默认false.true未匹配到指定数据源时抛异常,false使用默认数据源 strict: false datasource:
master: url: jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf- 8
&useSSL=false driver-class-name: com.mysql.cj.jdbc.Driver username: root
password: 123456 slave_1: url: jdbc:mysql://localhost:3306/mybatis_plus_1?
characterEncoding=utf- 8&useSSL=false driver-class-name:
com.mysql.cj.jdbc.Driverusername: root password: 123456 @DS("master")
//指定所操作的数据源 @Service public class UserServiceImpl extends ServiceImpl<UserMapper
, User> implements UserService { }