【web项目 MybatisPlus 01】

为了更加容易掌握MybatisPlus的内容,需要先创建数据库,然后进行实际操作掌握

一、MybatisPlus  demo

1、创建数据库

mybatis_plus

2、创建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)
);

3、User表insert数据

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');

4、在idea上创建一个springboot项目,需要引入下面的包

<!--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用来简化实体类-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

5、在idea的application.properties中配置数据库信息

#mysql数据库连接
spring boot 2.0(内置jdbc5驱动)
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://172.16.137.131:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456

spring boot 2.1及以上(内置jdbc8驱动)
注意:driver和url的变化
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://172.16.137.131:3306/mybatis_plus?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456

6、编写代码测试mybatisPlus对数据库的操作

//1、springboot启动类 - 在SpringBoot启动类中添加@MapperScan注解,扫描Mapper文件夹
@SpringBootApplication
@MapperScan("com.mobvista.demomp.mapper")
public class DemompApplication {

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

备注:@MapperScan("com.mobvista.demomp.mapper")  括号内添加mapper文件包地址
//2、创建entity包,User类
@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
备注;@Data相当于@Setter和@Getter -->作用是对私有化属性进行get和set方法

//3、创建mapper包,UserMapper接口
@Repository
public interface UserMapper extends BaseMapper<User>{
}
备注:UserMapper继承了BaseMapper,<User>泛型指定是User的引用类型,BaseMapper是已经封装好的接口,内部是一些对数据库的增删改查操作

//4、测试UserMapper对数据库的操作
@SpringBootTest
class DemompApplicationTests {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void findAll(){
        List<User> users = userMapper.selectList(null);
        System.out.println(users);
    }
}
备注:@Autowired自动加载创建对象
注意:IDEA在 userMapper 处报错,因为找不到注入的对象,因为类是动态创建的,但是程序可以正确的执行。
为了避免报错,可以在 dao 层 的接口上添加 @Repository 注
通过以上几个简单的步骤,我们就实现了 User 表的 CRUD 功能,甚至连 XML 文件都不用编写!

7、查看sql输出日志

在application.properties中添加

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

二、MybatisPlus-添加和主键策略

1、添加

数据库验证添加的数据

从数据库中可以看到生成的id是一个长的值,这个值是mp(MybatisPlus简称)生成的,叫做主键策略

2、主键策略

2.1、MP默认的主键策略是:ASSIGN_ID(使用了雪花算法) -->常用在bean中

常用的主键策略值

2.2、AUTO自增策略

需要再创建数据表的时候设置主键自增

实体字段中配置

 @TableId(type = IdType.AUTO)
    private Long id;

要想影响所有实体的配置,可以设置全局主键配置

#全局设置主键生成策略
mybatis-plus.global-config.db-config.id-type=auto

三、MybatisPlus-修改和自动填充

1、修改

 2、自动填充

背景:在项目中经常会遇到一些数据,例如创建时间和更新时间,在插入的时候是需要取当前时间的,为了方便MP可以自动填充完成这些字段的赋值操作。

# 案例演示

2.1、准备工作:

1)数据库修改:在user表中增加两个字段:create_time、update_time  (都是datetime类型)

2)实体类修改:User类中增加createTime、updateTime字段

2.2、在实体类要进行自动填充属性添加注解

2.3、实现元对象处理器接口:创建类实现接口,实现接口两个方法,一个方法添加执行,一个方法修饰执行,设置添加什么值

注意:不要忘记添加 @Component 注解

2.4、测试

1)先做添加操作,库内查看createTime和updateTime是否有值

2)在做更新操作,库内查看createTime和updateTime是否有值

四、mybatisPlus乐观锁

为什么要用乐观锁:适用场景: 当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新

乐观锁的实现方式:

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

# mp实现乐观锁步骤:

1、在表添加字段作为版本号,在表对应实体类添加版本号属性

 

2、修改user实体类 -->增加version属性并添加@Version注解

3、配置乐观锁插件 -创建配置文件

创建包config,创建MpConfig.java配置类

@Configuration //此注解代表是一个配置类
@MapperScan("com.mobvista.demomp.mapper")
public class MpConfig {

    /**
     * 乐观锁插件
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}

备注:此时可以删除主类中的@MapperScan扫描注解

前三步已经就实现了乐观锁的功能,为了更加明显,需要做以下的调整

改进1:在实体类user中version属性前加@TableField(fill = FieldFill.INSERT)注解

改进2:在实现类MyMateObjectHandler中增加this.setFieldValByName("version",1,metaObject); 让默认值为1自动添加

4、测试乐观锁

//测试乐观锁
    @Test
    public void testOptimisticLocker(){
        //1.先根据id查询
        User user = userMapper.selectById(6);
        //2. 修改ID=6的数据
        user.setName("大大");
        userMapper.updateById(user);
    }

    //乐观锁的问题经常出现在并发情况下,但是本次没办法演示,所以可以用更新操作来验证,如果每次version都增1,就说明乐观锁已经实现了

此数据已经被修改

五、MybatisPlus的查询操作

1、多个ID的批量查询

//多个ID的批量查询
   @Test
    public void testSelect1(){

        //selectBatchIds方法的参数是一个Collection集合,既可以传一个list对象也可以用Arrays工具类传多个ID
       ArrayList<Integer> list = new ArrayList<>();
       list.add(1);
       list.add(2);
       list.add(3);
       List<User> users = userMapper.selectBatchIds(list);
       System.out.println(users);

       List<User> users1 = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
       System.out.println(users1);
   }

2、简单的条件查询

 //简单条件查询
    //此中查询用到的语句是:SELECT id,name,age,email,create_time,update_time,version FROM user WHERE name = ? AND age = ? AND email = ?
    @Test
   public void testSelect2(){
        HashMap<String, Object> hm = new HashMap<>();
        hm.put("name","赵丽颖");
        hm.put("age",25);
        hm.put("email","123@qq.com");
        List<User> users = userMapper.selectByMap(hm);
        System.out.println("========"+users);
    }

3、分页查询

mp自带分页插件,只要简单的配置即可实现分页功能

实现步骤:

1)配置分页插件:在配置类(MpConfig类)中添加@Bean配置

/**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

2)编写分页代码

2.1)插入Page对象,传入两个参数

* 当前页

* 每页记录数

2.2)调用mp的方法实现分页

# 测试selectPage分页  -->最终通过page对象获取相关数据

//分页查询
    @Test
    public void testSelectPage(){
        //实体类和分页关联
        Page<User> page = new Page(1,3);
        // 调用selectPage方法返回分页对象
        Page<User> userPage = userMapper.selectPage(page, null);

        //返回对象得到分页所有数据
        long pages = userPage.getPages();
        long current = userPage.getCurrent();//获取当前页
        List<User> records = userPage.getRecords();//查询数据集合
        long total = userPage.getTotal();//总记录数
        boolean hasNext = userPage.hasNext();//下一页
        boolean hasPrevious = userPage.hasPrevious();//上一页

        System.out.println(pages);
        System.out.println(current);
        System.out.println(records);
        System.out.println(total);
        System.out.println(hasNext);
        System.out.println(hasPrevious);

    }

# 测试selectMapsPage分页 -->当指定了特定查询列时,希望分页结果列表只返回被查询的列,而不是很多null值。测试selectMapPage分页:结果集是Map

//分页查询 --selectMapsPage分页
    @Test
    public void testselectMapsPage(){
        Page<Map<String,Object>> page = new Page<>(1,5);
        Page<Map<String, Object>> mapPage = userMapper.selectMapsPage(page, null);
        System.out.println("查询数据集合:"+mapPage.getRecords());
        System.out.println("查询当前分页的所有数据:"+mapPage.getPages());
        System.out.println("获取当前页:"+mapPage.getCurrent());
        System.out.println("获取总数:"+mapPage.getTotal());
        System.out.println("上一页:"+mapPage.hasPrevious());
        System.out.println("下一页:"+mapPage.hasNext());
    }

六、mp实现删除和逻辑删除

1、删除

1.1、根据ID删除

1.2、批量删除

1.3、简单条件删除

//删除
    @Test
    public void testDelete(){
        int num = userMapper.deleteById(6);
        System.out.println(num);
    }
    //批量删除
    @Test
    public void testDelete2(){
        int ids = userMapper.deleteBatchIds(Arrays.asList(4, 3));
        System.out.println(ids);
    }

    //简单删除
    @Test
    public void testDelete3(){
        Map<String,Object> mp = new HashMap<>();

        mp.put("name","高圆圆");
        mp.put("age",19);

        int i = userMapper.deleteByMap(mp);
        System.out.println(i);
    }

2、逻辑删除

2.1、物理删除和逻辑删除

物理删除真是删除,将对应数据从数据库中删除,之后查询不到此条被删除数据

逻辑删除假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后再数据库中仍旧能看到此条数据记录

逻辑删除使用场景:可以进行数据恢复,有关联数据,不变删除

2.2、逻辑删除实现流程

2.2.1、数据库修改

添加delete_status字段

ALTER TABLE `user` ADD COLUMN delete_status boolean DEFAULT( FALSE);

2.2.2、实体类user修改

@TableLogic(value = "0",delval = "1")
private Integer deleteStatus;

2.2.3、配置(可选)-->如果在实体类中@TableLogic注解后面没有跟值,可配置,有值就可以不配置

application.properties加入以下配置,此为默认值,如果你的默认值和mp默认的一样,该配置可无

#设置逻辑删除--被删除和无删除的值
mybatis-plus.global-config.db-config.logic-delete-value = 2
mybatis-plus.global-config.db-config.logic-not-delete-value = 1

2.2.4、测试

@Test
    public void testDelete(){
        int num = userMapper.deleteById(21);
        System.out.println(num);
    }

删除执行的语句:

发现删除时,并不是执行的delete语句,而是update语句,并且查看数据库发现数据并没有被删除,而是delete_status字段的值从0变成了1

注意:被删除前,数据的delete_status字段的值必须是0,才能被选取出来执行逻辑删除

2.2.5、测试逻辑删除后的查询

//查询所有数据
    @Test
    public void testAll(){
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }

执行结果:

从执行结果打印出来的语句,可以看到只会查出来没有被删除的数据(即:delete_status=0)

七、条件构造器和常用接口

mybaitis-plus为了应对复杂的查询,引入了wapper

 wrapper:条件构造抽象类,最顶端父类,AbstractWrapper: 用于查询条件封装,主要是生成sql语句的where条件    QueryWrapper:查询条件封装(常用),UpdateWrapper:Update条件封装

/*
    * 用mp实现一些复杂查询 - Wrapper
    * */

    // 1、ge(大于等于)、gt(大于)、le(小于等于)、lt(小于)、isNull(为空)、isNotNull(不为空)
    @Test
    public void testQuery(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .isNotNull("name")
                .ge("age",20)
                .isNull("create_time");

        int num = userMapper.delete(queryWrapper);
        System.out.println(num);

        /*
        * 执行的sql语句:
        *   UPDATE user SET delete_status=1 WHERE delete_status=0 AND (name IS NOT NULL AND age >= ? AND create_time IS NULL)
         * 从语句可以看出:queryWrapper的几个条件,刚好就是sql语句中的where条件
        * */
    }

    //2、eq(等于)、ne(不等于)
    @Test
    public void testQuery1(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name","高圆圆");
        // selectOne()返回的是一条实体记录,当出现多条是会报错
        User user = userMapper.selectOne(queryWrapper); //只能返回一条记录,多余一条则会返回异常
        System.out.println(user);
    }

    //3、between,notBetween
    @Test
    public void testQuery2(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.between("age",20,25);
        Integer count = userMapper.selectCount(queryWrapper);
        System.out.println(count);
    }

    //4、like、notlike、likeLeft、likeRight  (模糊查询)
    @Test
    public void testQuery3(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .select("name","age")
                .like("name","丽")
                .likeRight("email","123");
        List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
        System.out.println(maps);
    }

    //5、orderBy(排序)、orderByDesc(降序)、orderByAsc(升序)
    @Test
    public void testQuery4(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id","age");
        List<User> users = userMapper.selectList(queryWrapper);
        System.out.println(users);
    }

 Wrapper的查询方式

SourceURL:file:///Users/mobvista/Desktop/资料/Java培训课程/慧测_测试开发/尚医通--要学习的new/笔记/01-教案/day01 项目介绍与MyBatis Plus.doc

查询方式

说明

setSqlSelect

设置 SELECT 查询字段

where

WHERE 语句,拼接 + WHERE 条件

and

AND 语句,拼接 + AND 字段=值

andNew

AND 语句,拼接 + AND (字段=值)

or

OR 语句,拼接 + OR 字段=值

orNew

OR 语句,拼接 + OR (字段=值)

eq

等于=

allEq

基于 map 内容等于=

ne

不等于<>

gt

大于>

ge

大于等于>=

lt

小于<

le

小于等于<=

like

模糊查询 LIKE

notLike

模糊查询 NOT LIKE

in

IN 查询

notIn

NOT IN 查询

isNull

NULL 值查询

isNotNull

IS NOT NULL

groupBy

分组 GROUP BY

having

HAVING 关键词

orderBy

排序 ORDER BY

orderAsc

ASC 排序 ORDER BY

orderDesc

DESC 排序 ORDER BY

exists

EXISTS 条件语句

notExists

NOT EXISTS 条件语句

between

BETWEEN 条件语句

notBetween

NOT BETWEEN 条件语句

addFilter

自由拼接 SQL

last

拼接在最后,例如:last(“LIMIT 1”)


 

posted @ 2022-09-21 19:21  尘封~~  阅读(23)  评论(0编辑  收藏  举报