Anwen

别人的看法都是狗屁,你是谁只有自己说了算。若命运不公,就和他斗到底。
——《哪吒之魔童降世》

自己的命自己扛,不要连累别人,不要留有遗憾~
  menu
70 文章
2 评论
2513 浏览
3 当前访客
ღゝ◡╹)ノ❤️

实习日记-工具框架-MybatisPlus

Mybatis & MybatisPlus

MybatisPlus简称MP,是对Mybatis的增强,通过在其基础上的进一步封装来进一步简化开发,由国人开发。官网,其分2.x3.x两个大版本,本文以2.3版本为例介绍其的使用-> 参考文档

学习视频:链接: https://pan.baidu.com/s/1Whu0pBMIvNJ5FsEArI6YLQ 提取码: dp40

初体验

环境准备

创建测试表

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);

创建maven工程,添加依赖:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.22</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>
<!-- mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>

创建实体类

@Data
public class Employee {

    private Integer id;
    private String lastName;
    private String email;
    private Integer gender;
    private Integer age;

}

创建log4j配置文件log4j.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <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"/>
    </logger>
    <logger name="org.apache.ibatis">
        <level value="info"/>
    </logger>
    <root>
        <level value="debug"/>
        <appender-ref ref="STDOUT"/>
    </root>
</log4j:configuration>

创建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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="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.xsd
			    http://www.springframework.org/schema/aop
			    http://www.springframework.org/schema/aop/spring-aop.xsd
			    http://www.springframework.org/schema/tx
			    http://www.springframework.org/schema/tx/spring-tx.xsd">


    <!-- 数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
        <property name="user" value="root"></property>
        <property name="password" value="123456"></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="typeAliasesPackage" value="cn.tuhu.mp.entity"></property>
    </bean>
    <!--
    配置 mybatis 扫描 mapper 接口的路径
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.tuhu.mp.mapper"></property>
    </bean>
</beans>

使用Mybatis实现查询

原来我们在spring集成mybatis之后,需要编写XxxMapper接口和方法,并在该类所在包路径下编写同名的XxxMapper.xmlnamespace为对应接口的全限定名,sql标签的id与接口中对应方法名一致,标签内写sql语句):

EmployeeMapper.java

package cn.tuhu.mp.mapper;

import cn.tuhu.mp.entity.Employee;
import java.util.List;

public interface EmployeeMapper {

    List<Employee> findAll();
}

src/main/resources/cn/tuhu/mp/mapper/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="cn.tuhu.mp.mapper.EmployeeMapper">
    <resultMap id="BaseResultMap" type="cn.tuhu.mp.entity.Employee">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="email" property="email"/>
        <result column="gender" property="gender"/>
        <result column="age" property="age"/>
    </resultMap>
    <select id="findAll" parameterType="int" resultMap="BaseResultMap">
        select * from tbl_employee
    </select>
</mapper>

注意:如果你使用的IDE是IDEA,这里有个坑,右键resources->New->Directory,应该写cn/tuhu/mp/mapper,这样才会创建级联文件夹,如果你写cn.tuhu.mp.mapper则会将其整个作为一个名称创建一个文件夹,这会导致编译后EmployeeMapper.xml无法和EmployeeMapper.java处于同一个目录下。

还有一个大坑就是,如果选择的是右键->New->File的方式创建EmployeeMapper.xml,那么文件名一定要带.xml扩展名后缀,切不可只写EmployeeMapper然后再根据编辑文件类型提示选择xml(这样也许在IDEA中能够正常显示xml标签,但是框架只严格扫描扩展名为xml的映射文件,这回导致明明你反复检查,确认了xml中的namespace和接口全限定名一致,sql标签的id与接口中定义的方法名一致,却仍然抛出Invalid bound statement (not found): com.mapper.EmployeeMapper.findAll的异常)。

EmployeeMapperTest.java

package cn.tuhu.mp.mapper;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class EmployeeMapperTest {

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    @Test
    public void testFindAll() {
        EmployeeMapper employeeMapper = context.getBean(EmployeeMapper.class);
        System.out.println(employeeMapper.findAll());
    }
}

集成MybatisPlus

再新建一个maven项目,复制之前的依赖,将mybatismybatis-spring去掉,添加mybatis-plus即可(因为mybatis-plus自身依赖了mybatismybatis-spring

<!--<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>2.3</version>
</dependency>

然后将applicationContext.xml中的org.mybatis.spring.SqlSessionFactoryBean替换成com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean即可,如此就在集成了Mybatis的基础上,进一步集成了MybatisPlus

<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
    <!-- 数据源 -->
    <property name="dataSource" ref="dataSource"></property>
    <!-- 别名处理 -->
    <property name="typeAliasesPackage" value="cn.tuhu.mp.entity"></property>
</bean>

我们不在需要编写接口及CURD方法和其对应的映射文件了,我们只需创建一个空的EmployeeMapper接口继承BaseMapper即可调用针对Employee实体类的通用CURD操作了。

package cn.tuhu.mp.mapper;

import cn.tuhu.mp.entity.Employee;
import com.baomidou.mybatisplus.mapper.BaseMapper;

public interface EmployeeMapper extends BaseMapper<Employee> {
    
}

由于MP是将实体类名首字母小写作为表名,属性名作为字段名为我们生成SQL的,因此不同之处我们还需声明一下:

package cn.tuhu.mp.entity;

import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;

@Data
@TableName(value = "tbl_employee")
public class Employee {

    @TableId(type = IdType.AUTO)    //mysql主键生成策略:自增
    Integer id;
    @TableField(value = "last_name")
    String lastName;
    String email;
    Integer gender;
    Integer age;

}

如此便可测试了:

package cn.tuhu.mp.mapper;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class EmployeeMapperTest {

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    @Test
    public void testFindAll() {
        EmployeeMapper employeeMapper = context.getBean(EmployeeMapper.class);
        System.out.println(employeeMapper.selectById(1));
    }
}

原理

我们压根就没写DAO方法和对应的SQL语句,MP是如何做到帮助我们生产对应的代理DAO对象的呢?既然我们通过继承BaseMapper就省去了原来DAO方法和SQL映射的书写,那么密码肯定就在BaseMapper中:

/**
 * <p>
 * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
 * </p>
 * <p>
 * 这个 Mapper 支持 id 泛型
 * </p>
 *
 * @author hubin
 * @Date 2016-01-23
 */
public interface BaseMapper<T> {

    /**
     * <p>
     * 插入一条记录
     * </p>
     *
     * @param entity 实体对象
     * @return int
     */
    Integer insert(T entity);

    ...

}

可以看到此类中封装了大量通用CURD操作,并将操作的具体实体类作为泛型参数以实现复用。

也就是说我们的EmployeeMapper继承BaseMapper之后,就通过传递的泛型继承了定义在其中的针对Employee的通用CRUD操作。

而我们在applicationContext.xml中替换SqlSessionFactoryBeanMybatisSqlSessionFactoryBean之后,MybatisPlus就会在原有Mybatis扫描mapper包下接口及同名SQL映射的方式生成绑定(一个DAO方法对应一个SQL)的基础上,为继承了BaseMapper的接口生成一系列的通用CRUD SQL缓存在mappedStatements中(keyBaseMapper中的各个方法,value为方法对应的SQL信息)。

收尾

CURD查询、AR查询、代码生成器、插件扩展等用法见 参考文档

IDEA插件MybatisX,可以帮助我们在编写DAO方法后alt + insert在对应的映射文件中生成SQL标签,还可以帮助我们在javaxml之间来回跳转。


标题:实习日记-工具框架-MybatisPlus
作者:zanwen
地址:http://www.zhenganwen.top/articles/2019/07/17/1565048871256.html

评论