目录
5.定义User的Mapper接口继承BaseMapper接口
2. 用户删除(通过id单独删除一条数据,同时删除多条数据)
5.2在 application.yml 中配置逻辑删除相关配置项
5.3在实体类中添加逻辑删除的属性,并加入 @TableLogic 注解
6.2业务实现类继承 MP 提供的 ServiceImpl 类
七、MP的代码生成 (实体类、mapper、Service)
前言:本片目的正如标题所示,主要为了帮助读者了解和掌握MP的基础使用,同时梳理MP提供的方法的如何使用以及代码含义,那么什么是MP,为什么要使用MP呢?以及MP和Mybatis有什么区别呢?这些问题大家可以去MP的官网进行了解https://baomidou.com/,本篇文章主要是结合实际开发一步一步的来说明讲解MP对持久层的开发应用、常用注解的使用、其的扩展功能和方便性功能,那么废话不多说,开始正题
一、开发环境搭建
1.创建相应的Maven工程
1.1配置项目基本信息
1.2导入数据库驱动
1.3搭建完成
2.导入项目依赖,配置pom文件
2.1导入Mybatis-Plus的Maven坐标
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
2.2导入Lombok的Maven坐标(不是必须,但是可以帮助我们简化项目代码和提供一些便捷的功能)
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
2.3导入aliyun的数据库连接池(不是必须,建议导入,不导入的话SpringBoot默认使用的是Hi
kariCP连接池,根据自己的项目需求进行导入
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.1</version>
</dependency>
3.配置数据源(.yml)
3.1若项目中不带resource文件夹,自行创建(注意文件的层级)并在该目录下创建applcation.yml文件实现对数据源的配置(主要是为了连接数据库、配置数据库连接池,将Mabatis-Plus对数据库操作的语句显示在控制台上,以及之后配置Mabatis-plus的全局变量)
注意 :项目配置文件采用多环境配置(这里主要应用了dev的配置文件,下面是两个yml文件的内容,dev.yml文件的内容需要根据自己实际的数据库进行修改)
3.1.1 application.yml
server: port: 8080 address: 0.0.0.0 spring: profiles: active: dev datasource: druid: # driver-class-name: com.mysql.cj.jdbc.Driver type: ${MP.datasource.type} driver-class-name: ${MP.datasource.driver-class-name} url: jdbc:mysql://${MP.datasource.host}:${MP.datasource.port}/${MP.datasource.database}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true username: ${MP.datasource.username} password: ${MP.datasource.password}mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3.1.2 application-dev.yml(注意要记得修改成自己的数据库哟)
MP: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver host: localhost port: 3306 database: mybatisplus_db username: root password: 1234
4.创建实体类和在数据库创建对应的数据表
4.1创建实体类
@Data //注意这里如果没有导入lombok依赖项会报错,需要自己添加该实体类的每个属性的get和set方法
public class User {
private Long id;
private String name;
private String password;
private Integer age;
private String tel;
}
4.2创建对应的数据表(下面是建表语句)
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号' ,
`name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名' ,
`password` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码' ,
`age` int(3) NOT NULL COMMENT '龄年' ,
`tel` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '电话' ,
PRIMARY KEY (`id`)
)
5.定义User的Mapper接口继承BaseMapper<User>接口
注意:BaseMapper<>中的泛型必须输入你要操作的数据表对应的实体类名称如我的"User",且此时在我们的实体类名称应与数据表名相同,否则MP无法进行自动映射,就找不到要操作的数据表后面,可以通过注解解决表名与实体名不同的问题)
这是最关键的一步,因为BaseMapper<>是MP的核心接口,提供了CRUD(增删改查)的方法定义,通过这个接口大大简化了我们对数据访问层的代码书写(只针对单表查询),在使用该Mapper接口提供的方法时MP通过动态代理自动生成BaseMapper的实现类自动实现了对数据层的访问和操作,不在需要自己苦苦的写查询语句!!好了,开发环境的搭建以及完毕,接下来就是常用方法的讲解
二、Mabatis-Plus的CRUD
1.数据插入
1.1打开项目的测试文件夹,我们将在这二进行项目代码编写以及测试
1.2通过控制注入,注入UserMapper,并使用Mapper接口的insert()方法
@Slf4j//注意这是Lombok包下的注解,提供在控制台能进行信息展示的方法 @SpringBootTest class MabatisPlusApplicationTests { @Autowired UserMapper userMapper; /** * 插入User数据 */ @Test void userInsertTest() { User user = new User();//构建实体对象 user.setName("小华"); user.setPassword("123456"); user.setTel("111111111111"); user.setAge(18); userMapper.insert(user);//直接调用Mapper接口的方法完成数据插入 }
执行结果(返回插入数据的条数):
2. 用户删除(通过id单独删除一条数据,同时删除多条数据)
/** * 通过用户id进行删除及批量删除 */ @Test void userDeleteTest() { int deleteNum = userMapper.deleteById(1835658620844974081L);//将删除的数据条数进行返回 int deleteNums = userMapper.deleteBatchIds(Arrays.asList(1835512087411494913L, 1835512111763591170L));//通过id进行批量删除 log.info("通过id删除记录数为{}", deleteNum); log.info("批量删除数据记录数{}", deleteNums); }
注意:因为MP框架会自动帮我们生成id,同时生成时默认调用的是雪花算法生成(可以兼容数值和字符串)的数字型其结构是:符号位+时间戳+工作进程位+序列号位,一个64bit的整数,8字节,正好为一个long类型数据所以当我们通过id删除单挑或者通过多条id删除多条数据时,应用long类型
执行结果(返回删除的数据条数,id不存在就返回0,这里我的语句是修改语句,是因为实现了逻辑删除,但结果是正确的,逻辑删除后面会进行讲解):
3.用户修改
/** * 通过用户id进行修改用户数据 */ @Test void userUpdateTest() { User user = new User(); user.setId(1835583781291474946L);//必须填写 user.setAge(20); user.setName("小红");//注意未设置字段不会设置为空值 int updateNum = userMapper.updateById(user);//会返回修改数据的记录数 log.info("修改id为{}的用户操作记录条数为{}", user.getId(), updateNum); }
执行结果(略)
4.用户查询
/** * 用户查询操作 */ @Test void userSelectTest() { //通过id查询 // User user = userMapper.selectById(1835514609693917185L); // log.info("根据id为{},查询出用户数据为{}", user.getId(), user); //通过id集合进行批量查询 /* List<Long> idList = Arrays.asList(1835514609693917185L, 1835519004863148033L); List<User> users = userMapper.selectBatchIds(idList); for (User user1 : users) { log.info("根据id为{},查询出用户数据为{}", user1.getId(), user1); }*/ //用户分页查询 Page<User> page = new Page<>(1, 1); userMapper.selectPage(page, null);//会将分页查询结果自动封装到page中 log.info("用户分页查询结果为{}", page.getRecords()); }
注意:本模块包含三个查询语句分别是id查询、id集合查询、分页查询(没有分页条件,后面讲解)
进行分页查询还需要配置MyBatis-Plus的分页拦截器
5.配置MyBatis-Plus的分页拦截器
5.1创建config包并在包下创建MPconfiguration
5.2编写配置文件代码
package com.mabatisplus.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 MPConfiguration { /** * 配置MyBatis-Plus的分页拦截器 * @return */ @Bean public MybatisPlusInterceptor pageInterceptor(){ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); //添加分页拦截器,实现分页查询 interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } }
5.3执行分页查询结果
三、常用注解详解
1.TableName注解
- 类型:类注解
- 添加位置:实体类上
- 作用:当当前实体类的名称与对应的数据表不同时添加,设置当前实体类与数据库表的对应关系
- 示例:
@TableName("t_user")
public class User {
private Long id;
}
注意: 如果类名使用驼峰命名法命名,表名使用对应的下划线分隔命名,MP可以自动进行映射,此时 TableName 注解可以省略,名字相同也可省略
2.TableFiled注解
- 类型:属性注解
- 位置:实体类属性上
- 作用:设置当前属性对应的数据库表中的字段关系
- 相关属性:
- value:设置数据库表字段名称
- exist:设置属性在数据库表字段中是否存在,默认为true
- 示例:
public class User {
@TableField(value="pwd")
private String password;
}
注意: 比如我有一个套餐实体类,里面会有一个包含的商品的List集合但对应数据库中应当时一张关系表来反映套餐和单个商品的联系,所以数据库表中就不会有对应字段所以需要在实体类上添加@Table Filed(exist="false")进行表识
3.TableId注解
- 类型:属性注解
- 位置:实体类中用于表示主键的属性上
- 作用:映射类中属性和表中主键对应关系,设置主键的生成策略
- 相关属性:
- value:设置数据库主键字段名称,如果属性名和字段名一致,可以省略此属性
- type:设置主键属性的生成策略,值参照IdType枚举值
- 示例:
public class User {
@TableId
private Long id;
}
- 主键生成策略:
- AUTO(0):使用数据库id自增策略控制id生成
- NONE(1):不设置id生成策略
- INPUT(2):用户手工输入id
- ASSIGN_ID(3):雪花算法生成id(可兼容数值型与字符串型)
- ASSIGN_UUID(4):以UUID生成算法作为id生成策略
注意:要使用主键生成策略可以进行全局配置,然后在对应的主键属性上加上@TableId注解(严格注意缩进)
mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: id-type: assign_id # 全局设置主键生成策略
四、条件构造器
介绍:条件构造器(Wrapper),可以控制最终生成的 SQL 语句的条件部分
1.QueryWrapper
通过QueryWrapper田间构造器,可以控制最终生成的查询类SQL语句
/** * 对用户进行条件查询(QueryWrapper) */ @Test void userQueryWrapperTest() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.select("name","password","tel","age");//指定字段进行查询(可选) queryWrapper.like("name", "小");//添加查询条件,姓名模糊查询 queryWrapper.ge("age", 13);//添加查询条件,年龄大于等于10岁 queryWrapper.orderByDesc("id");//添加查询排序条件按照id降序排序 // List<User> users = userMapper.selectList(queryWrapper);//执行条件查询返回多条查询数据 Page<User> page = new Page<>(1, 1); userMapper.selectPage(page, queryWrapper);//执行分页条件查询 log.info("用户分页查询结果为{}", page.getRecords()); }
2.LambdaQueryWrapper
和QueryWrapper的使用相同但是能够保证自己添加查询条件的字段的正确性
/** * 对用户进行条件查询(LambdaQueryWrapper) */ @Test void userLambdaQueryWrapperTest() { String queryName = "小"; LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.select(User::getName,User::getPassword,User::getAge,User::getTel);//指定字段进行查询 //添加查询条件,姓名模糊查询,添加condition属性判断queryName是否为空,不为空则执行次语句,为空则跳过跳过次语句 queryWrapper.like(true,User::getName, queryName); queryWrapper.ge(User::getAge, 13);//添加查询条件,年龄大于等于10岁 queryWrapper.orderByDesc(User::getName);//添加查询排序条件按照id降序排序 // List<User> users = userMapper.selectList(queryWrapper);//执行条件查询 Page<User> page = new Page<>(2, 1); userMapper.selectPage(page, queryWrapper);//执行分页查询 log.info("用户分页查询结果为{}", page.getRecords()); }
3.UpdateWrapper
LambdaUpdateWrapper类似于LambdaQueryWrapper,这里不再赘述
/** * 通过指定条件对满足条件的用户进行修改 */ @Test void userUpdateWrapperTest() { UpdateWrapper<User> updateWrapper = new UpdateWrapper<>(); updateWrapper.eq("name","小明");//添加where条件指定用户名为“小明”的数据 updateWrapper.set("name","小天");//将小明的姓名改为“小天” updateWrapper.set("password","123456");//将小明的密码改为“123456” int updateNum = userMapper.update(null, updateWrapper); log.info("修改记录数为{}",updateNum); }
五、逻辑删除的实现
删除数据库中的数据,可以通过物理删除,也可以通过逻辑删除。
- 物理删除 指的是直接将数据从数据库中删除
- 逻辑删除 指的是修改数据的某个字段,使其表示为已删除状态
5.1在需要的数据表中添加逻辑删除字段
注意:添加的deleted字段代表逻辑删除字段同时设置默认值为0表示未删除,1为删除
5.2在 application.yml 中配置逻辑删除相关配置项
mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 id-type: assign_id
5.3在实体类中添加逻辑删除的属性,并加入 @TableLogic 注解
三步执行完毕后,就完成了逻辑删除的配置
六、MP对Service的支持
MP 框架除了可以简化持久层代码开发,还为 Service 层提供了业务接口和实现类,可以简化 Service 层的开发。
6.1业务接口继承 MP 提供的 IService 接口
6.2业务实现类继承 MP 提供的 ServiceImpl 类
注意:
按照上面的截图建立对应的service包和实现类分别继承对应MP提供的实现类就能直接使用
@Autowired UserService userService; /** * MP对user的service层支持测试 */ @Test void userServiceTest(){ QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.like("name", "小");//添加查询条件,姓名模糊查询 queryWrapper.ge("age", 13);//添加查询条件,年龄大于等于10岁 queryWrapper.orderByDesc("id");//添加查询排序条件按照id降序排序 // List<User> users = userMapper.selectList(queryWrapper);//执行条件查询 Page<User> page = new Page<>(1, 1); userService.page(page,queryWrapper); log.info("userService的page查询结果为{}",page.getRecords()); }
七、MP的代码生成 (实体类、mapper、Service)
7.1下载MybatisX插件
MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。
下载方式:打开 IDEA,进入 File -> Settings -> Plugins -> Browse Repositories,输入 mybatisx 搜索并安装。
7.2配置数据源
完成Spring-Boot集成的数据库图像化界面的数据源配置
1.打开数据图形化界面
2.点击添加数据源
3.选择数据源
4.配置选项
5.添加数据库成功后,右键点击需要代码生成的数据表选择(可通过shift实现多选)
6.配置代码生成器的选项
7.配置完成后,点击next
8.根据需求进行勾选,完毕后点击finish生成对应文件