• MybatisPlus核心功能——实现CRUD增删改查操作 (包含条件构造器)


    CRUD

    官方文档:https://baomidou.com/
    (建议多看看官方文档,每种功能里面都有讲解)【本文章使用的mybatisplus版本为3.5.2】

    条件构造器

    一般都是用service层的方法,因为比mapper层的全。十分重要:Wrapper 记住查看输出的SQL进行分析

    相当于创建一个构造器对象,然后讲需要查询or更新的条件写在里面,最后打包给mapper or service层的插入、更新方法

    下图是Wapper的子类,QueryWrapperUpdateWrapper是一般的Wrapper,AbstractLambdaWrapper 是lambda语法糖的链式操作(两者选择一种使用即可)

    image

    下图是wrapper的条件方法,就不一一介绍了,下面举了六个就基本例子
    image

    1、测试一

    copy
    @Test public void testWrapper1() { //参数是一个wrapper ,条件构造器,和刚才的map对比学习! //查询name不为空,email不为空,age大于18的用户 QueryWrapper wrapper = new QueryWrapper<>(); wrapper .isNotNull("name") .isNotNull("email") .ge("age",18); List userList = userMapper.selectList(wrapper); userList.forEach(System.out::println); }

    测试二

    copy
    @Test public void testWrapper2() { //查询name=wsk的用户 QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("name","wsk"); //查询一个数据selectOne,若查询出多个会报错 //Expected one result (or null) to be returned by selectOne(), but found: * //若出现多个结果使用list或map User user = userMapper.selectOne(wrapper);//查询一个数据,若出现多个结果使用list或map System.out.println(user); }

    测试三

    copy
    @Test public void testWrapper3() { //查询age在10-20之间的用户 QueryWrapper wrapper = new QueryWrapper<>(); wrapper.between("age", 10, 20);//区间 Integer count = userMapper.selectCount(wrapper);//输出查询的数量selectCount System.out.println(count); }

    测试四

    copy
    @Test public void testWrapper4() { //模糊查询 QueryWrapper wrapper = new QueryWrapper<>(); wrapper .notLike("name","s") .likeRight("email","qq");//qq% 左和右? List> maps = userMapper.selectMaps(wrapper); maps.forEach(System.out::println); }

    测试五

    copy
    @Test public void testWrapper5() { //模糊查询 // SELECT id,name,age,email,version,deleted,create_time,update_time //FROM user //WHERE deleted=0 AND id IN //(select id from user where id<5) QueryWrapper wrapper = new QueryWrapper<>(); //id 在子查询中查出来 wrapper.inSql("id","select id from user where id<5"); List objects = userMapper.selectObjs(wrapper); objects.forEach(System.out::println); }

    测试六

    copy
    @Test public void testWrapper6() { QueryWrapper wrapper = new QueryWrapper<>(); //通过id进行降序排序 wrapper.orderByDesc("id"); List userList = userMapper.selectList(wrapper); userList.forEach(System.out::println); }

    CRUD接口

    基本配置:

    0、创建数据库

    copy
    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 '邮箱', version INT(10) NOT NULL DEFAULT 1 COMMIT '乐观锁版本号', DELETED INT(10) NOT NULL DEFAULT 0 COMMIT '逻辑删除', CREATE_TIME DATE COMMIT '创建时间', modify_time DATE COMMIT '更新时间', PRIMARY KEY (id) ); DELETE FROM user; INSERT INTO user (id, name, age, email) VALUES (1, '工藤新一','test1@baomidou.com'), (2, '毛利兰','est2@baomidou.com'), (3, '柯南', 28, 'test3@baomidou.com'), (4, '灰原哀', 21, 'test4@baomidou.com'), (5, '工藤有希子', 24, 'test5@baomidou.com');

    1、创建项目,导入依赖

    copy
    <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-testartifactId> <scope>testscope> dependency> <dependency> <groupId>org.projectlombokgroupId> <artifactId>lombokartifactId> dependency> <dependency> <groupId>mysqlgroupId> <artifactId>mysql-connector-javaartifactId> <version>8.0.26version> dependency> <dependency> <groupId>com.baomidougroupId> <artifactId>mybatis-plus-boot-starterartifactId> <version>3.5.2version> dependency>

    2、yaml

    copy
    #设置开发环境 spring: datasource: username: root password: 123456 driver-class-name: com.p6spy.engine.spy.P6SpyDriver url: jdbc:p6spy:mysql://localhost:3306/mybatis_plus?serverTimezone=UTC&useUnicode=true&characterEncoding=utf #配置日志 log-impl:日志实现 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

    3、创建实体类

    copy
    @Data @AllArgsConstructor @NoArgsConstructor @TableName("user") public class User { @TableId(type = IdType.AUTO) Long id; String name; int age; String email; @Version//乐观锁version注解 private Integer version; private Integer isDelete; @TableField(fill = FieldFill.INSERT) private Date cTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date upTime; }

    4、写Mapper

    copy
    @Repository public interface UserMapper extends BaseMapper { }

    5、写Service接口和实现类

    copy
    //Service接口 public interface UserService extends IService { //别忘了继承这个父类 } //实现类 @Service public class UserServiceImpl extends ServiceImpl implements UserService { //记得继承父类 }

    6、之后就可以测试了

    Mapper CRUD接口

    顾名思义这个只有mapper层对象才有的方法

    Insert

    写数据库的时候id设置了主键自增的话,插入的时候不需要加入id,因为MP会自动添加并且自增的。

    注:数据库写了id自增的话,在实体类设置主键生成策略是没用的,因为数据库设置了自增,数据库优先级高于代码

    copy
    @Test//测试插入 public void insertTest(){ User user = new User(); user.setName("wsk"); user.setAge(18); user.setEmail("2803708553@qq.com"); Integer result = userMapper.insert(user); //会帮我们自动生成id System.out.println(result); //受影响的行数 System.out.println(user); //通过日志发现id会自动回填(id是由雪花算法生成的,在主键生成策略部分有讲到) }

    image

    数据库插入的id的默认值为:全局的唯—id

    Update

    copy
    @Test//测试更新 public void updateTest(){ User user = new User(); user.setId(2L);//怎么改id?? //通过条件自动拼接动态Sql user.setName("root"); user.setAge(12); user.setEmail("root@qq.com"); int i = userMapper.updateById(user);//updateById,但是参数是个user System.out.println(i); }

    image

    Select

    • 通过id查询单个用户
    copy
    @Test//通过id查询单个用户 public void testSelectById(){ User user = userMapper.selectById(1L); System.out.println(user); }

    image

    • 通过id查询多个用户
    copy
    @Test//通过id查询多个用户 public void testSelectBatchIds(){ List users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L)); users.forEach(System.out::println); //System.out.println(users); }

    image

    image

    • 条件查询 通过map封装
    copy
    @Test//通过条件查询之一 map(这里的map,相当于where后面的 name="conan"等条件) public void testMap(){ HashMap map = new HashMap<>(); //自定义要查询的 map.put("name","www"); //查询名字是www的数据 map.put("name","111"); //查询名字是111的数据 最后的结果是取两者交集 map.put("age",18); List users = userMapper.selectByMap(map); users.forEach(System.out::println); }

    image

    image

    Delete

    基本的删除任务:

    image

    copy
    @Test public void testDeleteById(){ userMapper.deleteById(1359507762519068681L); } @Test public void testDeleteBatchIds(){ userMapper.deleteBatchIds(Arrays.asList(1359507762519068675L,1359507762519068676L)); } @Test public void testD(){ HashMap map = new HashMap<>(); map.put("age","18"); map.put("name","lol"); userMapper.deleteByMap(map); }

    Service CRUD接口

    顾名思义这是Service层才有的方法

    Save

    为了区分mapper层和service层的方法,所以service层的插入方法取名为save

    copy
    @Test void test(){ User user = new User(); user.setName("Conan"); user.setAge(18); user.setEmail("毛利侦探事务所"); //插入单条数据 userService.save(user); // 插入(批量) userService.saveBatch(Arrays.asList(user)); }

    Remove

    service层删除方法取名为remove

    copy
    @Test void test(){ User user = new User(); user.setName("Conan"); user.setAge(18); user.setEmail("毛利侦探事务所"); HashMap map = new HashMap<>(); map.put("name","Conan"); QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("name","毛利小五郎"); userService.remove(wrapper); //根据条件构造器删除数据 userService.removeById(16L); //根据id删除数据,也可以根据实体类对象删除数据 userService.removeByMap(map); //根据map的条件删除记录 userService.removeBatchByIds(Arrays.asList(user)); //批量删除 }

    Update

    copy
    @Test void test(){ User user = new User(); user.setName("Conan"); user.setAge(18); user.setEmail("毛利侦探事务所"); HashMap map = new HashMap<>(); map.put("name","Conan"); QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("name","毛利小五郎") .ge("age",18); userService.update(wrapper); //根据条件构造器更新 userService.updateById(user); //根据传入的实体类id确定需要更新的数据,更新为传入的实体类对象 userService.updateBatchById(Arrays.asList(user)); //批量更新 }

    Get

    该方法只能查询一条数据,所以不推荐。查询用list方法

    copy
    @Test void test(){ User user = new User(); user.setName("Conan"); user.setAge(18); user.setEmail("毛利侦探事务所"); HashMap map = new HashMap<>(); map.put("name","Conan"); QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("name","毛利小五郎") .ge("age",18); userService.getById(12L); //根据id查询一条数据 userService.getMap(wrapper); //根据构造器查询一条数据,返回Mapper集合 }

    List

    查询多条数据

    copy
    @Test void test(){ User user = new User(); user.setName("Conan"); user.setAge(18); user.setEmail("毛利侦探事务所"); HashMap map = new HashMap<>(); map.put("name","Conan"); QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("name","毛利小五郎") .ge("age",18); userService.list(); //查询全部数据 userService.listMaps(); //查询全部数据,以map形式返回 userService.listByMap(map); //根据map查询数据 userService.listByIds(Arrays.asList(10L,15L)); //根据id查询数据 }

    SaveOrUpdate

    运行逻辑:直接更新,更新0行的话;就select,查询出来是0行;则就插入

    有传入id的情况会优先更新,如果更新不了,则会插入新的数据

    记得在实体类写上@TableId!!!

    copy
    @Test void test(){ User user = new User(); user.setName("Conan"); user.setAge(18); user.setEmail("毛利侦探事务所"); HashMap map = new HashMap<>(); map.put("name","Conan"); UpdateWrapper wrapper = new UpdateWrapper<>(); wrapper.eq("name","毛利小五郎") .ge("age",18); userService.saveOrUpdate(user); //传入的对象id存在则更新,否则插入新数据 userService.saveOrUpdate(user,wrapper); //根据更新条件构造器,更细数据 userService.saveOrUpdateBatch(Arrays.asList(user)); //批量修改插入 }

    Count

    统计符合条件的数据的数量

    copy
    @Test void test(){ User user = new User(); user.setName("Conan"); user.setAge(18); user.setEmail("毛利侦探事务所"); HashMap map = new HashMap<>(); map.put("name","Conan"); QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("name","毛利小五郎") .ge("age",18); userService.count(); userService.count(); }

    Chain

    链式调用,可以不用条件构造器完成 条件设置和增删改查。推荐!因为优雅!

    Query
    copy
    @Test void test(){ User user = new User(); user.setName("Conan"); user.setAge(18); user.setEmail("毛利侦探事务所"); HashMap map = new HashMap<>(); map.put("name","Conan"); QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("name","毛利小五郎") .ge("age",18); List userList = userService.query() .eq("name", "工藤新一") .gt("age", 17) .list(); for(User user01: userList) { System.out.println(user); } }
    Update
    copy
    @Test void test(){ User user = new User(); user.setName("Conan"); user.setAge(18); user.setEmail("毛利侦探事务所"); HashMap map = new HashMap<>(); map.put("name","Conan"); QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("name","毛利小五郎") .ge("age",18); userService.update() .eq("name", "工藤新一") .gt("age", 17) .update(); }
  • 相关阅读:
    Docker
    WPF中使用LibVLCSharp.WPF 播放rtsp
    分布式session的4种解决方案
    浅析云边端协同与算力调度在AI视频检测场景中的应用意义
    Python实用模块之argparse
    1s 创建100G文件,最快的方法是?
    springboot物业公司收费车位报修管理系统tbr18-java-ssm
    LeetCode 40 Java 实现
    C语言的函数
    Nuxt3 实战 (五):Header 头部布局
  • 原文地址:https://www.cnblogs.com/buchizicai/p/16607743.html