实习***-工具框架-MybatisPlus
个人博客:zhenganwen.top
Mybatis & MybatisPlus
MybatisPlus
简称MP,是对Mybatis
的增强,通过在其基础上的进一步封装来进一步简化开发,由国人开发。官网,其分2.x
和3.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.xml
(namespace
为对应接口的全限定名,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项目,复制之前的依赖,将mybatis
和mybatis-spring
去掉,添加mybatis-plus
即可(因为mybatis-plus
自身依赖了mybatis
和mybatis-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
中替换SqlSessionFactoryBean
的MybatisSqlSessionFactoryBean
之后,MybatisPlus
就会在原有Mybatis
扫描mapper
包下接口及同名SQL映射的方式生成绑定(一个DAO方法对应一个SQL)的基础上,为继承了BaseMapper
的接口生成一系列的通用CRUD SQL缓存在mappedStatements
中(key
为BaseMapper
中的各个方法,value
为方法对应的SQL信息)。
收尾
CURD查询、AR查询、代码生成器、插件扩展等用法见 参考文档
IDEA插件MybatisX
,可以帮助我们在编写DAO方法后alt + insert
在对应的映射文件中生成SQL标签,还可以帮助我们在java
和xml
之间来回跳转。