目录
application.yml配置(增加日志输出和mapper目录指定的配置)
前言
过年在家没有事做,待在家就是为国做贡献,武汉加油,中国加油,花了一点时间整理了一下mybatis plus集成springboot。
1.Mybatis plus简介
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。例如aop里面的环绕增强类似
1.1特点:
• 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
• 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
• 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
• 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
• 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
• 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
• 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
• 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
• 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
• 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
• 内置性能分析插件可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
• 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
1.2支持数据库:
mysql 、 mariadb 、 oracle 、 db2 、 h2 、 hsql 、 sqlite 、 postgresql 、 sqlserver
2.环境搭建及入门
2.1 创建一个springboot项目
输入项目的x,y坐标。点击下一步。
可以修改对应工作空间目录。点击finish
耐心的等待一段时间,这段时间在下载springboot的一些依赖包
如果,发现下载速度很卡,可以到maven conf里面的setting文件里,增加阿里云镜像。
项目创建完成。
2.2 创建表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(30) DEFAULT NULL COMMENT '姓名',
`age` int(11) DEFAULT NULL COMMENT '年龄',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱',
`create_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '小短腿鲁班', 18, 'test1@baomidou.com', '2020-01-30 17:21:56');
INSERT INTO `user` VALUES (2, '站撸王后羿', 20, 'test2@baomidou.com', '2020-01-30 17:21:59');
INSERT INTO `user` VALUES (3, '隐身兰陵王', 28, 'test3@baomidou.com', '2020-01-30 17:22:02');
INSERT INTO `user` VALUES (4, '98k百里守约', 20, 'test4@baomidou.com', '2020-01-15 17:22:04');
INSERT INTO `user` VALUES (5, '钩子哥钟馗', 24, 'test5@baomidou.com', '2020-01-08 17:22:08');
SET FOREIGN_KEY_CHECKS = 1;
2.3检查pom.xml依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cxyxs</groupId>
<artifactId>mybatisplus</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatisplus</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--junit测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
<!--简化代码插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<!-- druid阿里巴巴数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.4 application.yml配置
server:
port: 8888
spring:
datasource:
# 配置数据源
driver-class-name: com.mysql.cj.jdbc.Driver
# 使用druid连接池
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://127.0.0.1:3306/pro?useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username: root
password: root
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
注意:修改成自己对应的配置。配置mybatis-plus对应的日志,方便定位问题(开发环境使用)。
例如,上述代码转换成的sql为如下,这样就方面定位问题,项目开发中,日志格式输出也要规范,好的日志规范,能提高我们的开发效率。
2.5 实体类
package com.cxyxs.mybatisplus.entity;
import lombok.Data;
import java.util.Date;
@Data
public class User {
private Integer id;
private String name;
private Integer age;
private String email;
private Date createTime;
}
@Data注解,就是使用lombok的插件,简化代码
2.6 其他代码
package com.cxyxs.mybatisplus.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cxyxs.mybatisplus.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository //记得加上这个注解,不然,@Autowired会报红,但是可以查询数据
public interface UserMapper extends BaseMapper<User> {
}
启动类
package com.cxyxs.mybatisplus;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.cxyxs.mybatisplus.dao")
public class MybatisplusApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisplusApplication.class, args);
}
}
测试类
package com.cxyxs.mybatisplus;
import com.cxyxs.mybatisplus.entity.User;
import com.cxyxs.mybatisplus.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
class MybatisplusApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
}
/**
* 查询所有数据
*/
@Test
void select() {
List<User> list= userMapper.selectList(null);
list.forEach(System.out::println);
}
}
注意:使用了junit,不了解的可以百度一下
2.7 测试结果
到这里,mybatils plus入门的小demo就成功。说明我们的配置整体的配置都没有问题。
3.实战
说再多,看再多,还不如自己动手。这是社长我一直坚信的一点。
3.1 查询篇
这是所有的查询方法,具体可以通过查看他的源码,都有中文注释,再也不要跟社长会,我看不懂。。
3.1.1 常用查询
package com.cxyxs.mybatisplus;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cxyxs.mybatisplus.entity.User;
import com.cxyxs.mybatisplus.dao.UserMapper;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 程序猿学社
*/
@RunWith(SpringRunner.class)
@SpringBootTest
class MybatisplusApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
}
/**
* 查询所有数据
*/
@Test
void select() {
List<User> list= userMapper.selectList(null);
list.forEach(System.out::println);
}
/**
* 查询根据id返回对象
*/
@Test
void selectById(){
User user = userMapper.selectById(1);
System.out.println(user.toString());
}
/**
* 根据List的id集合查询对应的用户list
*/
@Test
void selectBatchIds(){
List<User> list = userMapper.selectBatchIds(Arrays.asList(1,2,10));
list.forEach(System.out::println);
}
@Test
void selectByMap(){
Map<String, Object> map = new HashMap<>();
map.put("age","20");
//查询年龄为20岁的所有用户,可以拼接多个值
//注意:建议尽量减少使用map这种方式。因为可能字段名可能存在修改的情况,如果,项目开发一段时间后,再修改,影响太大
List<User> list = userMapper.selectByMap(map);
list.forEach(System.out::println);
}
/**
* 查询大于20岁的学生,名称中包含小的人,带条件判断的,可以采用这种方式
* SELECT id,name,age,email,create_time FROM user WHERE (name LIKE ? AND age > ?)
*/
@Test
void selectListWrapper(){
//类似于hibernate
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name","小");
queryWrapper.gt("age", "17");
List<User> list = userMapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
/**
* 模糊查询名称包含王,年龄大于18,通过Lambda方式
* 强烈推荐这种方式:因为他是通过调用字段对应的get方法,实现跟数据库字段的一个映射
* 而不想之前的代码,key都是实体类的字符串的字段名,万一,字段有变动,根本就无法知道哪里有变动。
*/
@Test
void lambdaQueryWrapper(){
LambdaQueryWrapper<User> query = Wrappers.<User>lambdaQuery();
query.like(User::getName,"王").gt(User::getAge,18);
//.gt(User::getAge, 20);
List<User> list = userMapper.selectList(query);
list.forEach(System.out::println);
}
}
3.1.2 自定义sql
注意:mybatis-plus版本需大于等于3.0.7,才支持自定义sql
方案一 注解方式
package com.cxyxs.mybatisplus.dao;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.cxyxs.mybatisplus.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository //记得加上这个注解,不然,@Autowired会报红,但是可以查询数据
public interface UserMapper extends BaseMapper<User> {
@Select("select * from user ${ew.customSqlSegment}")
List<User> getAll(@Param(Constants.WRAPPER) Wrapper wrapper);
}
测试方法:
/**
* 获取自定义的MP(注解版本)
*/
@Test
void getAll(){
LambdaQueryWrapper<User> query = Wrappers.<User>lambdaQuery();
query.like(User::getName,"王").gt(User::getAge,18);
//.gt(User::getAge, 20);
List<User> list = userMapper.getAll(query);
list.forEach(System.out::println);
}
方案二 XML形式 Mapper.xml
UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cxyxs.mybatisplus.dao.UserMapper">
<select id="getXml" resultType="com.cxyxs.mybatisplus.entity.User">
select * from User ${ew.customSqlSegment}
</select>
</mapper>
application.yml配置(增加日志输出和mapper目录指定的配置)
###增加日志输出,方便定位问题
logging:
level:
root : warn
com.cxyxs.mybatisplus.dao: trace
###控制台输出格式
pattern:
console: '%p%m%n'
mybatis-plus:
mapper-locations: classpath*:/com/cxyxs/mybatisplus/mapper/*.xml
Dao类代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.cxyxs.mybatisplus.dao;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cxyxs.mybatisplus.entity.User;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
@Repository
public interface UserMapper extends BaseMapper<User> {
List<User> getXml(@Param("ew") Wrapper wrapper);
}
测试类
/**
* 获取自定义的MP(xml版本)
*/
@Test
void getAllXml(){
LambdaQueryWrapper<User> query = Wrappers.<User>lambdaQuery();
query.like(User::getName,"王").gt(User::getAge,18);
//.gt(User::getAge, 20);
List<User> list = userMapper.getXml(query);
list.forEach(System.out::println);
}
运行junit发现有如下报错?
卡了社长不短的时间,查了一段时间,才发现编译后的目录里面没有mapper文件?why?
解决方法:需要再build文件中如下代码。
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
划重点:mapper文件包,如果在resources目录下,就可以不加。
3.1.3 分页查询
package com.cxyxs.mybatisplus.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Description:mybatis-plus插件
* Author: 程序猿学社
* Date: 2020/2/2 15:26
* Modified By:
*/
@Configuration
public class MyBatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
}
1. selectPage方法
/**
* 分页查询
*/
@Test
void getSelectPage(){
LambdaQueryWrapper<User> query = Wrappers.<User>lambdaQuery();
//第一个参数表示当前页
//第二个参数表示当前页显示多少条
//第三个参数是否查询count
Page<User> page = new Page<>(2, 2,false);
Page<User> userPage = userMapper.selectPage(page, query);
//需要需要获取总记录数或者总页数,可以自己查看Page源码里面都有那些字段
List<User> records = userPage.getRecords();
records.forEach(System.out::println);
}
通过日志,我们可以自动,分页插件,一个分页,需要查两次,一次查count,还有一次查对应的数据。
扩展:
学习了mybatis-plus后,发现他只是对sql做一个增强,通过这种方式,例如,做权限管理系统,通过权限控制数据,深圳市的管理,只能看深圳的数据,广东省的管理只能看广东省的数据,全国的管理,可以看全国的数据,我们就可以通过增强实现。在写好的sql后,通过mybatis-plus类似的方式,把权限的条件拼接上,这样我们的代码,就更好维护。学习就是主要是还是学习别人的思想,这样我们才能有大的提升。
2. selectMapsPage方法
/**
* 分页查询 Map方式
*/
@Test
void getSelectMapsPage(){
QueryWrapper<User> query = new QueryWrapper<User>();
//第一个参数表示当前页
//第二个参数表示当前页显示多少条
Page<Map<String,Object>> page = new Page<>(2, 2);
IPage<Map<String, Object>> maps = userMapper.selectMapsPage(page,query);
maps.getRecords().forEach(System.out::println);
}
3.2 修改篇
updateById 根据id修改用户信息
/**
* 根据id修改用户信息
*/
@Test
void updateUserById(){
User user = new User();
user.setId(1);
user.setName("小短腿鲁班-程序猿学社");
int result = userMapper.updateById(user);
System.out.println(result>0 ? "修改成功":"修改失败");
}
update通过条件修改用户信息
/**
* 通过条件修改用户信息
*/
@Test
public void updateWrapper(){
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.eq("age","18");
User user = new User();
user.setName("小短腿鲁班-程序猿学社123");
int result = userMapper.update(user, wrapper);
System.out.println(result>0 ? "修改成功":"修改失败");
}
通过条件修改用户信息(需要修改的字段少,可通过这种方式)
/**
* 通过条件修改用户信息(需要修改的字段少,可通过这种方式)
*/
@Test
public void updateWrapper1(){
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.eq("age","18").set("name","小短腿鲁班-程序猿学社456");
int result = userMapper.update(null, wrapper);
System.out.println(result>0 ? "修改成功":"修改失败");
}
通过条件修改用户信息(lambda方式,强烈推荐)
/**
* 通过条件修改用户信息(需要修改的字段少,可通过这种方式)
* 强烈推荐,避免出错
*/
@Test
public void updatelamWrapper(){
LambdaUpdateWrapper<User> updateWrapper = Wrappers.<User>lambdaUpdate();
updateWrapper.eq(User::getAge,"18").set(User::getName,"小短腿鲁班-程序猿学社789");
int result = userMapper.update(null, updateWrapper);
System.out.println(result>0 ? "修改成功":"修改失败");
}
lambda链表方式,根据条件修改用户记录
/**
* lambda链表方式,根据条件修改用户记录
*/
@Test
public void updatelambdaWrapper(){
boolean result = new LambdaUpdateChainWrapper<>(userMapper)
.eq(User::getAge, "18").set(User::getName, "小短腿鲁班-程序猿学社1314").update();
System.out.println(result ? "修改成功":"修改失败");
}
3.3 删除篇
根据id删除对应的用户记录
/**
* 根据id删除对应的用户记录
*/
@Test
public void deleteById(){
int result = userMapper.deleteById(6);
System.out.println(result>0 ? "删除成功":"删除失败");
}
根据id批量删除
/**
* 根据id批量删除
*/
@Test
public void deleteBatchIds(){
int result = userMapper.deleteBatchIds(Arrays.asList(6, 7, 8));
System.out.println("批量删除条数:"+result);
}
根据map里面的条件,删除对应的数据
/**
* 根据map里面的条件,删除对应的数据
*/
@Test
public void deleteByMap(){
Map<String,Object> map = new HashMap<>();
map.put("age","38");
int result = userMapper.deleteByMap(map);
System.out.println(result>0 ? "删除成功":"删除失败");
}
lambda链表方式实现通过条件删除对应数据
/**
* lambda链表方式实现通过条件删除对应数据
*/
@Test
public void deleteChainWrapper(){
boolean remove = new LambdaUpdateChainWrapper<>(userMapper).eq(User::getAge, 39).remove();
System.out.println(remove ? "删除成功":"删除失败");
}
lambda通过条件删除对应数据
/**
* lambda通过条件删除对应数据
*/
@Test
public void deleteWrapper(){
LambdaQueryWrapper<User> lambdaQuery= Wrappers.<User>lambdaQuery();
lambdaQuery.eq(User::getAge, 39);
int result = userMapper.delete(lambdaQuery);
System.out.println(result>0 ? "删除成功":"删除失败");
}
3.4 插入篇
数据库是自动增长,设置实体类也为自增长模式
插入用户信息
/**
* 新增用户信息
*/
@Test
public void insert(){
User user = new User();
user.setName("程序猿学社123");
user.setAge(11);
user.setCreateTime(new Date());
user.setEmail("1024@qq.com");
int result = userMapper.insert(user);
System.out.println(result>0 ? "新增成功":"新增失败");
}
发现插入的时间和数据库的时间有时差?
serverTimezone=GMT%2B8
批量插入
package com.cxyxs.mybatisplus.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cxyxs.mybatisplus.entity.User;
import org.springframework.stereotype.Service;
/**
* Description:
* Author: 程序猿学社
* Date: 2020/2/2 18:47
* Modified By:
*/
@Service
public interface UserService extends IService<User> {
}
package com.cxyxs.mybatisplus.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cxyxs.mybatisplus.dao.UserMapper;
import com.cxyxs.mybatisplus.entity.User;
import com.cxyxs.mybatisplus.service.UserService;
import org.springframework.stereotype.Service;
/**
* Description:
* Author: 程序猿学社
* Date: 2020/2/2 18:51
* Modified By:
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
/**
* 批量插入
*/
@Test
public void saveBatch(){
System.out.println("123");
List<User> users = new ArrayList<>();
for(int i=0;i<5;i++){
User user = new User();
user.setName("程序猿学社"+i);
user.setAge(11);
user.setCreateTime(new Date());
user.setEmail("1024@qq.com");
users.add(user);
}
boolean result = userService.saveBatch(users);
System.out.println(result ? "批量新增成功":"批量新增失败");
}
不存在则新增,新增则修改
/**
* 不存在则新增,新增则修改
*/
@Test
public void saveOrUpdate(){
User user = new User();
user.setName("程序猿学社520");
user.setAge(11);
user.setCreateTime(new Date());
user.setEmail("1024@qq.com");
user.setId(21);
boolean result = userService.saveOrUpdate(user);
System.out.println(result ? "成功":"失败");
}
3.5逻辑删除篇
逻辑删除实际上就是假删除。在数据表中,通过一个字段标识该字段是否已删除
表结构变动,增加一个是否删除的字段
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(30) DEFAULT NULL COMMENT '姓名',
`age` int(11) DEFAULT NULL COMMENT '年龄',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱',
`create_time` datetime NOT NULL COMMENT '创建时间',
`is_delete` int(1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;
实体类变动
增加@TableLogin注解标识该字段是逻辑位字段。
测试代码
/**
* 根据id删除对应的用户记录
*/
@Test
public void deleteById(){
int result = userMapper.deleteById(21);
System.out.println(result>0 ? "删除成功":"删除失败");
}
通过测试,我们可以发现,我们明明跑到删除语句,但是,底层会给我们拼上is_delete=0,只有标识位为0的数据,我们才能删除。新增,修改都是同上,注意:我们自己写的mybatis文件里面的sql,不会补上。
查询的数据排除标识逻辑位
有社友反馈说,每次查询,返回都返回标识位,太浪费了,能不能把逻辑位,不显示出来,当然可以呀
@Test
void selectById(){
User user = userMapper.selectById(22);
System.out.println(user.toString());
}
改进方案:
增加该注解
再次查询,我们可以看到,没有is_delete字段了
注意:自己写的mybatils的sql语法,如果写了is_delete字段,返回还会有值。这里所有的注解,只是针对mybatis-plus他自己实现的语法而言。
3.6自动填充篇
表结构变动
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(30) DEFAULT NULL COMMENT '姓名',
`age` int(11) DEFAULT NULL COMMENT '年龄',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL,
`is_delete` int(1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;
实体类变动
自动填充的类
package com.cxyxs.mybatisplus.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* Description:
* Author: 程序猿学社
* Date: 2020/2/2 21:02
* Modified By:
*/
@Component
public class AutoFill implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
//考虑到没有createTime字段,也执行了,所以,这里需要增加判断
boolean flag = metaObject.hasGetter("createTime");
if(flag){
setFieldValByName("createTime",new Date(),metaObject);
}
}
@Override
public void updateFill(MetaObject metaObject) {
Object flag = getFieldValByName("updateTime",metaObject);
//如果有给修改时间赋值,就不用给该字段赋值
if(flag == null){
setFieldValByName("updateTime",new Date(),metaObject);
}
}
}
测试类
/**
* 新增用户信息
*/
@Test
public void insert(){
User user = new User();
user.setName("程序猿学社456");
user.setAge(11);
user.setEmail("1024@qq.com");
int result = userMapper.insert(user);
System.out.println("id为:"+user.getId());
System.out.println(result>0 ? "新增成功":"新增失败");
}
/**
* 根据id修改用户信息
*/
@Test
void updateUserById(){
User user = new User();
user.setId(1);
user.setName("小短腿鲁班-程序猿学社");
user.setUpdateTime(new Date());
int result = userMapper.updateById(user);
System.out.println(result>0 ? "修改成功":"修改失败");
}
这里设置了修改时间,就不用跑填充的类
博主,java小白,有问题欢迎在下方留言。大家互相交流,互相进步!
每周更新,分享各个技术点面试、结构和算法、源码分析等干货