简化开发
、提高效率
基于SpringBoot使用MyBatisPlus
CREATE DATABASE `mybatisplus_db`;
USER `mybatisplus_db`;
CREATE TABLE `user`(
`id` INT(20) NOT NULL PRIMARY KEY,
`name` VARCHAR(30) NOT NULL,
`password` VARCHAR(30) NOT NULL,
`age` INT(3) NOT NULL,
`tel` VARCHAR(30)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user` (`id`,`name`,`password`,`age`,`tel`) VALUES
(1,'Tom','tom',15,'1234567'),
(2,'Jerry','jerry',16,'1234568'),
(3,'Jcok','123456',18,'123456'),
(4,'小吴','123456',21,'123456')
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.16</version>
</dependency>
package com.mybatisplus_01_quickstart.domain;
public class User {
private Long id;
private String name;
private String password;
private int age;
private String tel;
@Override
public String toString( ) {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
", tel='" + tel + '\'' +
'}';
}
public int getAge( ) {
return age;
}
public void setAge( int age ) {
this.age = age;
}
public Long getId( ) {
return id;
}
public void setId( Long id ) {
this.id = id;
}
public String getName( ) {
return name;
}
public void setName( String name ) {
this.name = name;
}
public String getPassword( ) {
return password;
}
public void setPassword( String password ) {
this.password = password;
}
public String getTel( ) {
return tel;
}
public void setTel( String tel ) {
this.tel = tel;
}
}
BaseMapper
package com.mybatisplus_01_quickstart.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mybatisplus_01_quickstart.domain.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserDao extends BaseMapper<User> {
}
package com.mybatisplus_01_quickstart;
import com.mybatisplus_01_quickstart.dao.UserDao;
import com.mybatisplus_01_quickstart.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
class Mybatisplus01QuickstartApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testGetAll( ) {
List<User> userList = userDao.selectList(null);
System.out.println(userList);
}
}
在配置文件中添加配置(application.yml)
#开启mp的日志(输出到控制台)
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
标准CRUD制作
功能 | 自定义接口 |
---|---|
新增 | boolean save(T t) |
删除 | boolean delete(int id) |
修改 | boolean update(T t) |
根据id查询 | T getById(int id) |
查询全部 | List getAll() |
分页查询 | PageInfo getAll(int page, int size) |
按条件查询 | List getAll |
添加
@Test
void testSave(){
User user = new User();
user.setName("小吴在敲bug");
user.setId(123L);
user.setPassword("123456");
user.setAge(21);
user.setTel("2929054638");
userDao.insert(user);
}
删除
@Test
void testDelete(){
userDao.deleteById(123L);
}
修改:有什么属性修改什么属性,没有就不变
@Test
void testUpdate(){
User user = new User();
user.setName("小吴在敲bug");
user.setId(1L);
userDao.updateById(user);
}
查
@Test
void testGetById(){
User user = userDao.selectById(1L);
System.out.println(user);
}
mp要实现分页查询需要添加拦截器
package com.mybatisplus_01_quickstart.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mpInterceptor(){
//1.定义Mp拦截器
MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
//2.添加分页的拦截器
mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mpInterceptor;
}
}
MyBatisPlus分页demo
@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());
}
MyBatisPlus将书写复杂的SQL查询条件进行了封装,使用编程的形式完成查询条件的组合
默认是and
如果or需要添加
//查询年龄大于等于16岁,小于65岁的用户
lqw.lt(User::getAge,50).or().ge(User::getAge,16);
方式一:按条件查询
@Test
void testGetAll( ) {
//按条件查询
QueryWrapper qw = new QueryWrapper();
qw.lt("age",18);
List<User> userList = userDao.selectList(qw);
System.out.println(userList);
}
方式二:lambda格式
@Test
void testGetAll( ) {
//lambda格式按条件查询
QueryWrapper<User> qw = new QueryWrapper();
qw.lambda().lt(User::getAge,16);
List<User> userList = userDao.selectList(qw);
System.out.println(userList);
}
lambda对象格式
@Test
void testGetAll( ) {
//lambda对象格式按条件查询
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.lt(User::getAge,16);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
@Test
void testGetAll( ) {
//模拟页面传递过来的查询数据
UserQuery uq = new UserQuery();
uq.setAge(10);
//lambda对象格式按条件查询
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//先判断第一个参数是否为true,如果为true连接当前条件
lqw.lt(null != uq.getAge2(), User::getAge, uq.getAge2());
lqw.ge(null != uq.getAge() , User::getAge, uq.getAge());
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
设置要查询的字段
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.select(User::getAge,User::getName,User::getAge);
@Test
void testGetAll( ) {
QueryWrapper<User> lqw = new QueryWrapper<>();
lqw.select("id","name","tel");
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
统计记录(count(1)
):不能使用lambda格式
@Test
void testGetAll( ) {
QueryWrapper<User> qw = new QueryWrapper<>();
qw.select("count(1) as count");
List<Map<String, Object>> userList = userDao.selectMaps(qw);
System.out.println(userList);
}
分组查询:不能使用lambda表达式
@Test
void testGetAll( ) {
QueryWrapper<User> qw = new QueryWrapper<>();
qw.select("count(1) as count","tel");
qw.groupBy("tel");
List<Map<String, Object>> userList = userDao.selectMaps(qw);
System.out.println(userList);
}
范围匹配(>、=、between)
@Test
void testGetAll( ) {
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//等同于=
lqw.eq(User::getName,"Jerry").eq(User::getPassword,"jerry2");
User loginUser = userDao.selectOne(lqw);
System.out.println(loginUser);
}
模糊匹配(like)
@Test
void testGetAll( ) {
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//模糊查询like
lqw.likeRight(User::getName,"J");
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
}
空判定(null)
包含性匹配(in)
分组(group)
排序(order)
……
官网
属性注解
public class User {
@TableField(value = "pwd")
private String password;
@TableField(exist = false)
private Integer online;
@TableField(select=false)
private Long id;
}
exist
: 设置属性在数据库表字段是否存在,默认为true。此属性无法与value合并使用类注解
@TableName(value = "tbl_user")
public class User {}
属性注解
public class User {
@TableId(type = IdType.AUTO)
private Long id;
}
可兼容数值型与字符串型
)mybatis-plus:
# id生成策略
global-config:
db-config:
id-type: assign_id
mybatis-plus:
global-config:
db-config:
# 数据库表名前缀
table-prefix: tbl_
根据删除多个数据
@Test
void testDelete( ) {
List<Long> list = new ArrayList<>();
list.add(1L);
list.add(2L);
userDao.deleteBatchIds(list);
}
根据主键查询多条数据
@Test
void testSelect( ) {
List<Long> list = new ArrayList<>();
list.add(1L);
list.add(2L);
userDao.selectBatchIds(list);
}
修改实体类
package com.mybatisplus_03_dml.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;
@Data
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private String password;
private Integer age;
private String tel;
//逻辑删除字段,标记当前记录是否被删除
@TableLogic(value = "0",delval = "1")
private Integer deleted;
}
测试
@Test
void testDelete(){
userDao.deleteById(3l);
}
逻辑删除全局配置
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted #删除标记字段
logic-not-delete-value: 0 #显示标记
logic-delete-value: 1 #删除标记
业务并发现象带来的问题:秒杀
修改实体类
package com.mybatisplus_03_dml.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
@Data
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private String password;
private Integer age;
private String tel;
private Integer deleted;
@Version //添加注解
private Integer version;
}
编写拦截器
package com.mybatisplus_03_dml.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mpInterceptor(){
//1.定义Mp拦截器
MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
//2.添加乐观锁拦截器
mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mpInterceptor;
}
}
测试
@Test
void testUpdate(){
//1.先查询数据,获取到version数据
User userA = userDao.selectById(2l); //version=2
User userB = userDao.selectById(2l); //version=2
//2.执行数据修改操作
userB.setName("JockAAA");
userDao.updateById(userB); //version=3
userA.setName("JockBBB");
userDao.updateById(userB); //version=2?条件不成立
}
导入依赖
<!--MyBatisPlus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!--代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<!--veLocity模板引擎-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
编写代码生成器
package com.mybatisplus_04_generator;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
public class Generator {
public static void main( String[] args ) {
//实例化代码生成器
AutoGenerator autoGenerator = new AutoGenerator();
//配置数据库驱动
DataSourceConfig dataSource = new DataSourceConfig();
dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db");
dataSource.setUsername("root");
dataSource.setPassword("123456");
autoGenerator.setDataSource(dataSource);
//设置全局配置
GlobalConfig globalConfig = new GlobalConfig();
//设置代码生成位置
globalConfig.setOutputDir(System.getProperty("user.dir")+"/mybatisplus_04_generator/src/main/java");
//设置生成完毕是否打开生成代码所在的目录
globalConfig.setOpen(false);
//设置作者
globalConfig.setAuthor("小吴在敲Bug");
//设置是否覆盖原始生成的文件
globalConfig.setFileOverride(true);
//设置数据层接口名,%s为占位符,指代实体类名称
globalConfig.setMapperName("%sDao");
//设置id生成策略
globalConfig.setIdType(IdType.ASSIGN_ID);
//添加配置
autoGenerator.setGlobalConfig(globalConfig);
//设置包名相关配置
PackageConfig packageConfig = new PackageConfig();
//设置生成的报名,与代码所在位置不冲突,二者叠加完整路径
packageConfig.setParent("com.mybatisplus_04_generator");
//设置实体类包名
packageConfig.setEntity("domain");
//设置实体类包名
packageConfig.setMapper("dao");
//添加配置
autoGenerator.setPackageInfo(packageConfig);
//策略配置
StrategyConfig strategyConfig = new StrategyConfig();
//设置当前参与生成的表名,参数为可变参数
strategyConfig.setInclude("tbl_user");
//设置数据库表的前缀名称:实体类名 = 数据库表名 - 前缀名 例如:User=tbl_user
strategyConfig.setTablePrefix("tbl_");
//设置是否启用Rest风格
strategyConfig.setRestControllerStyle(true);
//设置乐观锁字段名
strategyConfig.setLogicDeleteFieldName("deleted");
//设置是否启用Lombok
strategyConfig.setEntityLombokModel(true);
//添加配置
autoGenerator.setStrategy(strategyConfig);
//执行代码生成器
autoGenerator.execute();
}
}