美文网首页
简单之美 MyBatis Plus

简单之美 MyBatis Plus

作者: 秋的蓝 | 来源:发表于2018-11-02 23:03 被阅读0次

前言

项目开发一直使用MyBatis , 简单,方便,容易上手,调优比其他的ORM框架容易的多。最近一次偶然的搜索,发现了MyBatis Plus, 试用之后,真是太爽了。MyBatis Plus是攻城狮的福利,几乎不用编码就可以完成单表的CRUD操作。使用心得做个记录。

一、准备环境

IDE编辑器:IntelliJ IDEA 2018.2.4(Ultimate Edition)
数据库:MySQL 5.7
框架:MyBatis Plus 3.05 , Spring Boot 2.0.6
管理工具:Maven 3.3.9
JDK:jdk1.8或以上

1. IDEA设置

idea是java开发的利器,我个人的常用设置有这么几项:

1) 设置自动导入包
自动导入包
2) 设置提示快捷键

idea默认的代码提示是ctrl + 空格,常和输入法冲突,可以改为 alt + /,特别是从Eclipse转过来的同学,alt + / 比较顺手。


设置代码提示快捷键 alt + /
3) 设置多Tab标签

idea默认代码区的Tab标签是单行显示,多文件时不方便。


代码区多Tab显示
4) 设置提示不区分大小写

idea默认是按首字母大小写匹配,进行代码提示, 例如输入FileReader,必须F是大写才有提示, 设置完成后 f 也可以有提示。


代码提示不区分大小写
5) 设置的包显示风格
设置包的扁平风格

2. 安装其他软件

安装jdk1.8 , mysql 5.7 ,maven3以上版本

二、初识 MyBatis Plus

官网:MyBatis Plus
MyBatis Plus 简称MP, 是MyBatis的增强,不做改变,只做增强。简单而又强大。
MP是一只带着蓝色面罩的小鸟。

logo.png

1. 功能特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer2005、SQLServer 等多种数据库
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 XML 热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 支持关键词自动转义:支持数据库关键词(order、key......)自动转义,还可自定义关键词
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
  • 内置 Sql 注入剥离器:支持 Sql 注入剥离,有效预防 Sql 注入攻击

以上特性大多都是项目开发中必用的功能。

2. 开始上手

MP主页有示例,按照例子步骤就可以快速搭建MP项目。

  • 准备表 student
    主键是id字段, auto increment
    student.png
  • 创建Spring Boot项目
    建议使用 Spring Initializr,依赖项选择MySQL
    创建springboot项目

依赖MySQL
  • pom.xml
    工程属性
 <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
 </properties>

parent依赖项

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

SpringBoot 依赖项

   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
   </dependency>

   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
   </dependency>

MyBatis Plus依赖项

   <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.5</version>
   </dependency>

MySQL 依赖项

  <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
  </dependency>
  • 配置数据库信息
    编辑resource/application.yml文件,使用默认的application.properties文件也是可以的,两种类型的文件作用一样,语法格式有区别。
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8
    username: test
    password: 123456
  • 创建entity类
    创建Student类,属性名和列名相同
public class Student {
    //指定主键为 自动增长(mysql的 auto increment)
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    private String name;
    private Integer age;
    private String email;
    private Integer status;
    private Date createtime;
    // set | get
  • 创建Mapper接口
public interface StudentMapper extends BaseMapper<Student> {
   //无需任何内容
}
  • 测试insert
    在test/java/ 目下创建测试类,使用@Test修饰测试方法
@SuppressWarnings("all")
@RunWith(SpringRunner.class)
@SpringBootTest
public class MPTest {
    @Autowired
    private StudentMapper studentMapper;

    @Test
    public void testInsertStudent(){
        Student student = new Student();
        student.setName("李名");
        student.setAge(20);
        student.setEmail("liming@163.com");
        student.setStatus(1);
        student.setCreatetime( new Date());
        int rows = studentMapper.insert(student);
        System.out.println("insert 结果:"+rows);
    }

}

三、实体属性名和列名相同

上面“2 开始上手”,实体类属性名和表的列名是相同的,使用MP无需设置,就可以完成CRUD, 在这部分继续实行其他的单表操作。

1. 增加数据

同“2 开始上手”中的测试部分的代码,首先创建实体对象, 给属性赋值,调用studentMapper的insert(),参数是实体类对象, insert()返回值是数据库插入成功的行数。整数值。

    //添加记录,并获取新记录的注解
    @Test
    public void testInsertStudent() {
        Student student = new Student();
        student.setName("周新");
        student.setAge(20);
        student.setEmail("liming@163.com");
        student.setStatus(1);
        student.setCreatetime(new Date());
        int rows = studentMapper.insert(student);
        // 主键是id,获取新添加记录的id,使用对象的getId()
        int newId = student.getId();
        System.out.println("insert 结果:" + rows + "|对象的id:"+newId);
    }

输出:insert 结果:1|对象的id:8 , id是你插入数据主键和我的不同。

2.修改数据

    //根据主键修改对象
    @Test
    public void testUpdateStudent(){
        Student student = new Student();
        student.setId(8);
        student.setName("新的名字");
        student.setAge(30);
        //根据主键修改对象, 对象null的属性,不进行修改
        int rows = studentMapper.updateById(student);
    }

首先给要修改的属性赋值,null的属性,不会参与修改。update set 列名=值不会出现null的字段;条件部分是 where id= 8;
注意:MP判断是否修改字段是判断属性的null,最好实体类Student的属性都是引用类型, 包括Integer age , 这样不给age赋值,就不会更新age字段。如果实体类定义 int age 。

    //根据主键修改对象
    @Test
    public void testUpdateStudent(){
        Student student = new Student();
        student.setId(8);
        student.setName("新的名字");
        //student.setAge(30);
        //根据主键修改对象, 对象null的属性,不进行修改
        int rows = studentMapper.updateById(student);
    }

MP的执行sql: UPDATE student SET name=?, age=? WHERE id=?
修改结果是 age 是 0 , 因为Student属性 int age ,这样定义int类型默认初值是 0 。

updateById()是根据主键作为添加更新,还可以根据其他条件更新,例如update(实体对象, Wrapper), Wrapper的使用后面会说到。

3. 删除数据
BaseMapper中删除方法

 deleteBatchIds(Collection); 参数是主键的集合,删除多条数据
 delete(Wrapper); 根据Wrapper对象的条件,删除数据
 deleteById(主键id);根据单一主键,删除数据
 deleteByMap(Map<String,Object>); 使用Map作为条件删除数据

    //删除数据
    @Test
    public void testDeleteStudent(){
        // sql : DELETE FROM student WHERE id=? 
        int rows = studentMapper.deleteById(2);
        System.out.println("deleteById结果:"+rows);
    }

注:deleteById(), 参数是主键值, 删除条件是 where id = 2


    @Test
    public void testDeleteStudent2(){
       Map<String,Object> condition = new HashMap<>();
       condition.put("name","周新");
       condition.put("age",20);
       int rows = studentMapper.deleteByMap(condition);
       System.out.println("deleteByMap 结果:"+rows);
    }

注:创建Map, 添加条件数据。Map的key是字段名,value是字段的值。调用deleteByMap(); 传入Map对象。 返回值成功删除的行数。


    @Test
    public void testDeleteStudent3(){
        //DELETE FROM student WHERE name = ? OR age > ? 
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.eq("name", "周新")
                .or()
                .gt("age", 20);
        int rows = studentMapper.delete(wrapper);
        System.out.println("delete(wrapper) 结果:"+rows);
    }

注:Wrapper是抽象类,QueryWrapper是他的子类, 用来封装条件字段和字段值。 eq()表示等于=, or() 是字段之间用 or 连接, gt()是大于。这些只是Wrapper中的几个方法, 参数是字段名,不是属性名。

4. 查询数据
BaseMapper的多个查询方法

  selectBatchIds(Collection); 查询集合中多个主键值数据
  selectByMap(Map<String,Object>); 根据Map条件查询
  selectList(Wrapper); 使用Wrapper对象作为查询条件
  selectById(id); 根据主键值查询
  selectPage(IPage, Wrapper); 根据Wrapper条件并进行分页
  selectCount(Wrapper); 统一记录数量
  selectOne(Wrapper); 查询结果是一个对象

使用selectById , selectOne查询数据, 其他查询方法后面有单独的章节,独立讲查询的各种使用方式。

    @Test
    public void testSelectStudent(){
        // SELECT id,name,age,email,status,createtime FROM student WHERE id=?
        Student student = studentMapper.selectById(8);
        System.out.println("根据id查询结果:"+student);
    }

    @Test
    public void testSelectStudent2(){
        QueryWrapper<Student> condition = new QueryWrapper<>();
        condition.eq("name","李名");
        //SELECT id,name,age,email,status,createtime FROM student WHERE name = ?
        Student student = studentMapper.selectOne(condition);
        System.out.println("selectOne查询结果:"+student);
    }

注:先创建Wrapper对象,添加查询条件, 调用selectOne()方法。 selectOne()的查询结果必须小于或等于一条记录,MP内部是调用的MyBatis的selectOne()方法,多于一个记录,系统会报错,错误提示如下:

org.apache.ibatis.exceptions.TooManyResultsException

相关文章

网友评论

      本文标题:简单之美 MyBatis Plus

      本文链接:https://www.haomeiwen.com/subject/mcnatqtx.html