MyBatis-Plus(Spring)

1.MyBatis Plus简介

MyBatis-Plus 简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

2.MyBatis Plus特性

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

3.支持的数据库

任何能使用 mybatis 进行 crud, 并且支持标准 sql 的数据库

4.快速入门

4.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@qq.com',1,22);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Jerry','jerry@qq.com',0,25);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Black','black@qq.com',1,30);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('White','white@qq.com',0,35);

4.2 创建JavaBean

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
    private Integer id;
    private String lastName;
    private String email;
    private Integer gender;
    private Integer age;
}

4.3 依赖配置

Mybatis 及 Mybatis-Spring 依赖请勿加入项目配置,以免引起版本冲突,Mybatis-Plus 会自动帮你维护!

	<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.19.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.19.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.0.19.RELEASE</version>
        </dependency>
        <!--mybatis plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.4.1</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>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.23</version>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.36</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
    </dependencies>

4.4 MyBatis配置文件: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>

4.5 日志配置文件: log4j.properties

log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG

4.6 数据库配置文件:jdbc.properties

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

4.7 spring配置文件: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 -->
	<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- 数据源 -->
		<property name="dataSource" ref="dataSource"></property>
		<property name="configLocation" value="classpath:mybatis-config.xml"></property>
		<!-- 别名处理 -->
		<property name="typeAliasesPackage" value="com.atguigu.mp.beans"></property>
	</bean>
	<!--配置 mybatis 扫描 mapper 接口的路径-->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="cn.edu.mp.mapper"></property>
	</bean>
</beans>

4.8 测试环境搭建

//搭建Spring测试环境
//		前提(依赖引入):1.junit 4.12以上版本  2.spring-test 与spring-context相同版本即可
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class MyTest {
}

4.9 测试环境搭建

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class MyTest {
	@Autowired
    private DataSource dataSource;

	@Test
    public void test1() throws SQLException {
        Connection connection = dataSource.getConnection();
        System.out.println("==>" + connection);
    }
}

4.10 集成MP

Mybatis-Plus 的集成非常简单,对于 Spring,我们仅仅需要把 Mybatis 自带MybatisSqlSessionFactoryBean 替换为 MP 自带的即可。

<!--applicationContext.xml-->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	<property name="typeAliasesPackage" value="cn.edu.pojo"/>
	<!--<property name="configLocation" value="classpath:mybatis-config.xml"/>-->
</bean>

4.11 配置日志

目的:查看sql语言是如何执行

<!--applicationContext.xml-->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	<property name="typeAliasesPackage" value="cn.edu.pojo"/>
	<!--<property name="configLocation" value="classpath:mybatis-config.xml"/>-->
	<property name="configuration" ref="configuration"/>
 </bean>

<!--mybatis plus日志-->
<bean id="configuration" class="com.baomidou.mybatisplus.core.MybatisConfiguration">
	<property name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
</bean>

5.MyBatis Plus自带的Mapper CRUD接口

EmployeeMapper继承BaseMapper<>
<>中实体类名

@Repository
public interface EmployeeMapper extends BaseMapper<Employee> {
}
  • 注解@TableName: 表名注解
    • 体类与数据库表对应,若表名与实体类名相同,则value不需要书写,若不一致,则需要写进表名
  • 注解@TableId:主键注解
    • value指定主键名,type指主键生成策略
    • 若实体类的属性名与表中相同,则可以省略
  • 注解@TableField:字段注解(非主键)
    • value指定字段名,若实体类属性与表名相同,或符合驼峰规则都可省略
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "tbl_employee")    
public class Employee {
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @TableField("last_name")
    private String lastName;
    private String email;
    private Integer gender;
    private Integer age;

5.1 插入操作

  • int insert(T entity); // 插入一条记录,并实现主键回填
	@Test
    public void testCommonInsert() {
        Employee employee = new Employee();
        employee.setLastName("黄药师");
        employee.setEmail("hys@qq.com");
        employee.setGender(1);
        int result = employeeMapper.insert(employee);
        System.out.println("==>" + result);
        System.out.println(employee.getId())
    }

5.2 更新操作

  • int updateById(@Param(Constants.ENTITY) T entity); // 根据 ID 修改
	@Test
    public void testUpdate() {
        Employee employee = new Employee();
        employee.setId(1);
        employee.setLastName("杨康");
        employee.setGender(1);
        int result = employeeMapper.updateById(employee);
        System.out.println("==>" + result);
    }

5.3 查询操作

-T selectById(Serializable id); //根据 ID 查询

  • List selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); //查询(根据ID 批量查询
  • List selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); //查询(根据 columnMap 条件)
  • List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper); // 根据 entity 条件,查询全部记录
@Test
    public void testQuery() {
/*
        //1.根据id查询
        Employee employee = employeeMapper.selectById(1);
        System.out.println(employee);
*/
/*
        //2.查询(根据ID 批量查询)
        List<Integer> idList = new ArrayList<>();
        for (int i = 1; i < 5; i++) {
            idList.add(i);
        }
        List<Employee> employeeList = employeeMapper.selectBatchIds(idList);
        employeeList.forEach((temp) -> {
            System.out.println(temp);
        });
*/
/*
        //3.查询(根据 columnMap 条件)
        HashMap<String, Object> columnMap = new HashMap<>();
        columnMap.put("gender", "0");
        List<Employee> employees = employeeMapper.selectByMap(columnMap);
        employees.forEach((temp) -> {
            System.out.println(temp);
        });
*/
        //4.
        List<Employee> employees = employeeMapper.selectList(null);
        employees.forEach((temp) -> {
            System.out.println(temp);
        });
    }

5.4 删除操作

  • int deleteById(Serializable id); //根据 ID 删除
  • int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); //删除(根据ID 批量删除)
  • int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); //根据 columnMap 条件,删除记录
@Test
    public void testDelete() {
/*

        //1.根据id批量删除
        List<Integer> ids = new ArrayList<>();
        for (int i = 8; i < 31; i++) {
            ids.add(i);
        }
        int result = employeeMapper.deleteBatchIds(ids);
        System.out.println(result);
*/


        //2.根据id删除
        int result = employeeMapper.deleteById(1);
        System.out.println(result);
/*
        //3.根据 columnMap 条件,删除记录
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("email", "ouyangfeng@.com");
        columnMap.put("gender", "1");
        int result = employeeMapper.deleteByMap(columnMap);
        System.out.println(result);
*/
    }

6.扩展

6.1自动填充功能

目的:创建时间、修改时间实现自动更新,而非手动更新

方法一:数据库实现(不推荐)

  • 在数据库中创建create_time,update_time字段
  • 设置默认值:CURRENT_TIMESTAMP
  • 在实体类Employee类中添加属性createTime,updateTime

方法二:MyBatis Plus实现

1).在实体类Employee类中添加属性createTime,updateTime及注解

	//注解@TableField():字段自动填充策略
	@TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

2).编写处理器来处理这个注解即可!

public class MyMetaObjectHandler implements MetaObjectHandler {
    //插入填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        System.out.println("==>自动填充策略:insertFill");
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }
    // 更新时填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        System.out.println("==>自动填充策略:updateFill");
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }
}

3).添加到配置文件中

<!--applicationContext.xml-->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	<property name="typeAliasesPackage" value="cn.edu.pojo"/>
	<!--<property name="configLocation" value="classpath:mybatis-config.xml"/>-->
	<property name="configuration" ref="configuration"/>
	<property name="globalConfig" ref="globalConfig"/>
</bean>

<!--MyBatisPlus全局声明-->
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
	<property name="metaObjectHandler">
		<!--自动填充策略-->
		<bean id="myMetaObjectHandler" class="cn.edu.config.MyMetaObjectHandler"/>
	</property>
</bean>

4)测试即可

6.2 逻辑删除

物理删除:从数据库中真是删除
逻辑删除:不是真实从数据库中删除,而是逻辑上的删除
目的==>管理员查看删除记录,防止数据丢失,犹如电脑的回收站

1)在数据库中添加字段deleted,并设置默认值为0

2)注册组件

<!--applicationContext.xml-->
	<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="typeAliasesPackage" value="cn.edu.pojo"/>
        <!--<property name="configLocation" value="classpath:mybatis-config.xml"/>-->
        <property name="configuration" ref="configuration"/>
        <property name="globalConfig" ref="globalConfig"/>
        <property name="plugins">
            <array>
                <ref bean="plugins"/>
            </array>
        </property>
    </bean>

    <!--MyBatisPlus全局声明-->
    <bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
        <property name="dbConfig">
            <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">
                <property name="logicDeleteValue" value="1"/>
                <property name="logicNotDeleteValue" value="0"/>
            </bean>
        </property>
    </bean>

3)测试:
==>实际上执行的是update操作

7.插件

7.1 乐观锁

简介:无论怎样,它都认为没有问题,因此不上锁。

乐观锁实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

1)在数据库中添加version字段,并设置默认值为1
2)实体类添加version属性

	//注解@Version:乐观锁
	@Version
    private Integer version;

3)注册组件

<!--applicationContext.xml-->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	<property name="typeAliasesPackage" value="cn.edu.pojo"/>
	<!--<property name="configLocation" value="classpath:mybatis-config.xml"/>-->
	<property name="configuration" ref="configuration"/>
	<property name="globalConfig" ref="globalConfig"/>
	<property name="plugins">
		<array>
			<ref bean="plugins"/>
		</array>
	</property>
</bean>

<!--MyBatisPlus插件-->
<bean id="plugins" class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
	<property name="interceptors">
		<array>
			<!--乐观锁-->
			<bean class="com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor"/>               
		</array>
	</property>
</bean>

4)测试

@Test
 public void testOptimisticLocker2() {
        Employee employee = employeeMapper.selectById(1);
        employee.setLastName("杨二111");
        employee.setAge(23);
        Employee employee2 = employeeMapper.selectById(1);
        employee2.setLastName("杨二222");
        employee2.setAge(23);
        employeeMapper.updateById(employee2);
        employeeMapper.updateById(employee);
    }

7.2 分页

1)注册组件

<!--applicationContext.xml-->

	<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="typeAliasesPackage" value="cn.edu.pojo"/>
        <!--<property name="configLocation" value="classpath:mybatis-config.xml"/>-->
        <property name="configuration" ref="configuration"/>
        <property name="globalConfig" ref="globalConfig"/>
        <property name="plugins">
            <array>
                <ref bean="plugins"/>
            </array>
        </property>
	</bean>

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

2)测试

    @Test
    public void testPage() {
        Page<Employee> page = new Page<>(1, 5);
        employeeMapper.selectPage(page, null);
        page.getRecords().forEach(System.out::println);
        System.out.println(page.getTotal());
        System.out.println(page.getCurrent());
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值