【201806版本MyBatis-Plus尚—01】2.3版本,整合spring,CRUD,主键策略,原理分析,条件构造器,活动记录。

1. 介绍

MyBatis-Plus(简称 MP),是一个 MyBatis 的增强工具包,只做增强不做改变. 为简化开
发工作、提高生产率而生

https://baomidou.com/

  • 文档地址

https://baomidou.com/pages/24112f/

版本信息

  • 2022 02 14 最新 稳定版 3.5.1
  • 2022 05 左右更新为 3.5.2
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.5.1</version>
</dependency>

Latest Version: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Nl3elfG-1659401055681)(https://img.shields.io/maven-central/v/com.baomidou/mybatis-plus.svg)]

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>Latest Version</version>
</dependency>
  • 教程中为:2.3,18年6月20

特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式
  • 支持自定义全局通用操作
  • 内置代码生成器
  • 内置分页插件
  • 分页插件支持多种数据库
  • 内置性能分析插件
  • 内置全局拦截插件

2. 整合MP

1. 创建测试库

-- 创建库
CREATE DATABASE mp;

-- 使用库
USE mp;

-- 创建表
CREATE TABLE tbl_employee(
id INT(11) PRIMARY KEY AUTO_INCREMENT,
last_name VARCHAR(50),
email VARCHAR(50),
gender CHAR(1),
age int
);

INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom','tom@atguigu.com',1,22);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Jerry','jerry@atguigu.com',0,25);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Black','black@atguigu.com',1,30);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('White','white@atguigu.com',0,35);

实体类

  • 注意使用 包装类型,int 默认值为0,boolean 默认值为 false
public class Employee {
    private Integer id ;
    private String lastName;
    private String email ;
    private Integer gender ;
    private Integer age ;
    //get set toString
}

2. 依赖配置

MP、 Spring、连接池、 Junit、 Mysql 驱动等依赖

  • MyBatis 和 Mybatis-Spring 依赖请勿加入项目配置,pm会自动维护
        <!-- mp 依赖 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>2.3</version>
        </dependency>

        <!--junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.9</version>
        </dependency>

        <!-- log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!-- c3p0 -->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>

        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.37</version>
        </dependency>

        <!-- spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.3.10.RELEASE</version>
        </dependency>

3. MyBatis 和 Spring 整合

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	
</configuration>

log4j.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
 
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
 
 <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> //std out 
   <param name="Encoding" value="UTF-8" />
   <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n" />
   </layout>
 </appender>
    
 <logger name="java.sql">
   <level value="debug" /> //sql下 debug
 </logger>
 <logger name="org.apache.ibatis"> //ibatis 下 info
   <level value="info" />
 </logger>
    
 <root>
   <level value="debug" />
   <appender-ref ref="STDOUT" /> //打印debug
 </root>
</log4j:configuration>

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mp
jdbc.username=root
jdbc.password=1234

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
	xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
	
	
	<!-- 数据源 -->
	<context:property-placeholder location="classpath:db.properties"/>
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driver}"></property>
		<property name="jdbcUrl" value="${jdbc.url}"></property>
		<property name="user" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>
	
	<!-- 事务管理器 -->
	<bean id="dataSourceTransactionManager" 
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	<!-- 基于注解的事务管理 -->
	<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
	
	
	<!--  配置SqlSessionFactoryBean 
		Mybatis提供的: org.mybatis.spring.SqlSessionFactoryBean 
		MP提供的:如下
	 -->
	<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
		<!-- 数据源 -->
		<property name="dataSource" ref="dataSource"></property>
        <!-- mybatis-config -->
		<property name="configLocation" value="classpath:mybatis-config.xml"></property>
		<!-- 别名处理 -->
		<property name="typeAliasesPackage" value="com.atguigu.mp.beans"></property>		
		
		<!-- 注入全局MP策略配置 --> 第一次讲,没有这个配置,配置在如下
		<property name="globalConfig" ref="globalConfiguration"></property>
	</bean>
    
	
	<!-- 定义MybatisPlus的全局策略配置--> 第一次讲,没有这个配置
	<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
        
		<!-- 在2.3版本以后,dbColumnUnderline 默认值就是true -->
		<property name="dbColumnUnderline" value="true"></property>
		
		<!-- 全局的主键策略 -->
		<property name="idType" value="0"></property>
		
		<!-- 全局的表前缀策略配置 ,表前缀,这个价了 类就能自动对应上 如:employee 对应表:tbl_employee--> 
		<property name="tablePrefix" value="tbl_"></property>
	</bean>
	
	<!-- 
		配置mybatis 扫描mapper接口的路径
	 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.atguigu.mp.mapper"></property>
	</bean>
	
</beans>

测试

public class TestMP {
    
	private ApplicationContext ioc = 
				new ClassPathXmlApplicationContext("applicationContext.xml");
	
	@Test
	public void testDataSource() throws Exception {
		DataSource ds  = ioc.getBean("dataSource",DataSource.class);
		System.out.println(ds);
		Connection conn = ds.getConnection();
		System.out.println(conn);
	}
	
}
// 数据源为 C3p0的
com.mchange.v2.c3p0.ComboPooledDataSource
[ identityToken -> 1hge1anaqejs9zb1tfqp6d|1ef6d34c, dataSourceName -> 1hge1anaqejs9zb1tfqp6d|1ef6d34c ]

//连接为:NewProxyConnection,新连接,嘛时候是 旧的呢
com.mchange.v2.c3p0.impl.NewProxyConnection@46cf05f7 [wrapping: com.mysql.jdbc.JDBC4Connection@5851bd4f]

整合mp

MP提供的:com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean

3. CRUD

CRUD(创建、读取、更新、删除)和

ACID(添加、变更、查询、删除)的首字母缩写来表示

事务四大特征:原子性(Atomicity),一致性(Consistency),隔离性(Isolation),持久性(Durability

inquire
英
/ɪnˈkwaɪə(r)/
美
/ɪnˈkwaɪər/
简明 牛津 新牛津 韦氏 柯林斯 例句 百科
v.
调查,查究;询问,打听

durability 
英
/ˌdjʊərəˈbɪləti/
美
/ˌdʊrəˈbɪləti/
全球发音
简明 例句 百科
n.
持久性,耐用性

插入逻辑

1. BaseMapper

基于 Mybatis

需要编写 EmployeeMapper 接口,并手动编写 CRUD 方法
提供 EmployeeMapper.xml 映射文件,并手动编写每个方法对应的 SQL 语句.

基于 MP
只需要创建 EmployeeMapper 接口, 并继承 BaseMapper 接口.这就是使用 MP
需要完成的所有操作,甚至不需要创建 SQL 映射文件。

public interface EmployeeMapper extends BaseMapper<Employee> {
}
  • 基类 有的方法
insert
deleteById
updateById
selectById

selectOne
selectList
selectPage

2. 插入测试

	private EmployeeMapper employeeMapper = 
			ioc.getBean("employeeMapper",EmployeeMapper.class);
		//初始化Employee对象
		Employee e  = new Employee();
		e.setLastName("MP");
		e.setEmail("mp@atguigu.com");
		e.setGender(1);
		e.setAge(22);

		// insert方法在插入时, 会根据实体类的每个属性进行非空判断,只有非空的属性对应的字段才会出现到SQL语句中
		Integer result = employeeMapper.insert(e);  

        //获取当前数据在数据库中的主键值
        Integer key = employee.getId();
        System.out.println("key:" + key);
ID 指定类型
	/*
	 * @TableId:
	 * 	 value: 指定表中的主键列的列名, 如果实体属性名与列名一致,可以省略不指定. 
	 *   type: 指定主键策略. 
	 */
	//@TableId(value="id" , type =IdType.AUTO)
	private Integer id ;
主键策略
  • 老版本

IdType.

  • AUTO
  • INPUT
  • ID_WORKER, worker 全局唯一ID
  • UUID
IdType类源码
public enum IdType {
    AUTO(0, "数据库ID自增"), 
    INPUT(1, "用户输入ID"),

    /* 以下2种类型、只有当插入对象ID 为空,才自动填充。 */
    ID_WORKER(2, "全局唯一ID"), 
    
    UUID(3, "全局唯一ID"), 
    NONE(4, "该类型为未设置主键类型"),
    ID_WORKER_STR(5, "字符串全局唯一ID");

    private final int key;
    private final String desc;


    /**
     * <p>
     * 主键策略 (默认 ID_WORKER)
     * </p>
     *
     * @param idType ID 策略类型
     * @return
     */
    public static IdType getIdType(int idType) {
        //枚举 转为 数组
        IdType[] its = IdType.values();
        //遍历,取出所有的 枚举,获取 枚举的key
        for (IdType it : its) {
            //如果枚举的key == 输入的值
            if (it.getKey() == idType) {
                //返回当前枚举
                return it;
            }
        }
        return ID_WORKER;
    }
    
}
  • 新版本

主键生成策略必须使用 INPUT

支持父类定义 @KeySequence 子类继承使用

支持主键类型指定(3.3.0 开始自动识别主键类型)

内置支持:

  • DB2 KeyGenerator
  • H2 加入上面的后缀
  • Kingbase
  • Oracle
  • Postgre

如果内置支持不满足你的需求,可实现 IKeyGenerator 接口来进行扩展.

表名对应
/*
 * MybatisPlus会默认使用实体类的类名到数据中找对应的表. 
 */
@TableName(value="tbl_employee")
public class Employee { }
获取主键值
  • MyBatis

        Integer  insertEmployee(Employee employee );
    	//指定,这个类的 Id去接收
    	//   <insert useGeneratedKeys="true" keyProperty="id" > SQL...</insert>
    
        //获取当前数据在数据库中的主键值,mp是直接获取
        Integer key = employee.getId();
        System.out.println("key:" + key);
全局策略配置
  • 配置:如上 文件 applicationContext

  • java类,lastName ,可以自动对应表字段 last_name

  • 相当于Mybaits的配置: mapUnderscoreToCamelCase

    • mp为:dbColumnUnderline
配置:com.baomidou.mybatisplus.entity.GlobalConfiguration		

<property name="idType" value="0"></property>  和 type =IdType.AUTO,相同
TableField
	@TableField(value = "last_name") //库里为 last_name
	private String  lastName; 

	@TableField(exist=false) //在库里 不存在
	private Double salary ; 
插入 全字段
		// insert方法在插入时, 会根据实体类的每个属性进行非空判断,只有非空的属性对应的字段才会出现到SQL语句中

		//insertAllColumn方法在插入时, 不管属性是否非空, 属性所对应的字段都会出现到SQL语句中. 
        Integer result = employeeMapper.insertAllColumn(employee);
INSERT INTO tbl_employee ( last_name,email,gender,age ) VALUES ( ?,?,?,? )  -- 没有值的插入null

3. 更新操作

  • 局部更新ID
  • 全局更新
		//初始化修改对象
		Employee employee = new Employee();
		employee.setId(7);
		employee.setLastName("小泽老师");
		employee.setEmail("xz@sina.com");
		employee.setGender(0);
		//employee.setAge(33);
		
		//判断 空,如果 对象的值,不存在,不会更新。
		Integer result = employeeMapper.updateById(employee);

		//这条数据,全表数据更新,对象的值 不存在,就更新为null,擦除更新
		Integer result = employeeMapper.updateAllColumnById(employee);

4. 查询

  • ID
  • 单个
  • ID列表
  • 条件
  • 分页
		//1. 通过id查询
		Employee employee = employeeMapper.selectById(7);
		System.out.println(employee);
		
		//2. 通过多个列进行查询    id  +  lastName
		Employee  employee = new Employee();
		//employee.setId(7);
		employee.setLastName("小泽老师");
		employee.setGender(0);
		
		Employee result = employeeMapper.selectOne(employee);
		System.out.println("result: " +result );
		//3. 通过多个id进行查询    <foreach>
		List<Integer> idList = new ArrayList<>();
		idList.add(4);
		idList.add(5);
		List<Employee> emps = employeeMapper.selectBatchIds(idList);
SELECT id,last_name AS lastName,email,gender,age FROM tbl_employee WHERE id IN ( ? , ? , ? , ? )   
4(Integer), 5(Integer), 6(Integer), 7(Integer)  
		//4. 通过Map封装条件查询
		Map<String,Object> columnMap = new HashMap<>();
		columnMap.put("last_name", "Tom");//传递 数据库 里的字段
		columnMap.put("gender", 1);
		
		List<Employee> emps = employeeMapper.selectByMap(columnMap);
		System.out.println(emps);

分页

  • 这里是 使用 内存中的分页 (查出所有,取第几页,没有用limit),推荐 pageHelper
Page<T> extends Pagination

public class Pagination extends RowBounds implements Serializable {}
		//5. 分页查询
		List<Employee> emps = employeeMapper.selectPage(new Page<>(3, 2), null);
		System.out.println(emps);

5. 删除

  • 单个
  • 条件
  • ID列表
		//1 .根据id进行删除
		Integer result = employeeMapper.deleteById(13);
		System.out.println("result: " + result );
		//2. 根据 条件进行删除
		Map<String,Object> columnMap = new HashMap<>();
		columnMap.put("last_name", "MP");
		columnMap.put("email", "mp@atguigu.com");
		Integer result = employeeMapper.deleteByMap(columnMap);
		System.out.println("result: " + result );
		
		//3. 批量删除
		List<Integer> idList = new ArrayList<>();
		idList.add(3);
		idList.add(4);
		idList.add(5);
		Integer result = employeeMapper.deleteBatchIds(idList);
		System.out.println("result: " + result );

6. 原理分析

  • XXMapper是代理对象,
    • 为:MapperProxy,org.apache.ibatis.binding.MapperProxy
    • mybatis做的 JDK动态代理
  • Configuration 和 MappedStatement 是MyBatis的

流程分析

Integer result = employeeMapper.deleteById(13);

2) 通过现象看到本质
A. employeeMapper 的本质 xx.MapperProxy

B. MapperProxy 中 sqlSession –>SqlSessionFactory

C. SqlSessionFacotry 中 → Configuration→ MappedStatements
每一个 mappedStatement 都表示 Mapper 接口中的一个方法与 Mapper 映射文件中的一个 SQL。

MP 在启动就会挨个分析 xxxMapper 中的方法,并且将对应的 SQL 语句处理好,
保存到 configuration 对象中的 mappedStatements 中.

D. 本质
BaseMapper,调用ISqlInjector.addMappedStatement
com.atguigu.mp.mapper.EmployeeMapper.deleteById  (JakartaCommonsLoggingImpl.java:54) 

自动注入器


/**
 * SQL 自动注入器
 * @author hubin sjy tantan
 * @Date 2016-09-09
 */
public class AutoSqlInjector implements ISqlInjector { 

        protected void injectDeleteByIdSql(boolean batch, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
        SqlMethod sqlMethod = SqlMethod.DELETE_BY_ID;
        SqlSource sqlSource;

        String sql = String.format(sqlMethod.getSql(), table.getTableName(), table.getKeyColumn(), idStr);
        sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        this.addDeleteMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource);
    }

}

//SqlMethod.DELETE_BY_ID; 具体为:
//DELETE_BY_ID("deleteById", "根据ID 删除一条数据", "<script>DELETE FROM %s WHERE %s=#{%s}</script>"),

//String.format 处理后,变成了:
//<script>DELETE FROM tbl_employee WHERE id=#{id}</script>
    
    public MappedStatement addDeleteMappedStatement(Class<?> mapperClass, String id, SqlSource sqlSource) {
        return this.addMappedStatement(mapperClass, id, sqlSource, SqlCommandType.DELETE, null, null, Integer.class,
            new NoKeyGenerator(), null, null);
    }

    public MappedStatement addMappedStatement(Class<?> mapperClass, String id, 
                                              SqlSource sqlSource,
                                              SqlCommandType sqlCommandType, 
                                              Class<?> parameterClass, 
                                              String resultMap, Class<?> resultType,
                                              KeyGenerator keyGenerator, 
                                              String keyProperty, String keyColumn) {
        
        String statementName = mapperClass.getName() + "." + id;

        //builderAssistant 做 缓存,SQL参数,查询返回的结果集 处理。
        return builderAssistant.addMappedStatement(id, sqlSource, StatementType.PREPARED, sqlCommandType, null, null, null,
            parameterClass, resultMap, resultType, null, !isSelect, isSelect, false, keyGenerator, keyProperty, keyColumn,
            configuration.getDatabaseId(), languageDriver, null);
    }


public class MapperBuilderAssistant extends BaseBuilder {
    public MappedStatement addMappedStatement(String id, xx) {
			xx

            MappedStatement statement = statementBuilder.build();
            this.configuration.addMappedStatement(statement);
            return statement;
        }
    }
}

MappedStatements

C. 的说明:比如MappedStatements 找到倒数第二个是:selectById

XXMapperProxy → sqlSession → SqlSessionFactory → Configuration → MappedStatements →

selectById → value → sqlSource → sqlSource → sql 里面有:Configuration对象

sqlSource是属性,对象里面 又有 sqlSource,里面是对象:有 sql,parameterMappings,configuration
(又有这52个SQL,和 外层是同一对象,递归的对象,K猪)
可找到SQL如下:
SELECT id,last_name AS lastName,email,gender,age FROM tbl_employee WHERE id=?
  • Configuration 实际就是 MybatisConfiguration
  • org.apache.ibatis.mapping.MappedStatement

重要对象

Configuration: MyBatis 或者 MP 全局配置对象

MappedStatement:一个 MappedStatement 对象对应 Mapper 配置文件中的一个
select/update/insert/delete 节点,主要描述的是一条 SQL 语句

SqlMethod : 枚举对象 , MP 支持的 SQL 方法

TableInfo: 数据库表反射信息 ,可以获取到数据库表相关的信息

SqlSource: SQL 语句处理对象

MapperBuilderAssistant: 用于缓存、 SQL 参数、查询方剂结果集处理等.
通过 MapperBuilderAssistant 将每一个 mappedStatement
添加到 configuration 中的 mappedstatements 中

4. 条件构造器

年龄在 18~50 之间性别为男且
姓名为 xx 的所有用户

MyBatis : 需要在 SQL 映射文件中编写带条件查询的 SQL,并基于 PageHelper 插件完成

往往需要我们做很多重复单调的工作。

两种方式

MP: 依旧不用编写 SQL 语句, MP 提供了功能强大的条件构造器 EntityWrapper

Wrapper

  • Condition
  • EntityWrapper
public class EntityWrapper<T> extends Wrapper<T> {
    /**
     * SQL 片段
     */
    @Override
    public String getSqlSegment() {}
}
  1. Mybatis-Plus

通过 EntityWrapper

  • (简称 EW, MP 封装的一个查询条件构造器)

  • 或者 Condition(与 EW 类似)

来让用户自由的构建查询条件,简单便捷,没有额外的负担,
能够有效提高开发效率

  1. 实体包装器, 主要用于处理 sql 拼接,排序,实体参数查询等

  2. 注意: 使用的是数据库字段,不是 Java 属性!

条件参数说明

  • set Sql Select

  • where

  • and

    • andNew 是:and (字段=值)
  • or

    • orNew
  • eq

    • allEq:基于map内容等于
    • ne:不等于
  • gt:大于>

    • ge:大于等于
  • lt:小于

    • le:小于等于
  • like

    • notLike
  • in

    • notIn
  • isNull

    • isNotNull
  • groupBy

    • having
  • orderBy

    • orderAsc
    • orderDesc
  • existe:exists条件语句

    • notExists
  • between

    • notBetween
  • addFilter:自由拼接SQL

  • last:拼接在 最后 last(“limit 1”)

实例

between 和 equ

		//我们需要分页查询tbl_employee表中,年龄在18~50之间且性别为男且姓名为Tom的所有用户
		
		//当前为 第一页,每页显示2条
		List<Employee> emps =employeeMapper.selectPage(new Page<Employee>(1, 2),
					new EntityWrapper<Employee>()
					.between("age", 18, 50)
					.eq("gender", 1)
					.eq("last_name", "Tom")
				);
		System.out.println(emps);
SELECT id,last_name AS lastName,email,gender,age 
FROM tbl_employee 
WHERE (age BETWEEN ? AND ? AND gender = ? AND last_name = ?)

Parameters: 18(Integer), 50(Integer), 1(Integer), Tom(String)
		// 查询tbl_employee表中, 性别为女并且名字中带有"老师" 或者  邮箱中带有"a"
		
		List<Employee> emps = employeeMapper.selectList(
				new EntityWrapper<Employee>()
				.eq("gender", 0)
				.like("last_name", "老师")
				//.or()    // SQL: (gender = ? AND last_name LIKE ? OR email LIKE ?)    
				.orNew()   // SQL: (gender = ? AND last_name LIKE ?) OR (email LIKE ?) 
				.like("email", "a")
				);
		System.out.println(emps);

条件更新

		Employee employee = new Employee();
		employee.setLastName("王老师");
		employee.setEmail("cls@sina.com");
		employee.setGender(0);
		
		employeeMapper.update(employee, 
					new EntityWrapper<Employee>()
					.eq("last_name", "Tom")
					.eq("age", 44)
					);
UPDATE tbl_employee SET last_name=?, email=?, gender=? 

WHERE (last_name = ? AND age = ?)

 Parameters: 王老师(String), cls@sina.com(String), 0(Integer), Tom(String), 44(Integer)

条件删除

		employeeMapper.delete(
					new EntityWrapper<Employee>()
					.eq("last_name", "Tom")
					.eq("age", 22)
				);
DELETE FROM tbl_employee WHERE (last_name = ? AND age = ?) 

orderBy 和 last

		// 查询性别为女的, 根据age进行排序(asc/desc), 简单分页
		List<Employee> emps  = employeeMapper.selectList(
				new EntityWrapper<Employee>()
				.eq("gender", 0)
				.orderBy("age")
				//.orderDesc(Arrays.asList(new String [] {"age"}))
				.last("desc limit 1,3")
				);
		System.out.println(emps);

Condition

		List<Employee > emps = employeeMapper.selectPage(
							new Page<Employee>(1,2),
							Condition.create()
							.between("age", 18, 50)
							.eq("gender", "1")
							.eq("last_name", "Tom")

							);

		System.out.println(emps);

MP: EntityWrapper Condition 条件构造器
MyBatis MBG : xxxExample→Criteria : QBC( Query By Criteria)

Hibernate 、 通用 Mapper

5. 活动记录

ctive Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的
一个表,而模型类的一个实例对应表中的一行记录。

ActiveRecord 一直广受动态语言( PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言,
对于 ActiveRecord 往往只能感叹其优雅,所以 MP 也在 AR 道路上进行了一定的探索

使用

  1. 仅仅需要让实体类继承 Model 类且实现主键指定方法,即可开启 AR 之旅
public class Employee extends Model<Employee>{

	@Override
	protected Serializable pkVal() {
		return this.id;
	}
}

插入 和 更新

		Employee e = new Employee();
		e.setLastName("宋老师");
		e.setEmail("sls@atguigu.com");
		e.setGender(1);
		e.setAge(35);
		
		boolean result = e.insert();
		System.out.println("result:" +result );


		Employee employee = new Employee();
		employee.setId(20);
		employee.setAge(36);
		
		boolean result = employee.updateById();
		System.out.println("result:" +result );
INSERT INTO 
    tbl_employee ( last_name, email, gender, age ) 
    VALUES ( ?, ?, ?, ? )
    
Parameters: 宋老师(String), sls@atguigu.com(String), 1(Integer), 35(Integer)
    
    
UPDATE tbl_employee 
    SET last_name=?, email=?, gender=?, age=? 
    WHERE id=? 
    
Parameters: 宋老是(String), sls@atguigu.com(String), 1(Integer), 36(Integer), 20(Integer)  (JakartaCommonsLoggingImpl.java:54) 

查询

		Employee employee = new Employee();
		
		//Employee result = employee.selectById(14);

		employee.setId(14);
		Employee result = employee.selectById();
		System.out.println(result );
		
		
		List<Employee> emps = employee.selectAll();
		System.out.println(emps);
		

		List<Employee > emps= 
				employee.selectList(new EntityWrapper<Employee>().like("last_name", "老师"));
		System.out.println(emps);
		
		Integer result = employee.selectCount(new EntityWrapper<Employee>().eq("gender", 0));

		System.out.println("result: " +result );
SELECT id,last_name AS lastName,email,gender,age 
FROM tbl_employee 
WHERE (last_name LIKE ?)  

 %老师%(String)
 
 
SELECT COUNT(1) FROM tbl_employee WHERE (gender = ?)  
0(Integer)

删除

		Employee employee = new Employee();
		//boolean result = employee.deleteById(2);

//		employee.setId(2);
//		boolean result = employee.deleteById();
// 删除0条,没有删除,返回true
//		System.out.println("result:" +result );
		
		
		boolean result = employee.delete(new EntityWrapper<Employee>().like("last_name", "小"));
		System.out.println(result );

分页

		
		Employee employee = new Employee();
		
		Page<Employee> page = employee.selectPage(new Page<>(1, 1), 
				new EntityWrapper<Employee>().like("last_name", "老"));
		List<Employee> emps = page.getRecords();
		System.out.println(emps);

源码

		boolean result = employee.delete(new EntityWrapper<Employee>().like("last_name", "小"));	
    @Transactional
    public boolean delete(Wrapper wrapper) {
        Map<String, Object> map = new HashMap<>();
        map.put("ew", wrapper);
        return SqlHelper.delBool(sqlSession().delete(sqlStatement(SqlMethod.DELETE), map));
    }


    /**
     * <p>
     * 获取Session 默认自动提交
     * <p/>
     */
    protected SqlSession sqlSession() {
        return SqlHelper.sqlSession(getClass());
    }
  1. AR 模式提供了一种更加便捷的方式实现 CRUD 操作,其本质还是调用的 Mybatis 对
    应的方法,类似于语法糖

语法糖是指计算机语言中添加的某种语法,这种语法对原本语言的功能并没有影响.
可以更方便开发者使用,可以避免出错的机会,让程序可读性更好.

  1. 到此,我们简单领略了 Mybatis-Plus 的魅力与高效率,值得注意的一点是:我们提供
    了强大的代码生成器,可以快速生成各类代码,真正的做到了即开即用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值