一、Mybatis+SpringBoot整合方式
先添加pom文件,自己看需要什么
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.xdclass</groupId> <artifactId>xdclass-mysql</artifactId> <version>0.0.1-SNAPSHOT</version> <name>xdclass-mysql</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.6</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-joda</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-parameter-names</artifactId> </dependency> <!-- 分页插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency> <!-- alibaba的druid数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.9</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.7</version> <configuration> <configurationFile>tools/generatorConfig-xdclass.xml</configurationFile> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> <executions> <execution> <id>Generate MyBatis Artifacts</id> <phase>none</phase> <goals> <goal>generate</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.7</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.24</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>
使用idea工具将properties转成yml
在plugin marketplace搜索Properties to YAML Converter工具
具体如何使用:
使用自动plugin插件自动生成sql xml文件配置
<build> <plugins> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.7</version> <configuration> <configurationFile>tools/generatorConfig-xdclass.xml</configurationFile> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> <executions> <execution> <id>Generate MyBatis Artifacts</id> <phase>none</phase> <goals> <goal>generate</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.7</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.24</version> </dependency> </dependencies> </plugin> </plugins> </build>
二、Mybatis Gennerator的使用
- 定义:MyBatis Generator 是 MyBatis 提供的一个代码生成工具。可以帮我们生成表对应的持久化对象(po)、操作数据库的接口(dao)、CRUD sql的xml(mapper)
- 自动生成增删改查SQL
- 配置项
- 配置context,id : 随便填,保证多个 context id 不重复就行
- jdbcConnection:MyBatis Generator 需要链接数据库,所以需要配置jdbcConnection
- javaTypeResolver:javaTypeResolver 是配置 JDBC 与 java 的类型转换规则,或者你也可以不用配置,使用它默认的转换规则
- sqlMapGenerator:xml生成的目录
- javaClientGenerator:java代码生成的目录
- 配置样例
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration>
<context id="xdclass" targetRuntime="MyBatis3">
<!-- 用反引号`包裹,默认是双引号"-->
<property name="autoDelimitKeywords" value="true"/>
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<property name="javaFileEncoding" value="UTF-8"/>
<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
<plugin type="org.mybatis.generator.plugins.MapperAnnotationPlugin"/>
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/xdclass_mysql?useUnicode=true&characterEncoding=UTF-8"
userId="xdclass" password="xdclass">
</jdbcConnection>
<!-- java type resolver -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
<property name="useJSR310Types" value="true"/>
</javaTypeResolver>
<!-- gem entity -->
<javaModelGenerator targetPackage="com.xdclass.mysql.model"
targetProject="./src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="false"/>
</javaModelGenerator>
<!-- gem sql map -->
<sqlMapGenerator targetPackage="mappers/xdclass/generated"
targetProject="./src/main/resources/">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!-- gem mapper -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.xdclass.mysql.persist.mapper.generated"
targetProject="./src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<table tableName="user" domainObjectName="User" mapperName="UserMapper"
enableCountByExample="false"
enableUpdateByExample="false" enableDeleteByExample="false"
enableSelectByExample="false" selectByExampleQueryId="false"
enableDeleteByPrimaryKey="true" enableInsert="true"
enableSelectByPrimaryKey="true" enableUpdateByPrimaryKey="true">
<columnOverride column="is_default_type" property="defaultType" javaType="java.lang.Boolean"
jdbcType="TINYINT"/>
</table>
</context>
</generatorConfiguration>
点击这个位置,自动生成,改什么位置看起来很清晰
三、基于Mybatis自定义SQL
- 新建mappes.xdclass.custom包用于存储自定义XML定义信息
- 指定resultMap和返回列sql
- 新建mapper.custom用于存储自定义mapper接口
- 加入@Mapper接口
- 进行自定义mapper查询接口测试案例
第一步:创建接口interface
@Mapper public interface CustomUserMapper { /** * 通过name和company查询数据 * @return */ User selectByNameAndCompany(String name ,String company); }
第二步:编写自定义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.xdclass.mysql.persist.mapper.custom.CustomUserMapper"> <resultMap id="ResultMap" type="com.xdclass.mysql.model.User"> <id column="id" jdbcType="BIGINT" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> <result column="company" jdbcType="VARCHAR" property="company" /> </resultMap> <sql id="Column_List"> id, `name`, company </sql> <select id="selectByNameAndCompany" resultMap="ResultMap"> select <include refid="Column_List" /> from user where name = #{name,jdbcType=VARCHAR} and COMPANY=#{company,jdbcType=VARCHAR} </select> </mapper>
测试一下
@RequestMapping(value = "/search", method = RequestMethod.GET) public RestItemResult<com.xdclass.mysql.model.User> get(String name,String company) { RestItemResult<com.xdclass.mysql.model.User> result = new RestItemResult<>(); com.xdclass.mysql.model.User user = customUserMapper.selectByNameAndCompany(name,company); if (user != null) { result.setItem(user); result.setResult("success"); } else { result.setMessage("查询用户失败"); result.setResult("failure"); } return result; }
四、Mybatis Executor执行过程解析
- 解读源码的学习习惯
- 理论先行。阅读某一个模块时,先搜索它的理论支撑
- 巧用调试。关于IDEA中debug的使用方式
- 业务为先。如果一个类太过庞大,则先将其中的方法按功能归类,捋清大致的执行流程,接下来再逐个功能地去攻克
- 不求甚解。有些方法不需要搞清楚实现过程,只需要了解它的作用
五、高级面试题之Mybatis自定义拦截器
- 拦截器作用:拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法。
- 对于实现自己的 Interceptor 而言有两个很重要的注解,一个是 @Intercepts,其值是一个@Signature 数组。@Intercepts 用于表明当前的对象是一个 Interceptor,而 @Signature则表明要拦截的接口、方法以及对应的参数类型
- @Signature 的参数:
- type:要拦截的接口
- method:需要拦截的方法,存在于要拦截的接口之中
- args:被拦截的方法所需要的参数
- 步骤:
- 实现org.apache.ibatis.plugin.Interceptor
- 重载intercept方法实现逻辑
- 将拦截器注入到config配置中
实战演示:
package com.xdclass.mysql.inteceptor; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.*; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import java.util.Properties; import java.util.Properties; @Intercepts( @Signature(method = "query", type = Executor.class, args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class} ) ) public class QueryInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { long startTime = System.currentTimeMillis(); System.out.println("拦截方法开始,SQL执行----"); Object proceed = invocation.proceed(); System.out.println("拦截方法结束,SQL执行时间"+(System.currentTimeMillis()-startTime)+"ms----"); return proceed; } @Override public Object plugin(Object target) { return Plugin.wrap(target,this); } @Override public void setProperties(Properties properties) { } }
package com.xdclass.mysql.config; import com.xdclass.mysql.inteceptor.QueryInterceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.List; @Configuration public class MybatisConfig { @Resource private List<SqlSessionFactory> sqlSessionFactoryList; @PostConstruct public void addMyInterceptor() { QueryInterceptor e = new QueryInterceptor(); for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) { sqlSessionFactory.getConfiguration().addInterceptor(e); } } }
package com.xdclass.mysql.config; import com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration; import com.xdclass.mysql.interceptor.QueryInterceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.List; /** * @author daniel */ @Configuration @AutoConfigureAfter(PageHelperAutoConfiguration.class) public class LogAutoConfiguration { @Resource private List<SqlSessionFactory> sqlSessionFactoryList; @PostConstruct public void addMyInterceptor() { QueryInterceptor e = new QueryInterceptor(); for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) { sqlSessionFactory.getConfiguration().addInterceptor(e); } } }
成功实现如下图
本文作者为DBC,转载请注明。