1134 字
6 分钟
SSM12-MybatisPlus
2023-06-28
2023-11-28

基础案例#

==极其精简化了dao层的书写==

==先引入mp起步依赖==

<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>

==导入实体类和表==

==定义数据接口继承BaseMapper<泛型>即可==

@Mapper
public interface UserDao extends BaseMapper<User> {
}

CURD和分页#

功能自定义接口MP接口
新增boolean save(T t)int insert(T t)
删除boolean delete(int id)int deleteById(Serializable id)
修改boolean update(T t)int updateById(T t)
根据id查询T getById(int id)T selectById (Serializable id)
查询全部List getAll()List selectList()
分页查询PageInfo getAll(int page, int size)IPage selectPage(IPage page)
条件查询List getAll(Condition condition)IPage selectPage(wrapper querywrapper)

==自动动态SQL==

样例:

@SpringBootTest
class MybatisplusApplicationTests {
@Autowired
private UserDao userDao;
//添加
@Test
void testSave() {
User user = new User();
user.setName("Wang");
user.setPassword("123456");
user.setAge(9);
user.setTel("116483477");
userDao.insert(user);
}
//删除
@Test
void testDelete() {
userDao.deleteById(1L);
}
//修改
@Test
void testUpdate() {
User user = new User();
user.setId(1L);
user.setName("Wang-nine");
userDao.updateById(user);
}
//查找
@Test
void testGetById() {
User user = userDao.selectById(1L);
System.out.println(user);
}
//查找全部
@Test
void testGetAll() {
List<User> users = userDao.selectList(null);
System.out.println(users);
}
//分页查询
@Test
void testGetByPage() {
IPage page = new Page(1, 2);
userDao.selectPage(page, null);
System.out.println("当前页码值:" + page.getCurrent());
System.out.println("每页页码值:" + page.getSize());
System.out.println("一共多少页:" + page.getPages());
System.out.println("一共多少条:" + page.getTotal());
System.out.println("数据:" + page.getRecords());
}
//
}

==对于分页查询,开启拦截器和输出日志==

拦截器

@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
//1.定义mp拦截器
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//2.添加具体的拦截器
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}

配置日志输出

mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

==条件查询==

//按条件查询
@Test
void testGetByCondition() {
//第一种方法
QueryWrapper qw = new QueryWrapper();
//查询小于18岁的
qw.lt("age", 18);
List<User> users = userDao.selectList(qw);
System.out.println(users);
//第二种方法,lambda表达式
QueryWrapper<User> qw1 = new QueryWrapper();
qw1.lambda().lt(User::getAge, 18);
List<User> users1 = userDao.selectList(qw);
System.out.println(users1);
//第三种方法,lambda表达式
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.lt(User::getAge, 18);
List<User> users2 = userDao.selectList(lqw);
System.out.println(users2);
//链式编程
LambdaQueryWrapper<User> lqw1 = new LambdaQueryWrapper<>();
lqw1.lt(User::getAge, 30).or().gt(User::getAge, 10);
//判断为空
//其弊端,判断年龄上下限,需要新来一个类继承一下user同时自己扩展一个age2
//模拟页面传递的数据,万一age2为空之类的情况
UserQuery uq = new UserQuery();
uq.setAge(10);
uq.setAge2(30);
lqw.lt(null != uq.getAge2(), User::getAge, uq.getAge2());
lqw.gt(null != uq.getAge(), User::getAge, uq.getAge());
...查询语句...
}

==查询投影,非常麻烦,不如自己写==

查询投影解决的是“返回哪些列”,与前面年龄上下限解决的“保留哪些行”不同。先确定调用方真正需要的字段,再让查询只选择这些列;若用实体承接部分列,未查询属性通常不会被填入数据,不能把它们当成完整记录直接覆盖更新。涉及统计或分组时,结果形状也可能不再对应完整 User,应选择合适的结果对象或映射方式,并核对实际生成的 SELECT 列表。

==对于其余的复杂查询,例如> = between like null in group order等,强烈建议自己写mysql语句,不要再去学习复杂的API了==

==实在想学,可以查看它的官方文档==

==字段名称映射(均为熟悉注解)==

  • 名称不一致
@TableField(value = "数据库字段名")
  • 存在数据库未定义属性
@TableField(exist = false)
  • 设定不可查询的字段权限,设定不参与查询
@TableField(select = false)
  • 表名与实体类名不一致
@TableName("表名")

全局配置表名前缀

mybatis-plus:
global-config:
db-config:
table-prefix: tbl_

==id生成策略(均为属性注解)==

@TableId(value = 数据库主键名称, type = 策略)

策略:IdType.AUTO 自增 NONE无策略 INPUT自己输入 ASSIGN_ID雪花算法 ASSIGN_UUIDuuid

主键策略首先要区分由谁提供标识:AUTO 依赖数据库自增,INPUT 要求应用在插入前设置主键,ASSIGN_ID 通常由框架的标识生成器分配,默认使用雪花算法,ASSIGN_UUID 面向字符串主键生成标识。NONE 表示没有单独指定策略,可跟随全局配置,并不等于数据库一定自增。应同时核对实体主键类型、数据库列定义、字段级 @TableId 与全局 id-type,避免只改一处配置就假定所有新增记录都会采用同一种方式。

也可在yaml中全局配置

mybatis-plus:
global-config:
db-config:
id-type: assign_id

==多数据操作==

样例

List<Long> ids = Arrays.asList(new Long[]{2, 3});
userDao.deleteBatchIds(ids); //删除
userDao.selectBatchIds(ids); //查询

==逻辑删除==

通用配置

mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted
logic-not-delete-value: 0
logic-delete-value: 1

==乐观锁:比如秒杀(可以解决2000个一下的并发问题)==

新增一个字段并加上下述注解

属性注解

@Version
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
//1.定义mp拦截器
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//2.添加具体的拦截器
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
//3.添加乐观锁拦截器
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mybatisPlusInterceptor;
}
}