⭐Mybatis-Plus⭐[全面+细致]

自己学习Mybatis-plus的笔记,好记性不如烂笔头

如有问题,望指出,共进步!!!!

与君共勉~

 1.Mybatis

1.1简介

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高

1.2特点

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响。
  • 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

2.入门案例

2.1环境

jdk:1.8

maven:3.8.1

idea:2021.2

mysql:8.0.33

SpringBoot:2.7.17

 2.2引入依赖

        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            org.springframework.boot
            spring-boot-starter
        


        
        
            org.projectlombok
            lombok
            true
        


        
        
            com.baomidou
            mybatis-plus-boot-starter
            3.5.1
        

        
        
            mysql
            mysql-connector-java
            8.0.33
        

2.3配置数据源

spring:
  #配置数据源信息
  datasource:
    url: jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8&serverTimezero=GMT%2B8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456

#加入日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

 3.实体类

@TableName():与数据库中的表名映射

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@TableName("t_user")
public class User {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private String sex;
    private String email;
}

4.mapper

  • @Respsitory:解决后面注入时爆红  (也可以不用)
  • mapper必须继承BaseMapper
@Repository
public interface UserMapper extends BaseMapper  {
    

}

5.测试查询所有

   @Autowired
    private UserMapper userMapper;

    @Test
    public void test() {
        //通过条件构造器查询list的集合,没有条件可设置null为条件
        List users = userMapper.selectList(null);

        users.forEach(user -> System.out.println(user));
    }

6.结果

⭐Mybatis-Plus⭐[全面+细致]_第1张图片

3.增删改查 

3.1.添加

 @DisplayName("测试添加")
    @Test
    public void test2() {
        User user = new User(null, "张沟", "1111", 18, "男", "[email protected]");
        int row = userMapper.insert(user);
        System.out.println("成果添加" + row + "行记录");
    }

3.2.删除

 @DisplayName("根据Id删除")
    @Test
    public void test3() {
        int row = userMapper.deleteById(1);
        System.out.println("成果删除" + row + "行记录");
    }

    @DisplayName("根据map条件删除")
    @Test
    public void test4() {
        Map map = new HashMap<>();
        map.put("username", "大飞");
        map.put("age", 23);
        int row = userMapper.deleteByMap(map);
        System.out.println("成果删除" + row + "行记录");
    }


    @DisplayName("批量删除")
    @Test
    public void test5(){
        List list= Arrays.asList(18,20);
        int row = userMapper.deleteBatchIds(list);
        System.out.println("成果删除" + row + "行记录");
    }

3.3.修改

    @DisplayName("修改")
    @Test
    public void test6(){
        User user=new User(2,"小张","666888",18,"男","[email protected]");
        int row = userMapper.updateById(user);
        System.out.println("成果修改" + row + "行记录");

    }

3.4.查找

   @DisplayName("根据id查询")
    @Test
    public void test7() {
        User user = userMapper.selectById(2);
        System.out.println(user);
    }

    @DisplayName("多个id查询")
    @Test
    public void test8() {
        List list = Arrays.asList(2, 3, 4, 5);
        List users = userMapper.selectBatchIds(list);
        users.forEach(user -> System.out.println(user));
    }

    @DisplayName("根据map条件查询")
    @Test
    public void test9() {
        Map map = new HashMap<>();
        map.put("sex", "男");
        map.put("age", 18);
        List users = userMapper.selectByMap(map);
        users.forEach(user -> System.out.println(user));
    }

    @DisplayName("根据条件查询")
    @Test
    public void test10() {
        List users = userMapper.selectList(null);
        users.forEach(user -> System.out.println(user));
    }

 4.自定义sql

mybatis-plus默认的mapper映射文件路径:/mapper/**/*.xml

⭐Mybatis-Plus⭐[全面+细致]_第2张图片

4.1创建mapper的映射文件



    
    
    

4.2创建manpper接口


@Repository
public interface UserMapper extends BaseMapper  {

    /**
     * 根据id查询用户信息为map集合
     * @param id
     * @return
     */
    Map selectMapById(@Param("id") Integer id);

}

4.3测试


    @DisplayName("自定义查询")
    @Test
    public void test11(){
        Map map = userMapper.selectMapById(2);
        System.out.println(map);
    }

⭐Mybatis-Plus⭐[全面+细致]_第3张图片

5.通用service

5.1service接口

接口继承Mybatis-plus的通用IService<实体类型>

public interface UserService extends IService {
}

5.2service实现类

  • service实现自己的接口
  • 继承mybatis-plus的实现类ServiceImpl<自己的mapper,要操作的实体类>
@Service
public class UserServiceImpl extends ServiceImpl implements UserService {


}

5.3测试

@SpringBootTest
public class TestService {

    @Autowired
    protected UserService userService;

    @DisplayName("查询总记录数")
    @Test
    public void test1(){
        long count = userService.count();
        System.out.println("总记录数:"+count);

    }
}

⭐Mybatis-Plus⭐[全面+细致]_第4张图片

5.4批量添加

  • 说明:在UserMapper里面没有批量添加的功能。
 @DisplayName("批量添加")
    @Test
    public void test2() {
        List list = new ArrayList<>();
        for (int i = 7; i <= 12; i++) {
            User user = new User(i, "小张" + i, "666" + i, 11 + i, "男", "666" + i + "@qq.com");
            list.add(user);
        }

        boolean b = userService.saveBatch(list);
        System.out.println("是否添加成功:"+b);
    }
}

⭐Mybatis-Plus⭐[全面+细致]_第5张图片

6.Mybatis-PLUS的注解

6.1@TableName

  •  @TableName:将指定的数据库表和实体类名相映射
@TableName("t_user")
public class User {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private String sex;
    private String email;
}

注意:如果数据库表名的前缀是一致的,则可以使用全局配置

mybatis-plus:
  #设置表名前缀
  global-config:
    db-config:
      table-prefix: t_

6.2@TableId

  • @TableId:将属性所对应的字段标识为主键(默认把id标识为主键,当不为 id 时,用此注解)
属性 类型 默认值 描述
value String "" 主键字段名
type Enum

IdType.NONE(雪花算法),与数据库是否设置自增无关

IdType.AUTO   (自动递增),数据库必须设置id自增,否则无效

指定主键类型
@TableName("t_user")
public class User {

    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;

    private String username;
    private String password;
    private Integer age;
    private String sex;
    private String email;
}

注意:也可以在全局配置里统一 主键生成策略

mybatis-plus:
  configuration:
    id-type: auto

6.3@TableField

  • @TableFild:指定属性对应的字段名
@TableName("t_user")
public class User {

    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    @TableField("username")
    private String name;
    private String password;
    private Integer age;
    private String sex;
    private String email;
}

6.4@TableLogic

  • @TableLogic:逻辑删除(自动转化为修改)
属性 类型 描述
value String 逻辑未删除值
delval String 逻辑删除值
@TableName("t_user")
public class User {

    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    @TableField("username")
    private String name;
    private String password;
    private Integer age;
    private String sex;
    private String email;
    @TableLogic
    private Integer isDelete;

⭐Mybatis-Plus⭐[全面+细致]_第6张图片

7.条件构造器

7.1Wapper

⭐Mybatis-Plus⭐[全面+细致]_第7张图片

  •  Wrapper: 条件构造抽象类,最顶端父类
  •  AbstractWrapper:用于查询条件封装,生成 sql 的 where 条件
  • QueryWrapper:查询条件封装
  • UpdateWrapper : Update条件封装
  • AbstractLambdaWrapper: 使用Lambda 语法
  1. LambdaQueryWrapper:用于Lambda语法使用的查询Wrapper
  2. LambdaUpdateWrapper: Lambda 更新封装Wrapper

7.2QueryWarpper

7.2.1组装查询条件

注意:查询的不是实体类的属性,而是数据空表中的字段

    @DisplayName("条件查询")
    @Test
    public void test1() {
        QueryWrapper queryWrapper = new QueryWrapper();
        //查询包含 张 ,age在19和22之间,email不为空
        queryWrapper.like("username", "张").between("age", 19, 22).isNotNull("email");
        List list = userMapper.selectList(queryWrapper);
        list.forEach(user -> System.out.println(user));
    }

查询结果:

因为之前添加了@TableLogic,所以查询的都是未删除的:WHERE is_delete=0 

==>  Preparing: SELECT id,username AS name,password,age,sex,email,is_delete FROM t_user WHERE is_delete=0 AND (username LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)
==> Parameters: %张%(String), 19(Integer), 22(Integer)
<==    Columns: id, name, password, age, sex, email, is_delete
<==        Row: 10, 小张10, 66610, 21, 男, [email protected], 0
<==        Row: 11, 小张11, 66611, 22, 男, [email protected], 0
<==      Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@76889e60]
User(id=10, name=小张10, password=66610, age=21, sex=男, [email protected], isDelete=0)
User(id=11, name=小张11, password=66611, age=22, sex=男, [email protected], isDelete=0)

7.2.2组装排序条件

  • orderByDesc:按照降序排
  • orderByAsc:按照升序排
 @DisplayName("排序条件")
    @Test
    public void test2(){
        QueryWrapper queryWrapper=new QueryWrapper<>();
        //先按照年龄降序排,若年龄相等,按照id升序排,年龄在19-22
        queryWrapper.orderByDesc("age").orderByAsc("id").between("age",19,22);
        List list = userMapper.selectList(queryWrapper);
        list.forEach(user -> System.out.println(user));
    }

结果: 

==>  Preparing: SELECT id,username AS name,password,age,sex,email,is_delete FROM t_user WHERE is_delete=0 AND (age BETWEEN ? AND ?) ORDER BY age DESC,id ASC
==> Parameters: 19(Integer), 22(Integer)
<==    Columns: id, name, password, age, sex, email, is_delete
<==        Row: 11, 小张11, 66611, 22, 男, [email protected], 0
<==        Row: 10, 小张10, 66610, 21, 男, [email protected], 0
<==      Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@55e2fe3c]
User(id=11, name=小张11, password=66611, age=22, sex=男, [email protected], isDelete=0)
User(id=10, name=小张10, password=66610, age=21, sex=男, [email protected], isDelete=0)

7.2.3组装删除条件

  @DisplayName("删除条件")
    @Test
    public void test3(){
        QueryWrapper queryWrapper=new QueryWrapper<>();
        queryWrapper.isNull("email");
        int row = userMapper.delete(queryWrapper);
        System.out.println("成功删除"+row+"条");
    }

因为前面添加了@TableLogic逻辑删除,所以应当是修改语句!!!!! 

==>  Preparing: UPDATE t_user SET is_delete=1 WHERE is_delete=0 AND (email IS NULL)
==> Parameters: 
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6f139fc9]
成功删除1条

⭐Mybatis-Plus⭐[全面+细致]_第8张图片

7.2.4组装修改条件

AND连接是默认的,但是OR需要 添加.or()

   @DisplayName("修改条件")
    @Test
    public void test4() {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        //将(年龄大于20并且用户名中包含张)或(邮箱为null的用户信息修改)
        queryWrapper.gt("age", 20).like("username", "张").or().isNull("email");
        User user = new User();
        user.setName("小小张");
        user.setEmail("[email protected]");
        //第一个参数是修改的内容,第二个参数是查询条件
        int row = userMapper.update(user, queryWrapper);
        System.out.println("成功修改" + row + "行");
    }

结果:

JDBC Connection [HikariProxyConnection@976042249 wrapping com.mysql.cj.jdbc.ConnectionImpl@4fb392c4] will not be managed by Spring
==>  Preparing: UPDATE t_user SET username=?, email=? WHERE is_delete=0 AND (age > ? AND username LIKE ? OR email IS NULL)
==> Parameters: 小小张(String), [email protected](String), 20(Integer), %张%(String)
<==    Updates: 5
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@64f1fd08]
成功修改5行

因为email为空的,之前被逻辑删除了,所以没有修改 

⭐Mybatis-Plus⭐[全面+细致]_第9张图片

7.2.5条件优先级

lambda中的条件优先执行

  @DisplayName("优先级")
    @Test
    public void test5() {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        //将用户名中包含 9 并且(年龄大于18或邮箱为null)的用户修改
        queryWrapper.like("username", "9")
                    .and(i -> i.gt("age", 18).or().isNull("email"));
        User user=new User();
        user.setName("小小陈");
        int row = userMapper.update(user, queryWrapper);
        System.out.println("成功修改"+row+"行");
    }

结果:

注意看下面的修改语句!!!,你品,你细细品~

==>  Preparing: UPDATE t_user SET username=? WHERE is_delete=0 AND (username LIKE ? AND (age > ? OR email IS NULL))
==> Parameters: 小小陈(String), %9%(String), 18(Integer)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@64469d8]
成功修改1行

  7.2.6查指定字段

  @DisplayName("指定字段")
    @Test
    public void test6(){
        QueryWrapper queryWrapper=new QueryWrapper<>();
        //查用户名,密码
        queryWrapper.select("username","password");
        List> maps = userMapper.selectMaps(queryWrapper);
        maps.forEach(stringObjectMap -> System.out.println(stringObjectMap));
    }

结果:

注意看下面的查询语句!!!,你品,你细细品~

==>  Preparing: SELECT username,password FROM t_user WHERE is_delete=0
==> Parameters: 
<==    Columns: username, password
<==        Row: 小张, 666888
<==        Row: 张沟, 1111
<==        Row: 张大沟, 2222
<==        Row: jack, 888
<==      Total: 4
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3dd818e8]
{password=666888, username=小张}
{password=1111, username=张沟}
{password=2222, username=张大沟}
{password=888, username=jack}

7.2.7组装子查询

  @DisplayName("子查询")
    @Test
    public void test7(){
        QueryWrapper queryWrapper=new QueryWrapper<>();
        //年龄小于20的
        queryWrapper.inSql("age","select age from t_user where age<20");
        List list = userMapper.selectList(queryWrapper);
        list.forEach(user -> System.out.println(user));
    }

结果:

==>  Preparing: SELECT id,username AS name,password,age,sex,email,is_delete FROM t_user WHERE is_delete=0 AND (age IN (select age from t_user where age<20))
==> Parameters: 
<==    Columns: id, name, password, age, sex, email, is_delete
<==        Row: 2, 小张, 666888, 18, 男, [email protected], 0
<==        Row: 3, 张沟, 1111, 18, 女, [email protected], 0
<==        Row: 4, 张大沟, 2222, 8, 男, [email protected], 0
<==        Row: 5, jack, 888, 18, 女, [email protected], 0
<==      Total: 4
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@64f1fd08]
User(id=2, name=小张, password=666888, age=18, sex=男, [email protected], isDelete=0)
User(id=3, name=张沟, password=1111, age=18, sex=女, [email protected], isDelete=0)
User(id=4, name=张大沟, password=2222, age=8, sex=男, [email protected], isDelete=0)
User(id=5, name=jack, password=888, age=18, sex=女, [email protected], isDelete=0)

7.2.8组装条件查询 

根据用户选择,进行加入查询条件

    @Test
    public void test9(){
        String username="";
        Integer ageBegin=20;
        Integer ageEnd=30;
        QueryWrapper queryWrapper=new QueryWrapper<>();
        if (StringUtils.isNotBlank(username)){//isNotBlank判断某个字符串是否不为空字符串,不为null,不为空白符
           queryWrapper.like("username",username);
        }
        if (ageBegin!=null){
            queryWrapper.gt("age",ageBegin);
        }
        if (ageEnd!=null){
            queryWrapper.lt("age",ageEnd);
        }
        List list = userMapper.selectList(queryWrapper);
        list.forEach(user -> System.out.println(user));
    }

 结果:

发现结果是根据age进行查询的,因为username=" ",所以不进行拼接

==>  Preparing: SELECT id,username AS name,password,age,sex,email,is_delete FROM t_user WHERE is_delete=0 AND (age > ? AND age < ?)
==> Parameters: 20(Integer), 30(Integer)
<==    Columns: id, name, password, age, sex, email, is_delete
<==        Row: 6, 小王, 123456, 23, 男, [email protected], 0
<==        Row: 10, 小小张, 66610, 21, 男, [email protected], 0
<==        Row: 11, 小小张, 66611, 22, 男, [email protected], 0
<==        Row: 12, 小小张, 66612, 23, 男, [email protected], 0
<==        Row: 22, 小小张, 66612, 23, 男, [email protected], 0
<==        Row: 23, 小小张, 66613, 24, 男, [email protected], 0
<==      Total: 6
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c15e8c7]
User(id=6, name=小王, password=123456, age=23, sex=男, [email protected], isDelete=0)
User(id=10, name=小小张, password=66610, age=21, sex=男, [email protected], isDelete=0)
User(id=11, name=小小张, password=66611, age=22, sex=男, [email protected], isDelete=0)
User(id=12, name=小小张, password=66612, age=23, sex=男, [email protected], isDelete=0)
User(id=22, name=小小张, password=66612, age=23, sex=男, [email protected], isDelete=0)
User(id=23, name=小小张, password=66613, age=24, sex=男, [email protected], isDelete=0)

7.2.9condition组装条件查询

condition:就是里面的条件---》like(条件,字段,字段值)

 @DisplayName("condition查询")
    @Test
    public void test10() {
        String username = "";
        Integer ageBegin = 20;
        Integer ageEnd = 30;
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(username), "username", username)
                .gt(ageBegin != null, "age", 20)
                .lt(ageEnd != null, "age", 30);
        List list = userMapper.selectList(queryWrapper);
        list.forEach(user -> System.out.println(user));

结果:

==>  Preparing: SELECT id,username AS name,password,age,sex,email,is_delete FROM t_user WHERE is_delete=0 AND (age > ? AND age < ?)
==> Parameters: 20(Integer), 30(Integer)
<==    Columns: id, name, password, age, sex, email, is_delete
<==        Row: 6, 小王, 123456, 23, 男, [email protected], 0
<==        Row: 10, 小小张, 66610, 21, 男, [email protected], 0
<==        Row: 11, 小小张, 66611, 22, 男, [email protected], 0
<==        Row: 12, 小小张, 66612, 23, 男, [email protected], 0
<==        Row: 22, 小小张, 66612, 23, 男, [email protected], 0
<==        Row: 23, 小小张, 66613, 24, 男, [email protected], 0
<==      Total: 6
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6b3f6585]
User(id=6, name=小王, password=123456, age=23, sex=男, [email protected], isDelete=0)
User(id=10, name=小小张, password=66610, age=21, sex=男, [email protected], isDelete=0)
User(id=11, name=小小张, password=66611, age=22, sex=男, [email protected], isDelete=0)
User(id=12, name=小小张, password=66612, age=23, sex=男, [email protected], isDelete=0)
User(id=22, name=小小张, password=66612, age=23, sex=男, [email protected], isDelete=0)
User(id=23, name=小小张, password=66613, age=24, sex=男, [email protected], isDelete=0)

7.3UpdateWarpper

 注意:条件中的字段,不是实体类型的属性,而是数据库表中的字段!!!!!

7.3.1组装修改条件 

不用在创建修改的对象,直接通过.set()进行设置即可


    @DisplayName("UpdateWrapper修改")
    @Test
    public void test8(){
        UpdateWrapper updateWrapper=new UpdateWrapper<>();
        //将用户名中包含 陈 并且(年龄大于18或邮箱为null)的用户修改
        updateWrapper.like("username","陈").and(i->i.gt("age",18).or().isNull("email"));
        //修改的字段
        updateWrapper.set("username","大大张").set("age",20);
        int row = userMapper.update(null, updateWrapper);
        System.out.println("成功修改"+row+"行");

    }

结果:

==>  Preparing: UPDATE t_user SET username=?,age=? WHERE is_delete=0 AND (username LIKE ? AND (age > ? OR email IS NULL))
==> Parameters: 大大张(String), 20(Integer), %陈%(String), 18(Integer)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e807c54]
成功修改1行

7.4.LambdaQueryWarpper

为了避免字段名写错,可以使用lambda表达式: User::getName

  @Test
    public void test11(){
        LambdaQueryWrapper lambdaQueryWrapper=new LambdaQueryWrapper();
        String username = "张";
        Integer ageBegin = 20;
        Integer ageEnd = 30;
        lambdaQueryWrapper.like(StringUtils.isNotBlank(username),User::getName,username)
                .ge(ageBegin!=null,User::getAge,ageBegin)
                .le(ageEnd!=null,User::getAge,ageEnd);
        List list = userMapper.selectList(lambdaQueryWrapper);
        list.forEach(user -> System.out.println(user));

    }

结果:

==>  Preparing: SELECT id,username AS name,password,age,sex,email,is_delete FROM t_user WHERE is_delete=0 AND (username LIKE ? AND age >= ? AND age <= ?)
==> Parameters: %张%(String), 20(Integer), 30(Integer)
<==    Columns: id, name, password, age, sex, email, is_delete
<==        Row: 9, 大大张, 6669, 20, 男, [email protected], 0
<==        Row: 10, 小小张, 66610, 21, 男, [email protected], 0
<==      Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@39c385d6]
User(id=9, name=大大张, password=6669, age=20, sex=男, [email protected], isDelete=0)
User(id=10, name=小小张, password=66610, age=21, sex=男, [email protected], isDelete=0)

7.5LambdaUpdateWarpper

同样使用lambda表达式,防止字段名写错;User.getName

 @Test
    public void test12() {
        LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
        //将用户名中包含 陈 并且(年龄大于18或邮箱为null)的用户修改
        updateWrapper.like(User::getName, "张").and(i -> i.gt(User::getAge, 23).or().isNull(User::getEmail));
        updateWrapper.set(User::getName,"大大大张").set(User::getAge,88);
        int row = userMapper.update(null, updateWrapper);
        System.out.println("成功修改" + row + "行");
    }

结果:

==>  Preparing: UPDATE t_user SET username=?,age=? WHERE is_delete=0 AND (username LIKE ? AND (age > ? OR email IS NULL))
==> Parameters: 大大大张(String), 88(Integer), %张%(String), 23(Integer)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6438a7fe]
成功修改1行

8.插件

8.1分页插件

Mybatis-plus自带分页插件,但需要配置

8.1.1添加配置类

@Configuration
public class MyConfig {

    /**
     * 分页插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

8.2.2测试分页插件

  @Test
    public void test1() {
        Page page = new Page<>(1,3);
        userMapper.selectPage(page,null);
        System.out.println(page.getCurrent());
    }

8.2乐观锁插件

8.2.1背景描述

描述:当小李和小王同时修改商品时,他俩都是对原商品操作,在没有锁的情况下,后来的会覆盖之前的,这是老板再来查询,就是小王在原商品上的修改,而并非在小李修改后,对小李的结果进行修改。

   @Autowired
    private ProductMapper productMapper;

    @DisplayName("商品操作")
    @Test
    public void test(){
        //小李查询商品
        Product product1 = productMapper.selectById(1);
        System.out.println("小李查询的价格"+product1.getPrice());
        //小王查询商品
        Product product2 = productMapper.selectById(1);
        System.out.println("小王查询的价格"+product2.getPrice());

        //小李+50
        product1.setPrice(product1.getPrice()+50);
        productMapper.updateById(product1);

        //小王-30
        product2.setPrice(product2.getPrice()-30);
        productMapper.updateById(product2);

        //老板
        Product product3 = productMapper.selectById(1);
        System.out.println("老板查询的价格:"+product3.getPrice());
    }

运行结果可知:

  • 小李查询的价格100
  • 小王查询的价格100
  • 老板查询的价格70

老板说:求求大哥,给孩子加个锁吧!!!

 8.2.1添加乐观锁

1.添加插件
@Configuration
public class MyConfig {


    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();
         //分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        //乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}
2.@Version
  • @Version:标识乐观锁版本号字段
@TableName("t_product")
public class Product {

    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    @TableField("t_name")
    private String name;
    private Integer price;
    @Version
    private Integer version;
}
3.再次查询

若小王查询后返回0,继续让他重新查询;这是他查询的就是小李更改后的

    @Autowired
    private ProductMapper productMapper;

    @DisplayName("商品操作")
    @Test
    public void test(){
        //小李查询商品
        Product product1 = productMapper.selectById(1);
        System.out.println("小李查询的价格"+product1.getPrice());
        //小王查询商品
        Product product2 = productMapper.selectById(1);
        System.out.println("小王查询的价格"+product2.getPrice());

        //小李+50
        product1.setPrice(product1.getPrice()+50);
        productMapper.updateById(product1);

        //小王-30
        product2.setPrice(product2.getPrice()-30);
        int row = productMapper.updateById(product2);
        if (row==0){//操作失败
            Product productNew = productMapper.selectById(1);
            productNew.setPrice(product2.getPrice()-30);
            productMapper.updateById(productNew);
        }

        //老板
        Product product3 = productMapper.selectById(1);
        System.out.println("老板查询的价格:"+product3.getPrice());
    }

这是查询结果:

  • 小李查询的价格100
  • 小王查询的价格100
  • 小王再次查询的价格150
  • 老板查询的价格:120

这时,老板露出了久违的笑容~

9.通用枚举

如果数据库中的字段值是固定的,如性别,就可以使用枚举喽~

9.1创建枚举

  • @EnumValue:将注解所标识的属性值存储到数据库中
@AllArgsConstructor
@Getter
public enum SexEnums {
    MALE(1,"男"),
    FEMALE(2,"女");

    @EnumValue//将注解所标识的属性值存储到数据库中
    private Integer sex;
    private String sexName;


}

当然实体类时,sex的类型就是SexEnums

 private SexEnums sex;

9.2设置全局配置

mybatis-plus:
  #通用枚举
  type-enums-package: com.xz.enums

9.3小测一把

这时的性别,就可以使用SexEnums.MALE/FMALE,枚举类型了

 @DisplayName("测试枚举")
    @Test
    public void test(){
        User user=new User(null,"荒天帝","888",18, SexEnums.MALE,"[email protected]");
        int row = userMapper.insert(user);
        System.out.println("成功添加:"+row+"行记录");
    }

一不小心成功了!!! 

==>  Preparing: INSERT INTO t_user ( username, password, age, sex, email ) VALUES ( ?, ?, ?, ?, ? )
==> Parameters: 荒天帝(String), 888(String), 18(Integer), 1(Integer), [email protected](String)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1866da85]
成功添加:1行记录

10.代码生成器

10.1添加依赖

        
        
            com.baomidou
            mybatis-plus-generator
            3.5.1
        

        
            org.freemarker
            freemarker
            2.3.32
        

10.2添加模板

官方的更权威

   FastAutoGenerator.create("jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8&serverTimezero=GMT%2B8", "root", "123456")
                //全局配置
                .globalConfig(builder -> {
                    builder.author("小张") // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .outputDir("F://Mybatis-PLUS"); // 指定输出目录
                })
                //设置包
                .packageConfig(builder -> {
                    builder.parent("com.xz") // 设置父包名
                            .moduleName("mybatis-plus") // 设置父包模块名
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "F://Mybatis-PLUS")); // 设置mapperXml生成路径
                })
                //设置策略
                .strategyConfig(builder -> {
                    builder.addInclude("t_user") // 设置需要生成的表名
                            .addTablePrefix("t_", "c_"); // 设置过滤表前缀
                })
                //生成的模板
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                //执行
                .execute();

    }
  • 若下面报错 :说明url配置有问题,查看你的url中是否存在空格!!!
Exception in thread "main" java.lang.RuntimeException: 无法创建文件,请检查配置信息!
	at com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine.batchOutput(AbstractTemplateEngine.java:244)
	at com.baomidou.mybatisplus.generator.AutoGenerator.execute(AutoGenerator.java:179)
	at com.baomidou.mybatisplus.generator.FastAutoGenerator.execute(FastAutoGenerator.java:213)
	at com.xz.TestAuto.main(TestAuto.java:35)
Caused by: java.lang.RuntimeException: java.sql.SQLException: No suitable driver found for  jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8&serverTimezero=GMT%2B8
	at com.baomidou.mybatisplus.generator.config.DataSourceConfig.getConn(DataSourceConfig.java:206)
	at com.baomidou.mybatisplus.generator.config.querys.DecoratorDbQuery.(DecoratorDbQuery.java:58)
	at com.baomidou.mybatisplus.generator.IDatabaseQuery$DefaultDatabaseQuery.(IDatabaseQuery.java:97)
	at com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder.getTableInfoList(ConfigBuilder.java:139)
	at com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine.batchOutput(AbstractTemplateEngine.java:226)
	... 3 more
Caused by: java.sql.SQLException: No suitable driver found for  jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8&serverTimezero=GMT%2B8
	at java.sql.DriverManager.getConnection(DriverManager.java:689)
	at java.sql.DriverManager.getConnection(DriverManager.java:247)
	at com.baomidou.mybatisplus.generator.config.DataSourceConfig.getConn(DataSourceConfig.java:196)
	... 7 more

10.3执行方法

⭐Mybatis-Plus⭐[全面+细致]_第10张图片

11.MybatisX插件

MyBatis-Plus为我们提供了强大的mapper和service模板,能够大大的提高开发效率但是在真正开发过程中, MyBatis-Plus并不能为我们解决所有问题,例如一些复杂的SQL,多表联查,我们就需要自己去编写代码和SQL语句,我们该如何快速的解决这个问题呢,这个时候可以使用MyBatisX插件MyBatisX—款基于 IDEA的快速开发插件,为效率而生。

11.1安装插件

重启生效!!!

⭐Mybatis-Plus⭐[全面+细致]_第11张图片

11.2创建mapper接口和映射文件

你就会惊奇的发现:

  • mapper接口前有个蓝鸟
  • mapper接口映射文件有个红鸟

点击红鸟,会定位到所对应的蓝鸟,反之亦然!!!!

⭐Mybatis-Plus⭐[全面+细致]_第12张图片

11.3代码快速生成

11.3.1选择数据源

⭐Mybatis-Plus⭐[全面+细致]_第13张图片

11.3.2测试链接 

⭐Mybatis-Plus⭐[全面+细致]_第14张图片

11.3.3选择要操作的表

⭐Mybatis-Plus⭐[全面+细致]_第15张图片

11.3.4设置生成规则

⭐Mybatis-Plus⭐[全面+细致]_第16张图片

⭐Mybatis-Plus⭐[全面+细致]_第17张图片

11.3.5模块架构

⭐Mybatis-Plus⭐[全面+细致]_第18张图片

你可能感兴趣的:(mybatis,java,开发语言,后端,idea,mysql,tomcat)