天天看点

MyBatis-Plus实现增删改查CURD

CURD:增加(Create)、检索(Retrieve)、更新(Update)和删除(Delete)

MyBatis-Plus是MyBatis的增强工具,在MyBatis基础上只做增强,不做改变

作用:为了简化开发,提高效率

MyBatis-Plus的首次使用

          • 1.创建数据库,创建数据表
          • 2.创建springboot项目工程
          • 3.引入和mp相关的依赖
          • 4.配置数据库
          • 5.编写核心代码
            • ①.实体类
            • ②.接口
            • ③.启动类
            • ④.Mybatis-plus的配置类
            • ⑤.自动填充处理类
            • ⑥.测试类(**重要,实现增删改查)
          • 6.底层逻辑
          • 7.小节
1.创建数据库,创建数据表
# 创建数据库
create database practice character set utf8;

# 创建User表
create table User(
	//测试主键策略
	id bigint(20) primary key,
	name varchar(30) null default null,
	age int(11) null default null,
	email varchar(50) null default null,
	//测试自动填充
	create_time datatime null default null,
	update_time datatime null default null,
	//测试乐观锁
	version int null default null,
	//测试逻辑删除
	status int null default null
)

# 添加数据
insert into User (id,name,age,email) values
(1,'Jane',10,'[email protected]',null),
(2,'Jack',20,'[email protected]',null),
(3,'Tom',26,'[email protected]',null),
(4,'Sandy',21,'[email protected]',null),
(5,'Billie',24,'[email protected]',null)
           
2.创建springboot项目工程
file - - new - - project - - Spring Initializr - - Java Version:8 - - Spingboot依赖随便选一个版本
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<!-- 到pom.xml中修改Springboot的依赖版本 -->
	<version>2.2.1.RELEASE</version>
	<relativePath/> <!-- lookup parent from repository -->
</parent>
           
3.引入和mp相关的依赖
pom.xml
<!--junit测试类依赖-->
<dependency>
	<groupId>org.junit.platform</groupId>
	<artifactId>junit-platform-launcher</artifactId>
	<scope>test</scope>
</dependency>

<!--mybatis-plus的依赖-->
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>3.3.1</version>
</dependency>

<!--mysql依赖-->
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
</dependency>

<!--安装lombok插件,settings——plugins——搜索lombok——安装-->
<!--lombok依赖,简化实体类,可以不需要手动生成get、set等方法,通过注解@Data来实现-->
<!-- https://blog.csdn.net/zhangmiaoping23/article/details/105707428/ -->
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<optional>true</optional>
</dependency>
           
4.配置数据库
application.properties:在src/main/resources/application.properties中配置数据库信息
# mysql数据库连接

# 1.spring boot2.0版本(内置jdbc5驱动)
# spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
# spring.datasource.username=root
# spring.datasource.password=root123

# 2.spring boot2.1及以上版本(内置jdbc8驱动)(driver和url的变化)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# serverTimezone=GMT%2B8为时区
spring.datasource.url=jdbc:mysql://localhost:3306/practice?serverTimezone=GMT%2B8  
spring.datasource.username=root
spring.datasource.password=root123

# 查看sql输出日志(mybatis日志) 为了查看mybaits-plus执行select的底层逻辑
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
           
5.编写核心代码

①.实体类

# com.atguigu.demomptest.entity.User
//@Data是lombok生成的注解,会将get、set方法和string方法都自动生成,可以点开左边的Structure查看
@Data
public class User {
	//ASSIGN_ID雪花算法,分布式ID生成器,按照时间自增排序
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;
    //INSERT,添加时自动填充值
    @TableField(fill= FieldFill.INSERT)
    private Date createTime;  //create_time
    //INSERT_UPDATE,修改时自动填充值(添加时没有值,修改时才设置值)
    @TableField(fill=FieldFill.INSERT_UPDATE)
    private Date updateTime;  //update_time
    //实现乐观锁
    @Version
    @TableField(fill= FieldFill.INSERT)   //添加一个默认值
    private Integer version;
    //实现逻辑删除
    @TableLogic
    @TableField(fill=FieldFill.INSERT)
    private Integer status;
}
           

②.接口

# com.atguigu.demomptest.mapper.UserMapper
//BaseMapper里面封装了增删改查等操作,泛型类为User
@Repository
public interface UserMapper extends BaseMapper<User>{}
           

③.启动类

# com.atguigu.demomptest.DemomptestApplication
@SpringBootApplication

// 将其放到config.MpConfig配置类中
// 因为UserMapper要动态生成它的实现类对象,动态生成对象默认查找不到,所以使用Mapper扫描来查找
// @MapperScan("com.atguigu.demomptest.mapper")
public class DemomptestApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemomptestApplication.class, args);
	}
}
           

④.Mybatis-plus的配置类

# com.atguigu.demomptest.config.MpConfig
// Mybatis-plus的配置类
// 说明这是一个配置类的注解
@Configuration
// 因为UserMapper要动态生成它的实现类对象,动态生成对象默认查找不到,所以使用Mapper扫描来查找
@MapperScan("com.atguigu.demomptest.mapper")
public class MpConfig {

    /*配置乐观锁的插件*/
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
        return new OptimisticLockerInterceptor();
    }
    /* 配置分页查询的插件 */
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        return new PaginationInterceptor();
    }
}

           

⑤.自动填充处理类

# com.atguigu.demomptest.handler.MyMetaObjectHandler
//把这个类交给spring管理
//@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注,标识为一个Bean
@Component

//实现MetaObjectHandler接口,并重写insertFill和updateFill两个方法
public class MyMetaObjectHandler implements MetaObjectHandler {

    // 添加时自动填充值,到创建时间和修改时间中,初始修改时间就是第一次创建时的时间
    @Override
    public void insertFill(MetaObject metaObject) {
        //setFieldValByName是设置属性值根据名字
        //第一个参数:被填充实体类的字段名
        //第二个参数:填充的值
        //第三个参数:metaObject对象
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
        //version默认值设置为1
        this.setFieldValByName("version",1,metaObject);
        //status在添加时自动填充默认为0,未被删除状态(1是被删除状态)
        this.setFieldValByName("status",0,metaObject);
    }

    // 修改时自动填充值
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}
           

⑥.测试类(**重要,实现增删改查)

# com.atguigu.demomptest/DemommptestApplicationTests
//给指定的字段或方法注入所需的外部资源
@Autowired
private UserMapper userMapper;   //这里会报错,原因是实现类是动态生成的,如果想不报错在UserMapper上加一个@Repository注解

# 增
@Test
public void testadd(){
	User user=new User();
	//没有设置id属性主键自增长,但mybatis-plus会使用主键策略自动生成id值
	user.setName("lucy");
	user.setAge(18);
	user.setEmail("[email protected]");
	int insert=userMapper.insert(user);
	System.out.println(insert);
}

# 删
//根据id删除
@Test
public void testDeleteById(){
	int rows=userMapper.deleteById(1L);
	System.out.println(rows);
}

//批量删除
@Test
public void testDeleteByIds(){
	int rows=userMapper.deleteBatchIds(Arrays.asList(2,3));
	System.out.println(rows);
}

//简单条件删除
@Test
public void testDeleteByIf(){
	Map<String,Object> map=new HashMap();
	map.put("name","Lily");
	map.put("age",19);
	int rows=userMapper.deleteByMap(map);
	System.out.println(rows);
}

//物理删除:真实删除,将数据从数据库中删除
//逻辑删除:假删除,方便删除之后的数据恢复,被删除记录的status字段被修改为“被删除状态”

//逻辑删除
//在表中添加一个status字段,作为删除的标准,每次删除时,修改标志位,0代表没有删除,1代表删除
//UPDATE user SET status=1 WHERE id=? AND status=0 查询条件有一个status=0,即查询的都是没有被删除过的记录,被删除过的记录就不会被查询出来了
@Test
public void testDeleteByLogic(){
	int rows=userMapper.deleteById(1441596779656179713L);     //在做了逻辑删除的配置后,再使用id进行删除,执行的语句变成了修改id=?并且status为0的记录,如果status原来就是1(被删除过了),也不会再被删除,
	System.out.println(rows);
}

# 改
//update user set name=? where id=?
@Test
public void testupdate(){
	User user=new User();
	//需要将数字后面加一个L
	user.setId(1441402736913481729L);
	user.setName("Lily");
	int count=userMapper.updateById(user);
	System.out.println(count);
}

# 查
//查询出一个集合
@Test
public void findAll() {
	List<User> users=userMapper.selectList(null);
	System.out.println(users);
}

// 多个id的批量查询
// 使用selectBatchIds方法,传入一个id集合
// List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> var1);
// SELECT id,name,age,email,create_time,update_time,version FROM user WHERE id IN ( ? , ? , ? )
// 问题:selectBatchIds怎么能确定查询的是id
@Test
public void testSelectByids(){
	List<User> users=userMapper.selectBatchIds(Arrays.asList(1,2,3));
	System.out.println(users);
}

// 简单的条件查询  简单了解,一般条件查询使用条件构造器来查询
// 使用selectByMap方法,使用Map来存要传的参数
// List<T> selectByMap(@Param("cm") Map<String, Object> var1);
// SELECT id,name,age,email,create_time,update_time,version FROM user WHERE name = ? AND age = ?
@Test
public void testSelectByif(){
	Map<String,Object> columnMap =new HashMap<>();
	columnMap.put("name","Jack");
	columnMap.put("age",20);
	List<User> users=userMapper.selectByMap(columnMap);
	System.out.println(users);
}

// 分页查询selectPage    也可以使用selectMapsPage进行分页查询,但是不常用
// 需要在MpConfig配置分页查询的插件
@Test
public void testselectPage(){
	// 引入mybatisplus的Page依赖
	// 传入2个参数,第一个是当前第几页,第二个是每页显示多少条记录
	Page<User> page=new Page(1,3);  //SELECT id,name,age,email,create_time,update_time,version FROM user LIMIT ?,?
	Page<User> userPage=userMapper.selectPage(page,null);
	//返回对象得到分页所有数据
	long pages=userPage.getPages();   //总页数 3页    SELECT COUNT(1) FROM user
	long current =userPage.getCurrent();  //当前页 第1页
	long total=userPage.getTotal();     //表中的总记录条数  9条数据
	List<User> users=userPage.getRecords(); //当前页数据集合(3条)
	boolean hasNext=userPage.hasNext(); //判断当前页是否有下一页  true
	boolean hasPrevious=userPage.hasPrevious(); //判断当前页是否有上一页  false(第1页每页上一页)
	System.out.println(pages);
	System.out.println(current);
	System.out.println(total);
	System.out.println(users);
	System.out.println(hasNext);
	System.out.println(hasPrevious);
}

//使用MyBatis-Plus的条件构造器实现一些复杂的查询操作
@Test
public void testWrapper(){
	//构造一个条件构造器对象
	QueryWrapper<User> queryWrapper=new QueryWrapper<>();

	//1.ge(大于等于) | gt(大于) | le(小于等于) | lt(小于) | isNull(为空) | isNotNull(不为空)
	//queryWrapper.ge("age",19);

	//2.eq(等于) | ne(不等于)
	//queryWrapper.eq("age",19);

	//3.between(在某个范围) | notBetween(不在某个范围)
	queryWrapper.between("age",19,22);

	//4.like(查出所有包含L的记录,like "%L%") | notLike(所有不包含L的实体记录 not like "%L%")
	//  likeLeft(like "L%",所有左边包含L的记录) | likeRight(like "%L",所有右边包含L的记录)
	//queryWrapper.likeRight("name","L");
	//queryWrapper.notLike("name","L");

	//5.orderBy | orderByDesc(降序排列) | orderByAsc(升序排列)
	//根绝id升序排列
	queryWrapper.orderByAsc("id");

	//传入条件构造器
	List<User> users=userMapper.selectList(queryWrapper);
	System.out.println(users);
}

# 测试乐观锁
@Test
public void testOptimisticLocker(){
	//根据id查询
	User user=userMapper.selectById(1441561265146171394L);
	//修改
	user.setName("张三");
	//这里不需要手动设置version值,因为mybatis-plus会自动将version值+1
	//UPDATE user SET name=?, age=?, email=?, create_time=?, update_time=?, version=? WHERE id=? AND version=?
	userMapper.updateById(user);
}
           
6.底层逻辑
MyBatis-Plus实现增删改查CURD
7.小节

增加

主键策略:ASSIGN_ID雪花算法,分布式ID生成器,按照时间自增排序生成主键ID值

删除

物理删除和逻辑删除:在表中添加一个status字段,删除其实是update status=1

根据id删除:deleteById

批量删除:deleteBatchIds

简单条件删除:deleteByMap

修改

自动填充:@TableField(fill= FieldFill.INSERT|INSERT_UPDATE)

乐观锁:@Version,解决丢失修改的问题

查询

查询出一个集合:selectList

多个id的批量查询: selectBatchIds

简单的条件查询:selectByMap

分页查询selectPage:selectPage

使用MyBatis-Plus的条件构造器实现一些复杂的查询操作:QueryWrapper