zoukankan      html  css  js  c++  java
  • mybatis-plus入门

    mybatis-plus 介绍

    关于介绍可以看官网https://mp.baomidou.com/guide/#%E7%89%B9%E6%80%A7

    mybatis-plus 简称MP,MP 使用类似于JPA  Dao层接口继承BaseMapper<要操作的实体类> 里面封装了Crud的一套方法 继承该接口,既可以调用方法进行基础的Crud,可以不用写sql 用过Hibernate 的都明白。

    MP要求编程人员 要熟悉mybatis  自然也要熟悉sql   还有lambda 表达式 才能很好的学习掌握MP

    下面是我写的测试项目 ,用于测试MP的方法 ,只是学习作用。

    创建springboot项目  添加jar坐标

    <!--Mybatis-Plus启动器-->
    <dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.1.0</version>
    </dependency>

    application.yml

    spring:
    datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/kgc?useSSL=false&ServerTimezone=GMT%2B8&characterEncoding=utf-8
    username: root
    password: root
    logging:
    level:
    root: warn
    com.mp.dao: trace 打印日志 只输出dao层 这里是输出sql语句
    pattern:
    console: '%p%m%n'

    实体类

    Data
    @TableName("user")//该注解指定映射数据库表名 数据库名与实体类名一样时可以不写
    public class User {

        
         @TableId//这个注解是指定id的映射 MP 默认找id做主键  字段不是id 就需写上该注解
        private Long id;
        @TableField("name")//注解是指定非字段名映射 字段名不相同时使用
    private String name;


    private Integer age;

    private String email;
    //直接上级
    private Long managerId;
    //创建时间
    private LocalDateTime createTime;
      
    //备注 这里是程序运行的时需要的字段并非数据库字段
    //MP 对于这种字段有三中解决方案 新增时 MP会自动过滤该属性不会添加到数据库 sql语句回忽略掉
    //1 private transient String remark; 表示不参与数据序列化 如果该类都要序列化 可以采取第二种方案
    //2 private static String remark 声明为静态变量(注意我这用的是Lombok 注解 静态变量不生成get、set 需要手动生成)
    //3 @TableField(exist = false) exist 默认是true 表示该属性是数据库字段 false 表示非数据库字段
    // private static String remark;
    @TableField(exist = false)
    private static String remark;

    public static String getRemark() {
    return remark;
    }

    public static void setRemark(String remark) {
    User.remark = remark;
    }


    }

    测试

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SimpleTest {
    @Autowired
    private UserMapper userMapper;


    @Test
    public void selectTest() {
    List<User> list = userMapper.selectList(null);
    Assert.assertEquals(5, list.size());
    list.forEach(System.out::println);
    }


    @Test
    public void insertTest() {
    User user = new User( );
    user.setAge(22);
    user.setName("刘强");
    user.setManagerId(1088248166370832385L);
    user.setCreateTime(LocalDateTime.now());
    user.setRemark("程序组装字段");
    int insert = userMapper.insert(user);
    System.out.println("影向记录数"+insert);
        List<Long> idlist = Arrays.asList(1088248166370832385L,1088250446457389058L,1094590409767661570L);
        
          //生成的sql为SELECT id,name,age,email,manager_id,create_time FROM user WHERE id IN ( ? , ? , ? )
        List<User>  userList  = userMapper.selectBatchIds(idlist);
        userList.forEach(System.out::println);



    }
      @Test
      public void selectByMap() {
       Map<String, Object> map = new HashMap<>();
       //生成的sql SELECT id,name,age,email,manager_id,create_time FROM user WHERE name = ? AND age = ?
       //map 中的key值是数据库的列 用字符串类型
       map.put("name", "王天风");
       map.put("age", 25);
       List<User> users = userMapper.selectByMap(map);
       users.forEach(System.out::println);
    }
    多条件查询使用条件构造器多条件条件链式添加
    下面是几个示例:
     /**
    * 查询名字包含雨并且年龄小雨40;
    */
    @Test
    public void selectByWrapper() {
    //创建条件构造器对象 有下面两种
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    // QueryWrapper<User> query = Wrappers.<User>query();
    //封装条件
    //生成的sql: SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? AND age < ?
    QueryWrapper<User> lt = queryWrapper.like("name", "雨").lt("age", 40);
    List<User> users = userMapper.selectList(lt);
    users.forEach(System.out::println);

    }

    /**
    * 查询名字包含雨并且年龄大于等于20且小于等于40并且email不为空;
    * name like'%雨%' and age between 20 and 40 email is not null
    */
    @Test
    public void selectByWrapper2() {
    //创建条件构造器对象
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //生成的sql语句为: SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL
    QueryWrapper<User> wrapper = queryWrapper.like("name", "雨").between("age", 20, 40).isNotNull("email");
    List<User> users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
    }
      
      
    /**
    * 查询名字为王姓或者年龄大于等于25,按照年龄降序排列,年龄相同按照ID 升序排序
    * name like'雨%' or age>= 25 order by age desc,id asc
    */
    @Test
    public void selectByWrapper3() {
    //创建条件构造器对象
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //sql语句为: SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? OR age >= ? ORDER BY age DESC , id ASC 
    QueryWrapper<User> wrapper = queryWrapper.likeRight("name", "王")
                         .or().ge("age", 25)
                        .orderByDesc("age")
                        .orderByAsc("id");
    List<User> users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
    }

    /**
    * 查询创建日期为2019年2月14日 并且直属上级的名字为王姓
    * date_format(create_time,'%Y-%m-%d')and manager_id in (select id from user where name like '王%')
    */
    @Test
    public void selectByWrapper4() {
    //生成的Sql语句:SELECT id,name,age,email,manager_id,create_time FROM user WHERE date_format(create_time,'%y-%m-%d')=? AND manager_id IN (select id from user where name like '王%')
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.apply("date_format(create_time,'%Y-%m-%d')={0}", "2019-02-14")
    .inSql("manager_id", "select id from user where name like '王%'");
       // queryWrapper.apply("date_format(create_time,'%Y-%m-%d')='2019-02-14'") 也可以直接写入值  相当于mybatis ${} 有sql注入风险 
    // .inSql("manager_id", "select id from user where name like '王%'");

    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);

      
    }
    
    
    /**
    * 名字为王姓并且(年龄小于40并且年龄大于20并且邮箱不为空)
    * name like '王%' and (age <40 or email in not null)
    */
    @Test
    public void selectByWrapper6() {
    //生成的Sql语句:SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? AND ( age < ? AND age > ? AND email IS NOT NULL )
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.likeRight("name", "王")
    .and(wq->wq.lt("age", 40).gt("age", 20).isNotNull("email"));

    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);


    }
    
    
    /**
    * (年龄小于40或邮箱不为空) 并且名字为王姓
    * (age < 40 or email is not null ) and name liek '王%'
    */
    @Test
    public void selectByWrapper7() {
    //生成的Sql语句:SELECT id,name,age,email,manager_id,create_time FROM user WHERE ( age < ? OR email IS NOT NULL ) AND name LIKE ?
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.nested(wq->wq.lt("age", 40).or().isNotNull("email"))
    .likeRight("name", "王");

    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);


    }
      
    /**
    * 查年龄为30 31 34 35
    * age in(30 31 34 35)
    */
    @Test
    public void selectByWrapper8() {
    //生成的Sql语句:SELECT id,name,age,email,manager_id,create_time FROM user WHERE age IN (?,?,?,?) 
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.in("age", Arrays.asList(30, 31, 34, 35));


    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);


    }
    下面两种方法是针对查询是需要查询某一些列 不需要全部的列
    
    
    /**
    * 只查询 ID name 字段名字中包含雨的 并且年龄小于40
    * name like '%雨%' and age<40
    */
    @Test
    public void selectByWrapperSuper(){
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //sql: SELECT id,name FROM user WHERE name LIKE ? AND age < ?
    queryWrapper.select("id","name").like("name","雨").lt("age", 40);

    List<User> userList = userMapper.selectList(queryWrapper);
    userList.forEach(System.out::println);
    }
    /**
    * 查询出表中的字段 除create_time manager_id 外所有字段 名字中包含雨的 并且年龄小于40
    * name like '%雨%' and age<40
    */
    @Test
    public void selectByWrapperSuper2(){
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //sql:SELECT id,name,age,email FROM user WHERE name LIKE ? AND age < ?
    queryWrapper.like("name","雨")
    .lt("age", 40)
    .select(User.class,info->!info.getColumn().equals("create_time")&& !info.getColumn().equals("manager_id"));

    List<User> userList = userMapper.selectList(queryWrapper);
    userList.forEach(System.out::println);
    }
     
        /**
    * 条件查询中condition的作用 condition是boolean 类型表示执行条件 true 表示 添加该条件 false不添加该条件 是一种动态sql的方法实现
       * 查询方法底层都有condition MP 默认是为true 添加该条件 要想写动态 调用对应查询的重载方法 第一个参数就是condition

    */
    private void condition(String name, String email) {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //sql:SELECT id,name,age,email FROM user WHERE name LIKE ? AND age < ?
    // if (StringUtils.isNotEmpty(name)) {
    // queryWrapper.like("name", name);
    // }
    // if (StringUtils.isNotEmpty(email)) {
    // queryWrapper.like("email", email);
    // }
    queryWrapper.like(StringUtils.isNotEmpty(name),"name", name)
    .like(StringUtils.isNotEmpty(email),"email", email);
    List<User> userList = userMapper.selectList(queryWrapper);
    userList.forEach(System.out::println);
    }

    @Test
    public void testCondition() {
    //生成的sql语句: SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? 没有 拼接email
    String name = "王";
    String email ="";
    condition(name, email);
    }
      
    /**
    * 这里条件构造器传入对象 用对象的属性值给查询条件赋值 和mybatis的对象参数是一个道理
    *  
    */
    @Test
    public void selectByEntity(){
    User user = new User( );
    user.setName("刘红雨");
    user.setAge(32);
    //生成的sql语句: SELECT id,name,age,email,manager_id,create_time FROM user WHERE name=? AND age=?
    QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
      
      //条件对象也有封装条件 它与对象参数的sql生成互不干扰 
      //SELECT id,name,age,email,manager_id,create_time FROM user WHERE name=? AND age=? AND name LIKE ? AND age < ?
      //可以看到两种条件的添加 sql会做继续拼接 并不影响各自
     // queryWrapper.like("name", "雨").lt("age", 40);
      //也可以在实体类上做条件
      
    /**
    * condition = SqlCondition.LIKE 该属性表示 name 字段在做条件查询时 sql条件会直接生成 name like CONCAT(‘%’,?,‘%’)
    * 当然SqlCondition.LIKE 不止有like

    @TableField(condition = SqlCondition.LIKE)
    private String name; */
     
    
    
     

    List<User> userList = userMapper.selectList(queryWrapper);

    userList.forEach(System.out::println);
    }
     /**
    * allEq的用法
    * 添加等值条件查询
    * 生成的sql语句:SELECT id,name,age,email,manager_id,create_time FROM user WHERE name = ? AND age = ?
    * 如果 条件添加 是这样的 例如 params.put("age",null) sql 会生成 and age is null 想要让sql 对null 值 忽略掉 使用 allEq(params, false)实现
    */
    @Test
    public void selectAllEq() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    Map<String, Object> params = new HashMap<>();

    params.put("name", "王天风");
    params.put("age", 25);
    // queryWrapper.allEq(params);
    //生成的sql语句:SELECT id,name,age,email,manager_id,create_time FROM user WHERE name = ? AND age = ?
    //如果 条件添加 是这样的 例如 params.put("age",null) sql 会生成 and age is null 想要让sql 对null 值 忽略掉 使用 allEq(params, false)实现
    // queryWrapper.allEq((k,v)->k.equals("name"),params); 这里使用Lambda函数 也可以实现对null值条件忽略

    List<User> userList = userMapper.selectList(queryWrapper);
    userList.forEach(System.out::println);
    }

      
    /**
    * List<Map<String,Object>> userList = userMapper.selectMaps(queryWrapper);
    * 返回值为map对象 应用于 在查询时只要个别字段 那么返回对象的话 不需要的字段都为null
    * 这样就不优雅了 所以提供selectMaps()方法 避免null
    */
    @Test
    public void selectMaps() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.like("name", "雨").lt("age", 40);
    //生成的sql语句 SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? AND age < ?


    List<Map<String, Object>> userList = userMapper.selectMaps(queryWrapper);
    userList.forEach(System.out::println);

    }


    /**
    * selectMaps()应用场景
    * 按照直属上级分组, 查询每组 的平均年龄 最大年龄, 最小年龄
    * 并且只取年龄总和 小于500的组
    *
    */
    @Test
    public void selectByMaps2(){
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //生成的sql语句 SELECT avg(age) avg_age,min(age) min_age,max(age)max_age FROM user GROUP BY manager_id HAVING sum(age)<?
    queryWrapper.select("avg(age) avg_age","min(age) min_age","max(age)max_age")
    .groupBy("manager_id")
    .having("sum(age)<{0}", 500);


    List<Map<String, Object>> userList = userMapper.selectMaps(queryWrapper);
    userList.forEach(System.out::println);


    }
     
    /**
    * selectObjs() 做查询 只会返回 一个列的值 而且是第一列 其他的列都会被舍弃
    * 只能在只需要放回一列时使用
    */
    @Test
    public void selectByobjs(){
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //生成的sql语句 SELECT avg(age) avg_age,min(age) min_age,max(age)max_age FROM user GROUP BY manager_id HAVING sum(age)<?
    queryWrapper.select("avg(age) avg_age","min(age) min_age","max(age)max_age")
    .groupBy("manager_id")
    .having("sum(age)<{0}", 500);


    List<Object> userList = userMapper.selectObjs(queryWrapper);
    userList.forEach(System.out::println);
    //返回值 40.0000
    // 25.0000
    // 28.2500 只有avg_age 的值


    }

    /**
    * 查询总记录数
    */
    @Test
    public void selectCount() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //生成的sql语句 SELECT COUNT( 1 ) FROM user WHERE name LIKE ? AND age < ?
    queryWrapper.like("name", "雨").lt("age", 40);


    Integer count = userMapper.selectCount(queryWrapper);
    System.out.println(count);


    }
    
    
    /**
    * selectOne() 只能返回条数据 或者返回空 所以条件必须满足只有一条数据或没有
    */
    @Test
    public void selectOne() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //生成的sql语句  SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? AND age < ?   
    queryWrapper.like("name", "刘红雨").lt("age", 40);
    User count = userMapper.selectOne (queryWrapper);
    System.out.println(count);


    }
    以上就是条件构造器查询 封装条件 做查询 还是有很多细节要掌握 ,认真学习 ,坚持练习没有不能掌握的知识。


      























    }
  • 相关阅读:
    Hadoopif.for.while 语句
    完全分布模式的四大模块设置
    语法糖定义
    Karaf 依赖equinox and felix,karaf 本Apache的很多项目作为基础框架
    Karaf 基于 osgi
    MEF(Managed Extensibility Framework) 微软平台插件化开发
    析构函数,构造函数
    C#和ASP.Net面试题目集锦
    论C# java的基本类型
    Boolean.parseBoolean("true") 和 Boolean.getBoolean("true");的区别及用法
  • 原文地址:https://www.cnblogs.com/bosblogs/p/11172081.html
Copyright © 2011-2022 走看看