栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mybatis-Plus学习笔记(狂神说版)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mybatis-Plus学习笔记(狂神说版)

Mybatis-Plus 快速开始

导入依赖


    com.baomidou
    mybatis-plus-boot-starter
    3.4.1

导入数据库

DROp TABLE IF EXISTS USER;

CREATE TABLE USER
(
	id BIGINT(20) NOT NULL COMMENT '主键ID',
	NAME VARCHAr(30) NULL DEFAULT NULL COMMENT '姓名',
	age INT(11) NULL DEFAULT NULL COMMENT '年龄',
	email VARCHAr(50) NULL DEFAULT NULL COMMENT '邮箱',
	PRIMARY KEY (id)
);

DELETE FROM USER;

INSERT INTO USER (id, NAME, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
配置数据源
spring.datasource.username=root
spring.datasource.password=123123
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncodind=utf8&useSSL=true&serverTimezone=GMT
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
创建实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
创建mapper接口,实现baseMapper接口,泛型即为实体类对象,注册为组件
//在对应的mapper上面继承基本的类 baseMapper
@Repository//代表持久层
public interface UserMapper extends baseMapper {
    //所有CRUD操作都已经编写完成了
    //你不需要向以前一样配置一大堆文件了!
}
@MapperScan在主入口类中扫描mapper所在的包
@MapperScan("com.lyk.mapper")
测试
@SpringBootTest
class MybatisPlusHelloApplicationTests {
    @Autowired
    private UserMapper userMapper;
    @Test
    void contextLoads() {
        List users = userMapper.selectList(null);
        for (User user : users) {
            System.out.println(user);
        }
    }
}

测试成功,我们发现真的不用写那些基础的CURD操作了!!!

配置日志

配置日志 (默认控制台输出)

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

这样我们就可以在控制台上看到执行细节了

Insert插入 主键生成策略

默认生成,通过雪花算法生成ID 参考博客:https://blog.csdn.net/lq18050010830/article/details/89845790

==>  Preparing: INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
==>  Parameters: 1423577873627734017(Long), 李永康(String), 19(Integer), 2238770242@qq.com(String)

可以观察到@TableId注解下有很多主键生成方案

AUTO(0),自增长ID,前提是将数据库设置为自增长
INPUT(2),自己输入ID
ASSIGN_ID(3),雪花算法,默认
ASSIGN_UUID(4),不带下划线的UUID,但是是String类型的
Update更新

通过updateById方法(参数传入一个对象,而不是一个值)

通过实践发现,Mybatis-Plus是帮我们自动拼接了动态sql

    @Test
    void updateText(){
        User user = new User();
        user.setId(8848L);
        user.setAge(15);
//      user.setName("李晶晶");
        userMapper.updateById(user);
    }

当我们为对象只注入Age属性的时候

sql是这样的:==> Preparing: UPDATE user SET age=? WHERe id=?


@Test
void updateText(){
    User user = new User();
    user.setId(8848L);
    user.setAge(15);
    user.setName("李晶晶");
    userMapper.updateById(user);
}

当我们即注入的Age,还注入了Name的时候

sql是这样的:Preparing: UPDATE user SET name=?, age=? WHERe id=?

由此可见,Mybatis-Plus帮我们封装的动态sql

自动填充

gmt_create (创建时间)gmt_modified(修改时间)这两个属性都需要操作自动化完成,我们并不能手动的去控制。

先在数据库里加上这两个字段

然后更改实体类,在要操作的字段上加@TableField注解,注意这里是时间的类型是LocalDateTime

@TableField(fill = FieldFill.INSERT)
private LocalDateTime gmtCreate;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime gmtModified;

这个注解下有一个FieldFill类下有这么几个常量

DEFAULT,
INSERT,
UPDATE,
INSERT_UPDATE;

然后写一个类实现metaObjectHandler接口

这个类必须@Component注册为组件

  • public void insertFill(metaObject metaObject)是执行插入时候执行的方法

  • public void updateFill(metaObject metaObject)是修改时执行的方法

@Component
public class MymetaObjectHandler implements metaObjectHandler {

    @Override
    public void insertFill(metaObject metaObject) {
        this.setFieldValByName("gmtCreate", LocalDateTime.now(), metaObject);
        this.setFieldValByName("gmtModified",LocalDateTime.now(),metaObject);
    }

    @Override
    public void updateFill(metaObject metaObject) {
        this.setFieldValByName("gmtModified",LocalDateTime.now(),metaObject);
    }
}

测试即可

乐观锁OptimisticLockerInnerInterceptor

当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:

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

在数据库新增一个version列,默认值为1

在实体类中同样增加version,并且加上@version注解

  • 写一个MP的配置类,再次配置乐观锁的组件
@Configuration
@MapperScan("com.lyk.mapper")
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

测试即可,在使用乐观锁更细之前,需要先查询,获取到被更新的对象。

Select查询
//测试查询
@Test
public void testSelectById(){
    User user = userMapper.selectById(1l);
    System.out.println(user);
}
//测试批量查询
@Test
public void testSelectByBatchId(){
    List users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
    users.forEach(System.out::println);
}// 按条件查询之一使用map操作
@Test
public void testSelectByBatchIds(){
    HashMap map = new HashMap<>();
    //自定义查询
    map.put("name","wanghang");
    map.put("age",18);
    List users = userMapper.selectByMap(map);
    users.forEach(System.out::println);
}
分页查询

写一个MP的配置类

@Configuration
@MapperScan("com.lyk.mapper")
public class MyBatisPlusConfig {
    //分页查询
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor2() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    }
}

然后测试

  • 先获取Page对象Page(long current, long size)
    • current是当前页数
    • size是当前页数大小
Page userPage = userMapper.selectPage(page, null);
List records = page.getRecords();

page.getRecords()获取分页数据。

@Test
void limitText(){
    Page page = new Page<>(1,5);
    Page userPage = userMapper.selectPage(page, null);
    List records = page.getRecords();
    System.out.println("是否有前一页"+page.hasPrevious());
    System.out.println("是否有后一页"+page.hasNext());
    System.out.println("一页有"+page.getSize()+"条数据");
    System.out.println("总页数: "+page.getPages());
    System.out.println("总记录数: "+page.getTotal());
    for (User record : records) {
        System.out.println(record);
    }
删除 物理删除
  • deleteById 根据ID删除
  • deleteBatchIds 批量根据ID删除
  • deleteByMap 根据条件删除
@Test
void deleteTest1(){
    userMapper.deleteById(1423928264693280769L);
}

@Test
void deleteTest2(){
    userMapper.deleteBatchIds(Arrays.asList(1423931343090188289L,1423928767514873858L,1423927306227781634L));
}

@Test
void deleteTest3(){
    Map map = new HashMap<>();
    map.put("name","李永康");
    map.put("age","19");
    userMapper.deleteByMap(map);
}
逻辑删除

给数据库新增一个del字段作为删除标记

  • 0代表未删除,是默认值
  • 1代表已删除

给实体类增加这个字段,并标注@TableLogic注解

@TableLogic
private int del;

在配置文件中配置

mybatis-plus.global-config.db-config.logic-delete-field=del
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

逻辑删除特点

  • 并不是在数据库层面删除了数据,只是修改了删除标记。
  • 在我们之后做查询操作的时候会追加一个条件del=0。
  • 也就是说逻辑删除的数据我们仍然是查询不到的,只有数据库管理员在后台可以查看。
条件构造器 alleq

判断全部相等

allEq(Map params)

allEq(Map params, boolean null2IsNull)

有两个构造器,区别就是null检查。

第一个构造器,对于空判断会用 is null

第二个构造器如果null2IsNull为true则和第一个构造器一样

如果为false,则不对空进行检查

空检查

SELECT id,name,age,email,gmt_create,gmt_modified,version,del FROM user WHERe del=0 AND (age = ? AND email IS NULL)
==> Parameters: 18(Integer)
==>      Total: 1
@Test
void allEq(){
    QueryWrapper wrapper = new QueryWrapper<>();
    Map map = new HashMap();
    map.put("age",18);
    map.put("name","Jone");
    map.put("email",null);
    wrapper.allEq(map,T);
    userMapper.selectList(wrapper);
}
eq

判断一个条件相等

eq(Children eq(R column, Object val)

构造器接收一个列名,一个参数

@Test
void Eq(){
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.eq("name","李永康");
    userMapper.selectOne(wrapper);
}
ne

不等于

ne(R column, Object val)

构造器接受一个列名,一个参数

@Test
void ne(){
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.ne("name","");
    System.out.println(userMapper.selectList(wrapper));
}
gt,ge
  • gt>
  • ge>=

ge(R column, Object val)

构造器接收一个列名,一个参数

@Test
void gt(){
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.gt("age",19);
    System.out.println(userMapper.selectList(wrapper));
}

@Test
void ge(){
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.ge("age",19);
    System.out.println(userMapper.selectList(wrapper));
}
lt,le
  • lt<
  • le<=

lt(R column, Object val)
lt(boolean condition, R column, Object val)

le同lt

@Test
void lt(){
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.lt("age",20);
    System.out.println(userMapper.selectList(wrapper));
}

@Test
void le(){
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.le("age",20);
    System.out.println(userMapper.selectList(wrapper));
}
between

查找指定范围的

between(R column, Object val1, Object val2)

构造器接收一个列名,两个极值

@Test
void between(){
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.between("age",18,20);
    System.out.println(userMapper.selectList(wrapper));
}

结果包含18和20

==>  Preparing: SELECT id,name,age,email,gmt_create,gmt_modified,version,del FROM user WHERe del=0 AND (age BETWEEN ? AND ?)
==> Parameters: 18(Integer), 20(Integer)
<==    Columns: id, name, age, email, gmt_create, gmt_modified, version, del
<==        Row: 1, Jone, 18, test1@baomidou.com, null, null, 1, 0
<==        Row: 2, Jack, 20, test2@baomidou.com, null, null, 1, 0
<==        Row: 3, Tom, 18, test3@baomidou.com, null, null, 1, 0
<==      Total: 3
notbetween

不查找指定范围内的

notBetween(R column, Object val1, Object val2)
notBetween(boolean condition, R column, Object val1, Object val2)

查找age 不包含[18,20]的

@Test
void notbetween() {
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.notBetween("age", 18, 20);
    System.out.println(userMapper.selectList(wrapper));
}
模糊查询
方法构造器对应属性
likelike(R column, Object val)like("name", "王")—>name like '%王%'
notLikenotLike(R column, Object val)notLike("name", "王")—>name not like '%王%'
likeLeftlikeLeft(R column, Object val)likeLeft("name", "王")—>name like '%王'
LikeRightlikeRight(R column, Object val)likeRight("name", "王")—>name like '王%'
isnull
isNull(R column)
isNull(boolean condition, R column)

判断是否为空

SELECT id,name,age,email,gmt_create,gmt_modified,version,del FROM user WHERe del=0 AND (name IS NULL)
isnotnull
isNotNull(R column)
isNotNull(boolean condition, R column)

判断是否不为空

SELECt id,name,age,email,gmt_create,gmt_modified,version,del FROM user WHERe del=0 AND (name IS NOT NULL)
in, notIn
in(R column, Collection value)
//in("age",{1,2,3})--->age in (1,2,3)
in(R column, Object... values)
//in("age", 1, 2, 3)--->age in (1,2,3)
notIn(boolean condition, R column, Collection value)
//notIn("age",{1,2,3})--->age not in (1,2,3)
notIn(boolean condition, R column, Object... values)
notIn("age", 1, 2, 3)--->age not in (1,2,3)
==>  Preparing: SELECt id,name,age,email,gmt_create,gmt_modified,version,del FROM user WHERe del=0 AND (age IN (?,?,?))
==> Parameters: 18(Integer), 2(Integer), 3(Integer)
==>  Preparing: SELECt id,name,age,email,gmt_create,gmt_modified,version,del FROM user WHERe del=0 AND (age NOT IN (?,?,?))
==> Parameters: 18(Integer), 2(Integer), 3(Integer)
insql
inSql(R column, String inValue)
inSql(boolean condition, R column, String inValue)
  • inSql("age", "1,2,3,4,5,6")—>age in (1,2,3,4,5,6)
  • 例: inSql("id", "select id from table where id < 3")—>id in (select id from table where id < 3)
@Test
void insql(){
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.inSql("age","SELECt age FROM USER WHERe id =3");
    List users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}
SELECT id,NAME,age,email,gmt_create,gmt_modified,VERSION,del 
FROM USER 
WHERe 
del=0 
AND 
(age IN (SELECt age FROM USER WHERe id =3))
#先找到 SELECt age FROM USER WHERe id =3 得到结果为 age=18
#然后再进行外层的查询,查询del=0 and age=18
notinsql
notInSql(R column, String inValue)
notInSql(boolean condition, R column, String inValue)
  • notInSql("age", "1,2,3,4,5,6")—>age not in (1,2,3,4,5,6)
  • 例: notInSql("id", "select id from table where id < 3")—>id not in (select id from table where id < 3)
@Test
void notinsql(){
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.notInSql("age","select age from id = 3");
    List users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}
SELECT id,NAME,age,email,gmt_create,gmt_modified,VERSION,del 
FROM
  USER 
WHERe del = 0 
  AND (
      age NOT IN 
      (SELECt 
       age 
       FROM
       USER 
       WHERe id = 3)
  )
groupby
groupBy(R... columns)
groupBy(boolean condition, R... columns)

分组函数

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/683898.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号