项目管理——MyBatisPlus

MyBatisPlus核心技术

一、MyBatisPlus快速开始

1 MyBatisPlus概述

MyBatis-Plus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。
MyBatisPlus的愿景是成为MyBatis最好的搭档,就像魂斗罗中的1P、2P,基友搭配,效率翻倍
在这里插入图片描述
官方网址:https://mp.baomidou.com/

2 MyBatisPlus准备工作

2.1 前期准备

  • 准备数据表,导入tb_employee.sql文件
    在这里插入图片描述

  • 创建Maven工程MyBatisPlus

  • 引入Maven依赖

    <dependencies>
        <!-- mybatisplus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.4.2</version>
        </dependency>
        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!-- lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
            <scope>provided</scope>
        </dependency>
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>
        <!-- log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.3.9</version>
        </dependency>
   
    </dependencies>
  • 在com.bzcxy.pojo下创建相关实体类(JavaBean)
@Data 
public class Employee {
    
     
	private Integer id; 
	private String empName; 
	private String useremail; 
	private String gender; 
	private Integer age; 
}

2.2 搭建Spring+Mybatis环境

  • Mybatis全局配置文件mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL Map Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <!--控制台输出sql语句配置 -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
</configuration>
  • 数据库配置文件jdbc.properties
jdbcusername=root
jdbcpassword=root
jdbcUrl=jdbc:mysql://localhost:3306/baizhan?useSSL=false&useUnicode=true&characterEncoding=utf8
driverClass=com.mysql.jdbc.Driver
  • Spring配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="
                    http://www.springframework.org/schema/context
                    http://www.springframework.org/schema/context/spring-context.xsd
                    http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
                    http://www.springframework.org/schema/tx
                    http://www.springframework.org/schema/tx/spring-tx.xsd
                    http://www.springframework.org/schema/aop
                    http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 加载配置文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- dataSource 配置 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
       <!-- 基本属性 url、user、password --> 
       <property name="driverClassName" value="${driverClass}"> </property> 
       
       <property name="url" value="${jdbcUrl}"/> 
       <property name="username" value="${jdbcusername}"/> 
       <property name="password" value="${jdbcpassword}"/>
    <!-- 对dataSource 数据源进行事务管理 -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
          p:dataSource-ref="dataSource"/>
    <!-- spring与mybatis整合配置-->
    <bean id="sqlSessionFactory"
          class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
          
    <!-- 自动扫描所有mapper ,将mapper接口生成代理注入到Spring-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
          p:basePackage="com.bzcxy.mapper"
          p:sqlSessionFactoryBeanName="sqlSessionFactory"/>
</beans>

3 集成MyBatisPlus

调整 SqlSessionFactory 为 MyBatis-Plus 的 SqlSessionFactory
MyBatis的SqlSessionFactory

org.mybatis.spring.SqlSessionFactoryBean

MyBatis-Plus的SqlSessionFactory

com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryB ean

测试

import com.bzcxy.mapper.EmployeeMapper;
import com.bzcxy.mapper.UserMapper;
import com.bzcxy.pojo.Employee;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class AppTest {
    
    
    private ApplicationContext applicationContext =
            new ClassPathXmlApplicationContext("applicationContext.xml");
    private UserMapper userMapper = applicationContext.getBean("userMapper",UserMapper.class);
    private EmployeeMapper employeeMapper =
            applicationContext.getBean("employeeMapper",EmployeeMapper.class);
    @Test
    //测试环境
    public void testEnv() throws SQLException {
    
    
        //从Spring容器中获取dataSource
        DataSource dataSource = (DataSource) applicationContext.getBean("dataSource");
        //获取链接
        Connection conn = dataSource.getConnection();
        System.out.println(conn);
    }

    @Test
    public void delall()
    {
    
    
        userMapper.deleteAll();
    }

    @Test
    public void testlogic()
    {
    
    
//        Employee employee = new Employee();
//        employee.setId(2);
//        employee.deleteById();
        Employee employee = new Employee();
        employee.setId(2);
        Employee e = employee.selectById();
        System.out.println(e);
    }

    @Test
    public void testfill()
    {
    
    
        Employee employee = new Employee();
        employee.setEmpName("百战程序员");
        employee.setUseremail("[email protected]");
        employee.setAge(3);
        employee.setGender("m");
        employee.insert();
    }

}

在这里插入图片描述

二、MyBatisPlus通用CRUD

1 BaseMapper

针对employee表进行CRUD

  • 基于MyBatis:
    编写EmployeeMapper接口,并手动编写CRUD方法
    提供EmployeeMapper.xml映射文件,并手动编写每个方法对应的SQL语 句
  • 基于MyBatisPlus
    只需要创建EmployeeMapper接口并继承BaseMapper接口,这就是使用
    MyBatisPlus需要完成的所有操作,甚至不需要创建SQL的映射文件
// BaseMapper<T>:泛型指定的是所需操作的实体类
//XXMapper继承该接口后,即可获得CRUD功能 不需要XXMapper.xml
public interface EmployeeMapper extends BaseMapper<Employee> {
    
    
    void deleteAll();
}

2 通用CRUD

2.1 insert

通过BaseMapper的insert方法可以直接传入一个实体类对象进行插入操作

public class CRUDTest {
    
    
    private ApplicationContext applicationContext =
            new ClassPathXmlApplicationContext("applicationContext.xml");
    private EmployeeMapper employeeMapper =
            applicationContext.getBean("employeeMapper",EmployeeMapper.class);
    @Test
    public void testInsert() throws SQLException {
    
    
        //创建实体类对象
        Employee employee = new Employee();
        //设置相关属性
        employee.setEmpName("MP");
        employee.setUseremail("[email protected]");
        employee.setGender("m");
        employee.setAge(15);
        //通过BaseMapper的insert方法插入数据
        int count = employeeMapper.insert(employee);
        //代表受影响的行数
       // System.out.println(employee.getId());
        //插入成功以后 直接获取主键
        System.out.println(employee.getId());
    }
  }

: 由于没有主键策略及相关属性不匹配,以上代码会报错

2.2 @TableId

@TableId注解于实体类属性上,用于指定哪个属性为主键

参数:
在这里插入图片描述
type主键的策略类型
在这里插入图片描述
ASSIGN_UUID 分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator
的方法nextUUID(默认default方法)

@Data 
public class Employee {
    
     
	//指定id属性为主键,value是数据表中的主键列名,如果属性名和列名一致,则可以 省略 
	//指定type主键策略为自增的IdType.AUTO 
	@TableId(value = "id",type = IdType.AUTO) 
	private Integer id; 
	private String empName; 
	private String useremail; 
	private String gender; 
	private Integer age; 
}

2.3 @TableName

@TableName注解于实体类上,用于指定该类为哪个表的实体类

@Data 
//mybatisplus 会找跟类名一样的表名 进行查询 
//@TableName指定表名为tb_employee 
@TableName(value = "tb_employee") 
public class Employee {
    
     
	//指定id属性为主键,value是数据表中的主键列名,如果属性名和列名一致,则可以 省略 
	//指定type主键策略为自增的IdType.AUTO 
	@TableId(value = "id",type = IdType.AUTO) 
	private Integer id; 
	private String empName; 
	private String useremail; 
	private String gender; 
	private Integer age; 
}

2.4 @TableField

@TableField注解于实体类非主键属性上,用于在属性和列名不同的情况下,指定映射关系

@Data 
//mybatisplus 会找跟类名一样的表名 进行查询 
//@TableName指定表名为tb_employee 
@TableName(value = "tb_employee")
public class Employee {
    
     
	//指定id属性为主键,value是数据表中的主键列名,如果属性名和列名一致,则可以 省略 
	//指定type主键策略为自增的IdType.AUTO 
	@TableId(value = "id",type = IdType.AUTO) 
	private Integer id; 
	private String empName; 
	//指定useremail属性对应的列名为email 
	@TableField(value = "email") 
	private String useremail; 
	private String gender; 
	private Integer age; 
}

再次执行代码,插入成功!
在这里插入图片描述
在这里插入图片描述

2.5 全局策略配置

如果针对每一个实体类都要添加相关注解,比较麻烦,可以使用通用的配置进行统一管理。
在applicationContext.xml中配置全局策略,全局配置有多个,在此仅仅配置DB

  <!-- 配置DB-->
    <bean id="DBConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig">
        <!--是否使用驼峰转下划线命名,默认开启 可以省略 -->
        <property name="tableUnderline" value="true"/>
        <!--设置所有主键为自增模式 -->
        <property name="idType" value="AUTO"/>
        <!--设置表名前缀 -->
        <property name="tablePrefix" value="tb_"/>
       
     </bean>

将DBconfig加入GlobalConfig

  <!-- 全局配置策略-->
    <bean id="globalconfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
        <property name="dbConfig" ref="DBConfig"/>
    </bean>

在sqlSessionFactory中添加globalConfig配置

<!-- spring与mybatis整合配置-->
    <bean id="sqlSessionFactory"
          class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--将globalConfig注入 sqlSessionFactory-->
        <property name="globalConfig" ref="globalconfig"/>
	</bean>        

修改POJO

@Data 
//mybatisplus 会找跟类名一样的表名 进行查询 
//@TableName指定表名为tb_employee 

public class Employee {
    
     
	//指定id属性为主键,value是数据表中的主键列名,如果属性名和列名一致,则可以 省略 
	//指定type主键策略为自增的IdType.AUTO 
	@TableId(value = "id") 
	private Integer id; 
	private String empName; 
	//指定useremail属性对应的列名为email 
	@TableField(value = "email") 
	private String useremail; 
	private String gender; 
	private Integer age; 
}

测试
在这里插入图片描述

2.6 获取主键值

MyBatis:需要通过useGenerateKeys,以及KeyProperty来设置

<insert id="save" parameterType="com.bzcxy.pojo.User" useGeneratedKeys="true" keyProperty="id"/> 
<!-- mybatis 支持主键自增,主键的值使用的是原生的jdbc方法 getGeneratedKey -->

MyBatisPlus:自动将主键值回写到实体类对象中

//插入成功以后 直接获取主键 
System.out.println(employee.getId());

在这里插入图片描述

2.7 update

通过BaseMapper的updateById方法可以直接传入一个实体类对象根据id进行更新没有设置的值则忽略

   @Test
    public void testUpdate()
    {
    
    
        //创建实体类对象
        Employee employee = new Employee();
        //设置需要更新的属性
        employee.setEmpName("baizhan");
        employee.setGender("f");
        //设置需要修改的数据id
        employee.setId(5);
        //根据主键进行更新,没有设置的值则忽略
        employeeMapper.updateById(employee);
    }

2.8 delete

  • 通过deleteById方法可以根据id删除一条记录
int deleteById(Serializable id);

//根据主键删除 
//删除11号数据 
employeeMapper.deleteById(11);
  • 通过deleteBatchIds进行批量删除
int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);

参数是实现Collection接口的集合

  @Test
    public void testDelete()
    {
    
    
        //根据主键删除
        //删除11号数据
       // employeeMapper.deleteById(11);
        //通过deleteBatchIds进行批量删除
        //创建list容器,加入将要删除的元素
        List<Integer> ids = new ArrayList<>();
        ids.add(12);
        ids.add(13);
        //同时删除12 13
        //employeeMapper.deleteBatchIds(ids);
        Map<String,Object> map = new HashMap<>();
        map.put("emp_name","baizhan");
        map.put("gender","m");
        employeeMapper.deleteByMap(map);
    }
  • 通过deleteByMap进行条件删除
int deleteByMap(@Param("cm") Map<String, Object> columnMap);

根据columnMap的key与value删除,key为列名,value为值,如果有多个key- value键值对,则按照and进行删除

Map<String,Object> map = new HashMap<>(); 
map.put("emp_name","baizhan"); 
//删除emp_name='baizhan'的数据 
employeeMapper.deleteByMap(map);
Map<String,Object> map = new HashMap<>(); 
map.put("emp_name","baizhan"); 
map.put("gender","m"); 
//删除emp_name为baizhan,gender为m的数据 
employeeMapper.deleteByMap(map);

2.9 select

  • 通过selectById根据id获取一条数据
T selectById(Serializable id); 
//根据id查找一条数据,并返回实体类对象 
Employee e = employeeMapper.selectById(1); 
System.out.println(e);
  • 通过selectBatchIds进行批量查询
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);

参数是实现Collection接口的集合

 
        //根据id集合查找
        //创建主键集合
        List<Integer> ids = new ArrayList<>();
        ids.add(1);
        ids.add(2);
        ids.add(3);
        //根据id = 1 2 3进行查询 返回一个 Employee对象集合
       List<Employee> emps = employeeMapper.selectBatchIds(ids);
       System.out.println(emps);
  • 通过selectByMap进行条件查询
List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);

根据columnMap的key与value查询,key为列名,value为值,如果有多个key- value键值对,则按照and进行查询

  @Test
    public void testselect()
    {
    
    
        //根据id查找一条数据,并返回实体类对象
       // Employee e = employeeMapper.selectById(1);
      //  System.out.println(e);
        //根据id集合查找
        //创建主键集合
        List<Integer> ids = new ArrayList<>();
        ids.add(1);
        ids.add(2);
        ids.add(3);
        //根据id = 1 2 3进行查询 返回一个 Employee对象集合
       // List<Employee> emps = employeeMapper.selectBatchIds(ids);
       // System.out.println(emps);
        Map<String,Object> map = new HashMap<>();
        map.put("gender","m");
        //查询所有gender=m的数据
        List<Employee> emps =  employeeMapper.selectByMap(map);
        System.out.println(emps);
    }
  • 通过selectPage进行分页查询
IPage<E> selectPage(IPage page, @Param("ew") Wrapper<T> queryWrapper);

page(分页条件):创建Page对象并初始化分页条件

//第0行数据开始取两行数据 
new Page<>(0,2)

queryWrapper(条件构造器):暂且为null

IPage(分页对象):返回的分页结果集、分页数据等

进行分页查询时,需要在sqlSessionFactory中添加分页插件

 <!-- 插件-->
        <property name="plugins">
            <array>
                <bean class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
                    <property name="interceptors">
                        <list>
                            <!-- 注册分页插件-->
                            <bean class="com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor"></bean>
                           
                        </list>
                    </property>
                </bean>
            </array>
        </property>

测试

    @Test
    public void testselectPage()
    {
    
    
        //分页数据
        Page page = new Page(0,2);
        IPage<Employee> res = employeeMapper.selectPage(page,null);
        //从分页对象中获取结果集
        List<Employee> emps = res.getRecords();
        System.out.println(emps);
    }

三、条件构造器

1 QueryWrapper

  • Mybatis-Plus 通过 QueryWrapper 来让用户自由的构建SQL条件,简单便捷,没有额外的负担,能够有效提高开发效率
  • 查询包装器QueryWrapper, 主要用于处理 sql 拼接,排序,实体参数查询等
  • 使用的是数据库字段,不是 Java 属性!
  • 需要给QueryWrapper提供实体类类型
  • 条件参数说明:
    在这里插入图片描述

2 select

  • selectList
    需要给QueryWrapper提供实体类类型new QueryWrapper()
public class QueryWrapperTest {
    
    
    private ApplicationContext applicationContext =
            new ClassPathXmlApplicationContext("applicationContext.xml");
    private EmployeeMapper employeeMapper =
            applicationContext.getBean("employeeMapper",EmployeeMapper.class);
    @Test
    public void testselectList()
    {
    
    
        QueryWrapper<Employee> qw = new QueryWrapper<>();
        //查询性别为女,且年龄小于等于35的数据
        qw.like("gender","f").le("age",35);
      //  List<Employee> emps = employeeMapper.selectList(qw);
       // System.out.println(emps);
        //查询年龄小于25或者年龄大于30的人
        List<Employee> emps =  employeeMapper.selectList(new QueryWrapper<Employee>()
                .lt("age",25)
                .or()
                .gt("age",30));
        System.out.println(emps);
    }
 }
  • selectPage
    @Test
    public void testselectpage()
    {
    
    
        //创建分页数据
        Page page = new Page(2,2);
        //获取第二页2条数据,且名字包含老师
        IPage<Employee> res = employeeMapper.selectPage(page,
                new QueryWrapper<Employee>().like("emp_name","老师"));
        //通过IPage的getRecords方法获取
        List<Employee> emps = res.getRecords();
        System.out.println(emps);
    }

3 update

    @Test
    public void testupdate()
    {
    
    
        //修改名字包含李且age=32数据
        //修改emp_name=baizhan [email protected]
        //创建条件构造器
        QueryWrapper<Employee> qw = new QueryWrapper<>();
        qw.like("emp_name","李").eq("age",32);
        //创建实体类对象
        Employee employee = new Employee();
        employee.setEmpName("baizhan");
        employee.setUseremail("[email protected]");
        employeeMapper.update(employee,qw);
    }

4 delete

    @Test
    public void testdel()
    {
    
    
        //删除age 在30-35之间 且名字包含a数据
        employeeMapper.delete(new QueryWrapper<Employee>()
                .between("age",30,35)
                .like("emp_name","a"));
    }

5 orderby

  • orderByAsc/orderByDesc:升序/降序方法
    @Test
    public void testOrderby()
    {
    
    
        //查询所有老师,按照年龄排序
        //按照年龄升序
//        List<Employee> emps = employeeMapper.selectList(new QueryWrapper<Employee>()
//                                    .like("emp_name","老师")
//                                    .orderByAsc("age"));
//        System.out.println(emps);
        List<Employee> emps = employeeMapper.selectList(new QueryWrapper<Employee>()
                                    .like("emp_name","老师")
                                    .orderByDesc("age"));
        System.out.println(emps);
    }

四、ActiveRecord

ActiveRecord(活动记录)也属于ORM(对象关系映射)层,由Rails最早提出,遵循标准的ORM模型:表映射到记录,记录映射到对象,字段映射到对象属性。配合遵循的命名和配置惯例,能够很大程度的快速实现模型的操作,而且简洁易懂。

ActiveRecord主要思想:

  • 每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录
  • 通常表的每个字段在类中都有相应的属性
  • ActiveRecord同时负责把自己持久化(即不通过mapper,依靠实体类本身),在ActiveRecord中封装了对数据库的访问,即CURD
  • 是一种领域模型模式,封装了部分业务逻辑

1 Model

实体类继承Model类之后,能通过实体直接进行CRUD操作,而不需要进行调用Mapper
:必须存在对应的原始mapper并继承BaseMapper并且可以使用的前提下

修改Employee实体类

@Data
//继承Model类 开启AR模式
public class Employee extends Model<Employee> {
    
    

    @TableId(value = "id")
    private Integer id;
    private String empName;
    //指定useremail属性对应的列名为email
    @TableField(value = "email")
    private String useremail;
    private String gender;
    private Integer age;   
    //重写pkVal方法,返回主键
    @Override
    protected Serializable pkVal()
    {
    
    
        return this.id;
    }
}

2 insert

public class ARTest {
    
    
    private ApplicationContext applicationContext =
            new ClassPathXmlApplicationContext("applicationContext.xml");
    @Test
    public void testinsert()
    {
    
    
        Employee employee = new Employee();
        employee.setEmpName("百战程序员");
        employee.setUseremail("[email protected]");
        employee.setAge(3);
        employee.setGender("m");
        //使用AR的insert方法,将实体类自身插入数据库
        employee.insert();
    }
}

3 update

    @Test
    public void testupdate()
    {
    
    
        //创建实体类对象
        Employee employee = new Employee();
        employee.setId(15);
        employee.setEmpName("北京尚学堂");
        employee.setUseremail("[email protected]");
        //使用AR的updateByid,实体类对象将自身更新
        employee.updateById();
    }

4 delete

  • deleteById根据id删除自身
    @Test
    public void testdel()
    {
    
    
        //创建实体类对象
        Employee employee = new Employee();
//        employee.setId(15);
//        //通过AR的deletebyid方法 将实体类自身删除
//        employee.deleteById();
        //通过AR的delete方法 参数是条件构造器 删除自身
        employee.delete(new QueryWrapper<Employee>()
                .like("emp_name","tom"));
    }
  • delete根据条件构造器删除
//通过AR的delete方法 参数是条件构造器 删除自身 
employee.delete(new QueryWrapper<Employee>() .like("emp_name","tom"));

5 select

  • selectById根据自身id获取数据
    @Test
    public void testselect()
    {
    
    
        //创建实体类对象
        Employee employee = new Employee();
 //       employee.setId(2);
        //通过AR的selectByid查询实体类对象
//        Employee e = employee.selectById();
//        System.out.println(e);
        //通过AR的selectAll方法查询所有数据
//        List<Employee> emps = employee.selectAll();
//        System.out.println(emps);
        //通过AR的selectList方法返回数据 参数是条件构造器
//        List<Employee> emps =
//                employee.selectList(new QueryWrapper<Employee>().like("gender","m"));
//        System.out.println(emps);
        //通过AR的selectCount方法返回结果集数量
        int count =
        employee.selectCount(new QueryWrapper<Employee>().like("emp_name","老师"));
        System.out.println("老师一共有:" + count);
    }
  • selectAll获取所有数据
//通过AR的selectAll方法查询所有数据 
List<Employee> emps = employee.selectAll();
  • selectList根据条件构造器查询
//通过AR的selectList方法返回数据 参数是条件构造器 
//查询所有性别为m的数据 
List<Employee> emps = employee.selectList(new QueryWrapper<Employee>(). like("gender","m"));
  • selectCount根据条件查询结果集数量
//通过AR的selectCount方法返回结果集数量 
//查询所有老师的数量 
int count = employee.selectCount(new QueryWrapper<Employee> ().like("emp_name","老师"));

五、MyBatisPlus插件机制

1 插件概述

1、 插件机制: Mybatis 通过插件(Interceptor) 可以做到拦截四大对象相关方法的执行,根据需求,完

成相关数据的动态改变。

  • Executor
    Mybatis的内部执行器,它负责调用StatementHandler操作数据库,并把结果集通过 ResultSetHandler进行自动映射,另外,它还处理了二级缓存的操作,也可以通过插件来实现自定义的二级缓存的。
  • StatementHandler
    Mybatis直接和数据库执行sql脚本的对象。另外它也实现了Mybatis的一级缓存。这里,我们可以使用插件来实现对一级缓存的操作(禁用等等)。
  • ParameterHandler
    Mybatis实现Sql入参设置的对象。插件可以改变我们Sql的参数默认设置。
  • ResultSetHandler
    Mybatis把ResultSet集合映射成POJO的接口对象。我们可以定义插件对Mybatis的结果集自动映射进行修改。

2、 插件原理
四大对象的每个对象在创建时,都会执行interceptorChain.pluginAll(),会经过每个插件对象的 plugin()方法,目的是为当前的四大对象创建代理。代理对象就可以拦截到四大对象相关方法的执行,因为要执行四大对象的方法需要经过代理.

3、常用插件

  • 分页插件
    (com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerI nterceptor)
  • 防止全表更新与删除插件
    (com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInne rInterceptor)
  • 乐观锁插件
    (com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLocke rInnerInterceptor)

2 分页插件

com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor

分页对象使用

public class InterceporTest {
    
    
    private ApplicationContext applicationContext =
            new ClassPathXmlApplicationContext("applicationContext.xml");
    @Test
    public void testpage()
    {
    
    
        //创建实体类对象
        Employee employee = new Employee();
        //创建分页信息
        Page page = new Page(0,2);

        IPage<Employee> res = employee.selectPage(page,null);
        //从分页对象中获取记录及
        List<Employee> emps = res.getRecords();
      //  System.out.println(emps);
        //获取总共记录数
        Long total = page.getTotal();
        System.out.println("total=" + total);
        //获取当前获得了多少数据
        Long size = page.getSize();
        System.out.println("size=" + size);
        //获取一共多少页
        Long pages = page.getPages();
        System.out.println("pages=" + pages);
        //是否有上一页 是否有下一页
        Boolean previous =  page.hasPrevious();
        Boolean next = page.hasNext();
        System.out.println(previous);
        System.out.println(next);
    }
}    

3 防止全表更新与删除插件

com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor

  • 只支持 MySQL5.6.3 以上版本

  • 该插件的作用是分析 DELETE UPDATE 语句,防止小白或者恶意进行 DELETE UPDATE 全表操作

  • 只建议在开发环境中使用,不建议在生产环境使用

  • 在插件的底层 通过 SQL 语句分析命令:Explain 分析当前的 SQL 语句,根据结果集中的 Extra 列来断定当前是否全表操作。

在applicationContext.xml中注册防止全表更新与删除插件插件

<!--注册防止全表更新与删除插件 --> 
<bean class="com.baomidou.mybatisplus.extension.plugins.inner.BlockAttack InnerInterceptor"></bean>

添加该插件后,如果删除整表,则会抛出异常

   @Test
    public void testdel()
    {
    
    
        Employee employee = new Employee();
        employee.delete(null);
    }

在这里插入图片描述

4 乐观锁插件

com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor

  • 当要更新一条记录的时候,希望这条记录没有被别人更新
  • 乐观锁的实现原理:
    取出记录时,获取当前 version
    更新时,带上这个 version
    执行更新时, set version = yourVersion+1 where version = yourVersion
    如果 version 不对,就更新失败
  • @Version 用于注解实体属性,必须要有在applicationContext.xml中注册乐观锁插件
<!--注册乐观锁插件 -->
 <bean class="com.baomidou.mybatisplus.extension.plugins.inner.OptimisticL ockerInnerInterceptor"></bean>

修改Employee类,添加整型version 属性,并在该属性上面增加@Version

@Data
//继承Model类 开启AR模式
public class Employee extends Model<Employee> {
    
    

    @TableId(value = "id")
    private Integer id;
    private String empName;
    //指定useremail属性对应的列名为email
    @TableField(value = "email")
    private String useremail;
    private String gender;
    private Integer age;
    //实现乐观锁
    @Version
    private Integer version;
    //重写pkVal方法,返回主键
    @Override
    protected Serializable pkVal()
    {
    
    
        return this.id;
    }
}

给tb_employee表添加一列整型version并初始化为1
在这里插入图片描述
更新数据时会校验版本号,新旧版本号一致时,表示当前数据未被其他事务更新过,更新通
过,版本号自动+1;

   @Test
    public void testversion()
    {
    
    
        Employee employee = new Employee();
        employee.setId(2);
        employee.setEmpName("百战程序员");
        //如果版本号跟数据库一致 更新成功,版本号+1
        // 不一致 更新失败
        employee.setVersion(2);
        employee.updateById();
    }

六、MyBatisPlus进阶

1 自定义全局操作

根据 MybatisPlus 的 AbstractSqlInjector可以自定义各种你想要的 sql ,注入到全局中,相当
于自定义 Mybatisplus 自动注入的方法。

导入tb_user.sql,并创建User相关文件
在这里插入图片描述
User实体类

@Data
public class User {
    
    
    @TableId
    private Integer id;
    private String username;
    private Integer userage;
}

UserMapper类

public interface UserMapper extends BaseMapper<User> {
    
     
}

在 Mapper 接口中定义相关的 CRUD 方法

public interface UserMapper extends BaseMapper<User> {
    
     
	void deleteAll(); 
}

重写 AbstractMethod的injectMappedStatement方法,实现 Mapper 接口中方法要注入的
SQL

新建com.bzcxy.inject及在包下创建自己的AbstractMethod类(deleteAll)

public class DeleteAll extends AbstractMethod {
    
    
    @Override
    public MappedStatement injectMappedStatement
            (Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
    
    
        //定义sql语句
        String sql = "delete from " + tableInfo.getTableName();
        //方法名
        String method = "deleteAll";
        //构建sqlsource
        SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration,sql,modelClass);
        //通过addDeleteMappedStatement构建
        return this.addDeleteMappedStatement(mapperClass,method,sqlSource);
    }
}

创建自己的AbstractSqlInjector的类(MySqlInject)并重写getMethodList方法

public class MySqlInject extends AbstractSqlInjector {
    
    
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
    
    
        List<AbstractMethod> methods = new ArrayList<>();
        //添加自定义方法
        methods.add(new DeleteAll());
        return methods;
    }
}

将MySqlInject注册到全局配置中

<!--定义自定义注入器 -->
    <bean id="MySqlinjector" class="com.bzcxy.inject.MySqlInject"></bean>
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig"> 
	<property name="dbConfig" ref="DBConfig"/> 
	<!-- 自定义注入器注册到全局配置 --> 
	<property name="sqlInjector" ref="MySqlinjector"/> 
</bean>

:需要将防止全表更新与删除插件删除

直接使用deleteAll()

    @Test
    public void delall()
    {
    
    
        userMapper.deleteAll();
    }

2 逻辑删除

物理删除:从数据库中直接删除
逻辑删除:在数据库中没有被删除,而是通过一个变量来代表它被删除。

  • logicDeleteValue逻辑删除全局值
  • logicNotDeleteValue 逻辑未删除全局值
  • 在 POJO 的逻辑删除字段 添加 @TableLogic 注解

给tb_employee表添加一列整型deleted并初始化为0

修改Employee类,添加整型deleted属性,并在该属性上面增加@TableLogic

@Data
//继承Model类 开启AR模式
public class Employee extends Model<Employee> {
    
    

    @TableId(value = "id")
    private Integer id;
    private String empName;
    //指定useremail属性对应的列名为email
    @TableField(value = "email")
    private String useremail;
    private String gender;
    private Integer age;
    @Version
    private Integer version;
    //逻辑删除属性
    @TableLogic
    private Integer deleted;
   
    private Date updatetime;
    //重写pkVal方法,返回主键
    @Override
    protected Serializable pkVal()
    {
    
    
        return this.id;
    }
}

在applicationContext.xml的DBConfig配置逻辑删除全局值

 <!-- 配置DB-->
    <bean id="DBConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig">
        <!--是否使用驼峰转下划线命名,默认开启 可以省略 -->
        <property name="tableUnderline" value="true"/>
        <!--设置所有主键为自增模式 -->
        <property name="idType" value="AUTO"/>
        <!--设置表名前缀 -->
        <property name="tablePrefix" value="tb_"/>
        <!--逻辑删除全局值 逻辑删除1 逻辑未删除0 -->
        <property name="logicDeleteValue" value="1"/>
        <property name="logicNotDeleteValue" value="0"/>
        <!--注册sequence -->
        <property name="keyGenerator" ref="keyGenerator"/>
     </bean>

测试:

    @Test
    public void testlogic()
    {
    
    
//        Employee employee = new Employee();
//        employee.setId(2);
//        employee.deleteById();
        Employee employee = new Employee();
        employee.setId(2);
        Employee e = employee.selectById();
        System.out.println(e);
    }

以上代码仅仅将deleted置为1,并没有从数据库中删除

3 自动填充

3.1 概述

com.baomidou.mybatisplus.core.handlers.MetaObjectHandler

MetaObjectHandler接口是MyBatisPlus提供的的一个扩展接口,可以利用这个接口在插入或者更新数据的时候,为一些字段指定默认值。

比如:向数据库插入一条数据的时候,少不了一些向createTime、updateTime此类字段,每次插入的数据都要设置这些个值,十分繁琐,通过实现MetaObjectHandler接口重写insertFill、updateFill方法可以自动填写。

本质上 MetaObjectHandler获取对象的属性值或者是给对象的属性设置值,最终是要通过Reflector 获取到属性的对应方法的 Invoker, 最终 invoke.

3.2 实现步骤

给tb_employee表添加一列日期型(datetime)数据updatetime
在这里插入图片描述
修改Employee类,添加Date型update_Time属性

@Data
//继承Model类 开启AR模式
public class Employee extends Model<Employee> {
    
    

    @TableId(value = "id")
    private Integer id;
    private String empName;
    //指定useremail属性对应的列名为email
    @TableField(value = "email")
    private String useremail;
    private String gender;
    private Integer age;
    @Version
    private Integer version;
    //逻辑删除属性
    @TableLogic
    private Integer deleted;
    //自动填充字段
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updatetime;
    //重写pkVal方法,返回主键
    @Override
    protected Serializable pkVal()
    {
    
    
        return this.id;
    }
}

在updateTime上添加 @TableField注解并设置fill参数

//自动填充字段 
@TableField(fill = FieldFill.INSERT_UPDATE) 
private Date updatetime;

填充策略:
在这里插入图片描述
创建com.bzcxy.handler包,并实现继承MetaObjectHandler接口的类(MyMetaObjectHandler),重写insertFill和updateFill方法

public class MyMetaObjectHandler implements MetaObjectHandler {
    
    
    @Override
    public void insertFill(MetaObject metaObject) {
    
    
        //自动填充逻辑
        
    }

    @Override
    public void updateFill(MetaObject metaObject) {
    
    
        //自动填充逻辑
       
    }
}

将MyMetaObjectHandler类注册到GlobalConfig中

 <!--定义自定义注入器 -->
    <bean id="MySqlinjector" class="com.bzcxy.inject.MySqlInject"></bean>
  <!-- 全局配置策略-->
    <bean id="globalconfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
        <property name="dbConfig" ref="DBConfig"/>
       <!-- <property name="sqlInjector" ref="MySqlinjector"/> -->
        <property name="metaObjectHandler" ref="MyMetaObjectHandler"/>
    </bean>

重写insertFill和updateFill填充逻辑,每次执行update和insert时,都更新当前时间

public class MyMetaObjectHandler implements MetaObjectHandler {
    
    
    @Override
    public void insertFill(MetaObject metaObject) {
    
    
        //自动填充逻辑
        //通过metaObject来获取需要被填充字段的值 updatetime
        Object fieldvalue = this.getFieldValByName("updatetime",metaObject);
        if (fieldvalue == null)
        {
    
    
            //获取当前时间
            Date now = new Date();
            //将当前时间赋值给fieldvalue
            this.setFieldValByName("updatetime",now,metaObject);
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
    
    
        //自动填充逻辑
        //通过metaObject来获取需要被填充字段的值 updatetime
        Object fieldvalue = this.getFieldValByName("updatetime",metaObject);
        if (fieldvalue == null)
        {
    
    
            //获取当前时间
            Date now = new Date();
            //将当前时间赋值给fieldvalue
            this.setFieldValByName("updatetime",now,metaObject);
        }
    }
}

4 代码生成器

4.1 概述

  • MP 代码生成器提供了大量的自定义设置,生成的代码完全能够满足各类型的需求

  • MP 的代码生成器 和 Mybatis MBG 代码生成器:
    MP 的代码生成器都是基于 java 代码来生成。MBG 基于 xml 文件进行代码生成

    MBG 的代码生成器可生成: 实体类、Mapper 接口、Mapper 映射文件

    MP 的代码生成器可生成: 实体类(可以选择是否支持 AR)、Mapper 接口、Mapper 映射文件、 Service 层、Controller 层

4.2 使用步骤

MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关
依赖

代码生成器依赖

<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
        </dependency>

模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl,可以选择自己熟悉的模板引擎,

如果不满足要求,可以采用自定义模板引擎。

 <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.2</version>
        </dependency>

1.全局配置

public class GenratorTest {
    
    
    @Test
    public void test()
    {
    
    
        //1.全局配置
        GlobalConfig config = new GlobalConfig();
        config.setActiveRecord(true)//是否开启AR模式
              .setAuthor("zhangsihang")//设置作者
              .setOutputDir(System.getProperty("user.dir")+"/src/main/java")//设置输出目录
              .setFileOverride(true)//是否文件覆盖
              .setOpen(false)//生成后是否打开资源管理器(文件夹)
              .setIdType(IdType.AUTO)//主键策略
              .setBaseResultMap(true);//是否生成基本的sql映射文件
	}
}

2.数据源配置

//2.数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL)//设置数据源为mysql
                        .setUrl("jdbc:mysql://localhost:3306/baizhan")//设置url
                        .setDriverName("com.mysql.jdbc.Driver")//设置驱动
                        .setUsername("root")
                        .setPassword("root");

3.策略配置

//3.策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setInclude("tb_employee")//指定要映射的数据表,可以有多个
                      .setNaming(NamingStrategy.underline_to_camel)// 命名规则下划线转驼峰
                      .setColumnNaming(NamingStrategy.underline_to_camel)//列名规则
                      .setEntityLombokModel(true)//是否生成lombok注解
                      .setTablePrefix("tb_");//设置表名前缀

4.包名配置

//4.包配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.bzcxy.generator")//设置根包名
                     .setMapper("mapper")//mapper接口位置
                     .setEntity("pojo")//pojo位置
                     .setController("controller")//控制器位置
                     .setService("service")//service位置
                     .setXml("mapper");//映射文件页在mapper中

5.整合配置

 //5.整合配置
        AutoGenerator autoGenerator = new AutoGenerator();
        autoGenerator.setGlobalConfig(config);
        autoGenerator.setDataSource(dataSourceConfig);
        autoGenerator.setStrategy(strategyConfig);
        autoGenerator.setPackageInfo(packageConfig);
        autoGenerator.execute();

6.执行生成

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;

public class GenratorTest {
    
    
    @Test
    public void test()
    {
    
    
        //1.全局配置
        GlobalConfig config = new GlobalConfig();
        config.setActiveRecord(true)//是否开启AR模式
              .setAuthor("zhangsihang")//设置作者
              .setOutputDir(System.getProperty("user.dir")+"/src/main/java")//设置输出目录
              .setFileOverride(true)//是否文件覆盖
              .setOpen(false)//生成后是否打开资源管理器(文件夹)
              .setIdType(IdType.AUTO)//主键策略
              .setBaseResultMap(true);//是否生成基本的sql映射文件
        //2.数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL)//设置数据源为mysql
                        .setUrl("jdbc:mysql://localhost:3306/baizhan")//设置url
                        .setDriverName("com.mysql.jdbc.Driver")//设置驱动
                        .setUsername("root")
                        .setPassword("root");
        //3.策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setInclude("tb_employee")//指定要映射的数据表,可以有多个
                      .setNaming(NamingStrategy.underline_to_camel)// 命名规则下划线转驼峰
                      .setColumnNaming(NamingStrategy.underline_to_camel)//列名规则
                      .setEntityLombokModel(true)//是否生成lombok注解
                      .setTablePrefix("tb_");//设置表名前缀
        //4.包配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.bzcxy.generator")//设置根包名
                     .setMapper("mapper")//mapper接口位置
                     .setEntity("pojo")//pojo位置
                     .setController("controller")//控制器位置
                     .setService("service")//service位置
                     .setXml("mapper");//映射文件页在mapper中

        //5.整合配置
        AutoGenerator autoGenerator = new AutoGenerator();
        autoGenerator.setGlobalConfig(config);
        autoGenerator.setDataSource(dataSourceConfig);
        autoGenerator.setStrategy(strategyConfig);
        autoGenerator.setPackageInfo(packageConfig);
        autoGenerator.execute();
    }
}

5 Oracle主键策略

MySQL: 支持主键自增。 IdType.Auto

Oracle: 序列(Sequence)

添加maven依赖

<dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <version>19.8.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.oracle.database.nls</groupId>
            <artifactId>orai18n</artifactId>
            <version>21.1.0.0</version>
        </dependency>

在db.properties中添加Oracle的连接信息

orcldriver=oracle.jdbc.OracleDriver
orclurl=jdbc:oracle:thin:@localhost:1521:orcl
orclusername=system
orclpassword=root

修改applicationContext.xml数据源为oracle

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> 
	<!-- 基本属性 url、user、password--> 
	<property name="driverClassName" value="${orcldriver}"> </property> 
	<property name="url" value="${orclurl}"/> 
	<property name="username" value="${orclusername}"/> 
	<property name="password" value="${orclpassword}"/> 
</bean>

在oracle中新建一个tb_useroracle表

Create table tb_useroracle( 
	id number(11) primary key, 
	name varchar(255) 
);

同时新建一个序列(Sequence)

create sequence seq_useroracle start with 100 increment by 1;

Sequence的常用操作

//查询序列的下一个值 dual代表虚表 
select seq_useroracle.nextval from dual 
//查询序列的当前值 
select seq_useroracle.currval from dual

DBConfig中注册Sequence

<!--配置Oracle主键Sequence --> 
<bean id="keyGenerator" class="com.baomidou.mybatisplus.extension.incrementer.OracleKeyGene rator"/> 
<bean id="DBConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig"> 
	<!-- 表名是否使用驼峰转下划线命名,只对表名生效 默认开启 可以不用添加--> 
	<property name="tableUnderline" value="true"/> 
	<!-- 设置所有主键为自增模式--> 
	<property name="idType" value="AUTO"/> 
	<!-- 设置表明前缀--> 
	<property name="tablePrefix" value="tb_"/> 
	<!-- 逻辑删除 配置删除的值为1 未删除的值为0--> 
	<property name="logicDeleteValue" value="1"/> 
	<property name="logicNotDeleteValue" value="0"/> 
	<!--注册Sequence --> 
	<property name="keyGenerator" ref="keyGenerator"/> 
</bean>

创建Useroracle实体类并配置主键 Sequence

在类上加@KeySequence注解

给主键配置@TableId(type = IdType.INPUT)

@KeySequence(value=”序列名”)

@Data 
@KeySequence(value = "seq_useroracle") public class Useroracle {
    
     
	@TableId(type = IdType.INPUT) 
	private Integer id; 
	private String name; 
}

创建UseroracleMapper继承BaseMapper

public interface UseroracleMapper extends BaseMapper<User> {
    
     
}

测试

public class SequenceTest {
    
    
    private ApplicationContext applicationContext =
            new ClassPathXmlApplicationContext("applicationContext.xml");
    UseroracleMapper useroracleMapper =
            applicationContext.getBean("useroracleMapper",UseroracleMapper.class);
    @Test
    public void test()
    {
    
    
        Useroracle useroracle = new Useroracle();
        useroracle.setName("百战1");
        useroracleMapper.insert(useroracle);
    }
}

向Oracle中插入数据
可以将@keySequence 定义在父类中,可实现多个子类对应的多个表公用一个 Sequence父类

@KeySequence(value = "seq_useroracle") 
public class ParentSequence {
    
    
 }

子类继承即可公用Sequence

@Data 
public class Useroracle extends ParentSequence{
    
     
	@TableId(type = IdType.INPUT) 
	private Integer id; 
	private String name; 
}

6 MyBatisX快速开发插件

MybatisX 辅助 idea 快速开发插件,极高提升开发效率。

可以实现 Java 与 xml 跳转,根据 Mapper 接口中的方法自动生成 xml 结构.

安装MybatisX :

  • 搜索安装
    File -> Settings -> Plugins->Marketplace 输入 MybatisX 安装下载
    在这里插入图片描述
  • 手动安装
    File -> Settings -> Plugins-> Install plugin from disk 找到MybatisX 安装包进行安装
    在这里插入图片描述
    :需要到https://plugins.jetbrains.com/搜索跟自己IDEA对应版本的MybatisX插件安装完成后需要重启IDEA
    给EmployeeMapper编写一个EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<mapper namespace="com.bzcxy.mapper.EmployeeMapper"> 
</mapper>

通过Generate statement在EmployeeMapper.xml自动生成xml结构
在这里插入图片描述
可以通过(Ctrl+右键+方法名)在xml和接口之间切换
练习源码:https://gitee.com/cutelili/my-batisplus
Git应用与实战

猜你喜欢

转载自blog.csdn.net/qq_42588990/article/details/120761803
今日推荐