一:插件
1:generator
https://download.csdn.net/download/qq_36297434/15759983
插件工具。是用于自动生成代码的,可以生成的代码包括:实体类型,mapper接口,mapper接口对应的SQL映射文件。
1.1:src下配置generatorConfig.xml
<?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="test" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/ssm" userId="root"
password="root">
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="com.hhxylwk.pojo"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.hhxylwk.mapper"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.hhxylwk.mapper"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<table schema="" tableName="user"></table>
</context>
</generatorConfiguration>
1.2:执行程序,生成代码
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;
public class GeneratorSqlmap {
public void generator() throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
//指定 逆向工程配置文件
InputSteam in = GeneratorSqlmap .class
.getResourceAsStream("/generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(in);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
callback, warnings);
myBatisGenerator.generate(null);
}
public static void main(String[] args) throws Exception {
try {
GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();
generatorSqlmap.generator();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2:Interceptor
是MyBaits提供的一个插件(plugin扩展)。代表拦截器。可以拦截代码中的数据库访问操作。就是Statement操作。拦截后可以修改正在执行的SQL语句,可以额外访问数据库们可以实现若干数据计算和处理。Interceptor影响执行效率。
2.1:实现拦截器类
package com.hhxylwk.interceptors;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Properties;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
/**
* @Intercepts代表当前的类型是一个Mybatis的拦截器,其中有必要属性是一个数组。
* @author 李伟康
*
*/
class User {
Long id;
String name;
Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
@Intercepts(
@Signature(
type = Executor.class, //签名类型:Executor
method = "query", //这个类型对应的方法
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class} //参数
)
)
public class MyInterceptor implements Interceptor {
private String dbType;
@Override
public Object intercept(Invocation invocation) throws Throwable {
//获取参数数据,就是注解中args配置的信息
Object[] args=invocation.getArgs();
//获取映射处理器
MappedStatement statement=(MappedStatement)args[0];
//拦截的方法的参数表
Object parameter=args[1];
//结果处理器。就是查询结果处理器,类似封装好的ResultSet
ResultHandler handler=(ResultHandler)args[3];
//拦截的方法
Method method=invocation.getMethod();
//获取执行器。类似JDBC中的statement
Executor target=(Executor)invocation.getTarget();
//通过MappedStatement获取SQL语句。可以是XML配置的或者注解配置的
BoundSql bsql=statement.getBoundSql(parameter);
//拼接生成新SQL字符串
String pageSql=this.toPageSql(bsql.getSql());
//定义一个新的SQL。用于替换拦截的方法要执行的SQL
BoundSql pageBoundSql=new BoundSql(statement.getConfiguration(), pageSql, bsql.getParameterMappings(), parameter);
//是一个缓存,当执行查询后,会将查询结果缓存到一级缓存中
CacheKey cacheKey=target.createCacheKey(statement, parameter, RowBounds.DEFAULT, pageBoundSql);
List<User> temp=target.query(statement, parameter, RowBounds.DEFAULT,handler,cacheKey, pageBoundSql);
return temp;
}
@Override //匹配你的拦截规则:
public Object plugin(Object o) {
//做拦截处理:默认都是这一句
return Plugin.wrap(o, this);
//不做拦截: return o;
}
@Override //通过这个方法获取到你自定义的配置
public void setProperties(Properties properties) {
dbType = properties.getProperty("dbType");
}
//该方法对SQL字符串重新拼接,生成新的SQL字符串,为简单不做处理
private String toPageSql(String sql) {
return sql;
}
}
2.2:配置文件(在Mybatis核心配置文件中)
<plugins>
<!--自定义的拦截器-->
<plugin interceptor="com.hhxylwk.MyInterceptor">
<!-- 自定义属性:setProperties可以获取到 -->
<property name="dbType" value="mysql"/>
</plugin>
</plugins>
二:动态SQL
1:provider
1.1:peovider注解
@InsertProvider @UpdateProvider @DeleteProvider @SelectProvider
Mybatis中提供的一个注解代发模式下的动态SQL构建方式,相对来说,SQL语法结构只满足标准SQL。provider编写的SQL语句,难以进行SQL优化,通过代码逻辑定义SQL语句,优化得代码就是重新编译代码。
1.2:核心代码
package com.hhxylwk.provider;
import java.util.List;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;
import org.apache.ibatis.jdbc.SQL;
class User {
Long id;
String name;
Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
public interface UserMapper {
/**
* provider系列注解:
* method属性-当前方法执行的时候,用于构建SQL的方法是什么
* type属性-当前方法执行的时候,用于构建SQL的类型是什么
*/
@InsertProvider(method="createInsertSQL",type=UserMapperProvider.class)
public int insertUser(User user);
@UpdateProvider(method="createUpdateSQL",type=UserMapperProvider.class)
public int updateUser(User user);
@DeleteProvider(method="createDeleteSQL",type=UserMapperProvider.class)
public int deleteUserById(Long id);
@SelectProvider(method="createSelectSQL",type=UserMapperProvider.class)
public List<User> selectUser(int age);
static class UserMapperProvider{
/**
* 构建插入SQL语句,方法名称自定义。
* @param user-就是insertUser的参数。
* @return 返回作为SQL语句的字符串
*/
public String createInsertUser(User user) {
//创建SQL构建工具,SQL是Mybatis提供的专门构建SQL的类型。
SQL sql=new SQL();
//设置要插入的表名
sql.INSERT_INTO("t_user");
//设置要插入的字段名和对应的值
sql.VALUES("name","lwk");
return sql.toString();
}
public String createUpdateSQL(User user) {
String sql=null;
return sql;
}
public String createDeleteSQL(Long id) {
String sql=null;
return sql;
}
public String createSelectSQL(int age) {
String sql=null;
return sql;
}
}
}