先将快速开始01看完,再看这个文档

配置日志

我们所有的sql现在都是不可见的,我们希望知道它是怎么执行的,所以我们就必须看日志,开发的时候打开,上线的时候关闭

application.properties配置日志

#配置日志
#默认的控制台输出
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

CRUD扩展

插入操作

注意:User是Long不是long

package com.jmu;

import com.jmu.mapper.UserMapper;
import com.jmu.pojo.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 MpApplicationTests { @Autowired
private UserMapper userMapper; @Test
public void testInsert(){
User user = new User();
user.setName("java");
user.setAge(3);
user.setEmail("10134@qq.com");
int insert = userMapper.insert(user);
System.out.println(insert);
System.out.println(user);
} }

主键生成策略

涉及到一个注解@TableId

@TableId描述:主键注解

属性 类型 必须指定 默认值 描述
value String "" 主键字段名
type Enum IdType.NONE 主键类型

IdType

描述
AUTO 数据库ID自增(需要在数据中也开启自增)
NONE 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUT insert前自行set主键值
ASSIGN_ID(默认) 分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID 分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)
ID_WORKER 分布式全局唯一ID 长整型类型(please use ASSIGN_ID)
UUID 32位UUID字符串(please use ASSIGN_UUID)
ID_WORKER_STR 分布式全局唯一ID 字符串类型(please use ASSIGN_ID)

使用

package com.jmu.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data; @Data
public class User {
@TableId(type =IdType.ASSIGN_ID)
private Long id;
private String name;
private Integer age;
private String email;
}

雪花算法

详情查看链接

更新操作

updateById通过条件实现动态sql

@Test
public void testUpdate(){
User user = new User();
user.setId(2L);
user.setName("java-02");
user.setAge(23);
int update = userMapper.updateById(user);
System.out.println(update);
}

自动填充

官网日志填充,可以先看看说不定到时候下面的方法就过时了。

创建时间、修改时间!这些操作都是自动化完成的,我们不希望手动更新!

阿里巴巴开发手册:所有的数据库表:gmt_create、gmt_modified几乎所有的表都要配置上!而且需要自动化

代码级别的方式

  1. 在表中新增字段 create_time,update_time

  1. 实体类字段属性上需要增加注解

一定要是LocalDateTime,而且Mybatis-Plus默认使用驼峰命名,所以是update_time-updateTime,user-User

//表示在insert的时候有createTime这个字段
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
//表示在insert和update的时候都有updateTime这个字段
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
  1. 编写处理器处理这个注解即可(可以新建一个handler包中写这个类)
  • 而且因为使用了LocalDateTime,所以字段属性也是要private LocalDateTime,而且类型如果不匹配的话是无法填充的,需要对应。
  • @Component 一定不要忘记把处理器加到IOC容器中
@Slf4j
@Component //一定不要忘记把处理器加到IOC容器中
public class MyMetaObjectHandler implements MetaObjectHandler { @Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill...");
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
} @Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill...");
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}

乐观锁

简单介绍

乐观锁:十分乐观,总是认为不会出现问题,无论干什么都不去上锁!如果出现了问题,再次更新值测试。

主要解决:丢失更新问题

丢失更新问题描述:即多人同时修改同一条数据

比如:有两个线程都要去改一行数据的某个属性值,两个线程同时开启事务,一个线程首先提交事务,修改了值。这个时候另外一个线程又提交,但是这时候的值进行再次的更新,将第一个提交的线程覆盖了,所以导致首先提交的数据丢失更新 。正确的过程应该是线程一开启事务,到提交事务后。线程二再去开启事务,提交事务。

乐观锁实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

实现乐观锁

(1)在数据库中添加version字段

(2)实体类中添加version字段

并添加@version注解

@Version
private Integer version;

(3)配置乐观锁插件

你可以把插件直接放在springboot的启动类中,但是,我们更加建议将插件放在配置中config.MpConfig

package com.jmu.config;

import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//配置随便取,重要的是加@Configuration注解
//顺便把之前放在启动类中的扫描包一起放在配置类这边
@MapperScan("com.jmu.mapper")
@Configuration
public class MpConfig {
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}

测试乐观锁

(1)成功案例

@Test
public void testOptimisticLocker(){
//根据id查询数据
User user = userMapper.selectById(1313089952522756098L);
System.out.println(user);
//修改
user.setAge(10);
userMapper.updateById(user);
}

注意:只能先查询,后更新才乐观锁生效

@Test
public void testOptimisticLocker(){
User user = new User();
user.setId(1313089952522756098L);
user.setAge(10);
userMapper.updateById(user);
}

(2)失败案例

@Test
public void testOptimisticLocker(){
//根据id查询数据
User user1 = userMapper.selectById(1313089952522756098L);
user1.setAge(1);
//模拟线程抢占
User user2 = userMapper.selectById(1313089952522756098L);
user2.setAge(2);
userMapper.updateById(user2);
userMapper.updateById(user1);
}

查询操作

//测试查询
@Test
public void testSelectById(){
User user = userMapper.selectById(1L);
System.out.println(user);
}
//测试批量查询
@Test
public void testSelectByIds(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 33));
users.forEach(System.out::println);
}
//条件查询 map
@Test
public void testselectByMap(){
HashMap<String, Object> map = new HashMap<>();
map.put("name","java");
map.put("age","3");
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}

分页查询

(1)配置插件

和配置乐观锁差不多

@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}

(2)测试分页

//测试分页
@Test
public void testPage(){
//当前页 分页大小
Page<User> page = new Page<>(2,5);
userMapper.selectPage(page,null);
page.getRecords().forEach(System.out::println);
}

删除操作

@Test
public void testDelete(){
userMapper.deleteById(null);
userMapper.deleteByMap(map);
userMapper.deleteBatchIds(Arrays.asList(1,2,3));
userMapper.delete(null);
}

逻辑删除(软删除)

物理删除:从数据库中直接移除

逻辑删除:在数据库中没有被移除,而是通过一个变量来让他失效 delete=0=>delete=1

(1)表中添加字段

默认值也可以用代码实现


@TableField(fill=FieldFill.INSERT)
private Integer deleted; public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
this.strictInsertFill(metaObject, "deleted", Integer.class, 0);
...

(2)在application.properties添加配置

注意:是delete-value不是delete-field

# 逻辑已删除值(默认为 1)
mybatis-plus.global-config.db-config.logic-delete-value=2
# 逻辑未删除值(默认为 0)
mybatis-plus.global-config.db-config.logic-not-delete-value=1

(3)在实体类添加注解@TableLogic

@TableLogic
private Integer deleted;

(4)测试删除

条件构造器 Wrapper

写一些复杂的sql就可以使用他来替代

具体可以看官网的条件构造器文档

注意wrapper.like("name","a")里面的name指的是数据中的字段名

package com.jmu;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jmu.mapper.UserMapper;
import com.jmu.pojo.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;
import java.util.Map; @SpringBootTest
public class WrapperTest {
@Autowired
private UserMapper userMapper; @Test
public void test1(){
//查询name不为空的用户,并且邮箱不为空的用户,年龄大于等于12
// (name IS NOT NULL AND email IS NOT NULL AND age >= ?)
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name").isNotNull("email").ge("age",12);
userMapper.selectList(wrapper).forEach(System.out::println);
}
@Test
public void test2(){
//查询年龄在20-30岁之间的用户
//(age BETWEEN ? AND ?)
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age",2,13);
userMapper.selectList(wrapper).forEach(System.out::println);
}
@Test
public void test3(){
//查询名字中包含a的用户,并且邮箱以t开头
// (name LIKE ? AND email LIKE ?)
QueryWrapper<User> wrapper = new QueryWrapper<>();
//likeRight理解成%(Like)的在右边
wrapper.like("name","a")
.likeRight("email","t");
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
@Test
public void test4(){
//查询id大于10的用户
// (id IN (select id from user where id > 10))
QueryWrapper<User> wrapper = new QueryWrapper<>();
//likeRight理解成%(Like)的在右边
wrapper.inSql("id","select id from user where id > 10");
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
}

Mybatis-Plus02 CRUD的更多相关文章

  1. MyBatis:CRUD功能

    在前面已经自动生成了mapper和pojo,接下来我们实现mybatis的CRUD功能,先新建service.controller层的方法. 这里的sid是一个开源的id生成类,写完后,我们还需要在启 ...

  2. Mybatis的CRUD案例

    一.Mybatis增删改查案例 上一节<Mybatis入门和简单Demo>讲了如何Mybatis的由来,工作流程和一个简单的插入案例,本节主要继上一讲完整的展示Mybatis的CRUD操作 ...

  3. 【MyBatis】MyBatis实现CRUD操作

    1.实现基本CRUD功能 使用MyBatis对数据完整的操作,也就是CRUD功能的实现.根据之前的内容,要想实现CRUD,只需要进行映射文件的配置. 范例:修改EmpMapper.xml文件,实现CR ...

  4. SpringBoot 整合 Mybatis 进行CRUD测试开发

    今天来和大家分享下 Spring Boot 整合 MyBatis 的 CRUD 测试方法开发.因为 MyBaits 有两种开发形式,一种基于注解,一种基于 xml . SpringBoot配置文件也有 ...

  5. 基于mybatis的CRUD

    u  基于Mybatis的CRUD u  掌握MyBatis的结果类型-resultMap和resultType u  掌握MyBatis的参数类型 u  掌握#和$两种语法 1      基于myb ...

  6. 05 Mybatis的CRUD操作和Mybatis连接池

    1.CRUD的含义 CRUD是指在做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete)几个单词的首字母简写.主要被用在描述软件系统中 ...

  7. 03 Mybatis:05.使用Mybatis完成CRUD

    mybatis框架:共四天 明确:我们在实际开发中,都是越简便越好,所以都是采用不写dao实现类的方式.不管使用XML还是注解配置. 第二天:mybatis基本使用 mybatis的单表crud操作 ...

  8. mybatis(CRUD)

    3.mybatis(CRUD) 有了mybatis,我们要对数据库进行增删改查只需要操作接口和mapper.xml文件,然后进行测试就可以了. 实例代码如下: 接口 public interface ...

  9. MyBatis之CRUD

    1 mybatis框架介绍 1.1回顾jdbc操作数据库的过程 1.2 mybatis开发步骤 A.提供一个SqlMapperConfig.xml(src目录下),该文件主要配置数据库连接,事务,二级 ...

  10. MyBatis Tutorial – CRUD Operations and Mapping Relationships – Part 1---- reference

    http://www.javacodegeeks.com/2012/11/mybatis-tutorial-crud-operations-and-mapping-relationships-part ...

随机推荐

  1. Python装饰器(2)

    上一篇介绍了装饰器的常规使用方法,即函数形式的装饰器.这篇文章中,进一步介绍类class跟装饰器的相关知识. [用装饰器来装饰类函数] 这是今天介绍的第一种使用场景,比较常见.因为目前好多的编程语言都 ...

  2. 从本质彻底精通Git——4个模型1个周期1个史观1个工作流

    一.什么是Git? Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git是Linus Torvalds为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软 ...

  3. java例题_08 输入特定数字求和(n个a位数递增求和问题)

    1 /*8 [程序 8 输入数字求和] 2 题目:求 s=a+aa+aaa+aaaa+aa...a 的值,其中 a 是一个数字.例如 2+22+222+2222+22222(此时共有 5 个数相加), ...

  4. c++一些概念

    面向对象语言三大特征: 封装,多态,继承 封装: 1.将函数定义到结构体内部,就是封装. 2.编译器会自动传递结构体的指针给函数. 类: 带有函数的结构体,称为类. 成员函数: 结构体里面的函数,称为 ...

  5. elasticsearch之Java调用本地代码

    虽然Java虚拟机为开发人员屏蔽了底层的实现细节,使得开发人员不用考虑底层操作系统的差异性.不过在某些应用程序中,还是免不了要直接与底层操作系统上的原生代码进行交互.今天我们就来看一下Java对本地调 ...

  6. 系统编程-网络-tcp客户端服务器编程模型(续)、连接断开、获取连接状态场景

    相关博文: 系统编程-网络-tcp客户端服务器编程模型.socket.htons.inet_ntop等各API详解.使用telnet测试基本服务器功能 接着该上篇博文,咱们继续,首先,为了内容的完整性 ...

  7. Dapper, Ef core, Freesql 插入大量数据性能比较(一)

    需求:导入9999行数据时Dapper, Ef core, Freesql 谁的性能更优,是如何执行的,级联增加谁性能更佳. 确认方法:sql server 的 sys.dm_exec_query_s ...

  8. Spring (三)SpringAoP

    1.Spring 的 AOP 简介 1.1 什么是 AOP AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程,是通过预编译方式和运行期动态代理实现程序功能 ...

  9. 数据库MySQL二

    注意拼接的时候如果为null则都为null 用if null 1.条件查询 2.按逻辑表达式筛选 3.模糊查询 还有not like 用转义字符\ #2.in 数值型的常量值都不用单引号,非数值型的都 ...

  10. Symmetry UVA - 1595

      The figure shown on the left is left-right symmetric as it is possible to fold the sheet of paper ...