mybatis @Intercepts的用法解读

 更新时间:2021年09月24日 08:47:58   作者:knife1220  
这篇文章主要介绍了mybatis @Intercepts的用法解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

mybatis @Intercepts的用法

1.拦截器类

package com.testmybatis.interceptor; 
import java.util.Properties; 
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
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.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.log4j.Logger;
 
@Intercepts({ @org.apache.ibatis.plugin.Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }) })
public class SqlInterceptor implements Interceptor {
	
	private Logger log=Logger.getLogger(getClass()); 
	public Object intercept(Invocation invocation) throws Throwable {
		// TODO Auto-generated method stub
 
		log.info("Interceptor......");
 
		// 获取原始sql语句
		MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
		Object parameter = invocation.getArgs()[1];
		BoundSql boundSql = mappedStatement.getBoundSql(parameter);
		String oldsql = boundSql.getSql();
		log.info("old:"+oldsql);
 
		// 改变sql语句
		BoundSql newBoundSql = new BoundSql(mappedStatement.getConfiguration(), oldsql + " where id=1",
				boundSql.getParameterMappings(), boundSql.getParameterObject());
		MappedStatement newMs = copyFromMappedStatement(mappedStatement, new BoundSqlSqlSource(newBoundSql));
		invocation.getArgs()[0] = newMs;
 
		// 继续执行
		Object result = invocation.proceed();
		return result;
	}
 
	public Object plugin(Object target) {
		// TODO Auto-generated method stub
		return Plugin.wrap(target, this);
	}
 
	public void setProperties(Properties properties) {
		// TODO Auto-generated method stub 
	}
 
	// 复制原始MappedStatement
	private MappedStatement copyFromMappedStatement(MappedStatement ms, SqlSource newSqlSource) {
		MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource,
				ms.getSqlCommandType());
		builder.resource(ms.getResource());
		builder.fetchSize(ms.getFetchSize());
		builder.statementType(ms.getStatementType());
		builder.keyGenerator(ms.getKeyGenerator());
		if (ms.getKeyProperties() != null) {
			for (String keyProperty : ms.getKeyProperties()) {
				builder.keyProperty(keyProperty);
			}
		}
		builder.timeout(ms.getTimeout());
		builder.parameterMap(ms.getParameterMap());
		builder.resultMaps(ms.getResultMaps());
		builder.cache(ms.getCache());
		builder.useCache(ms.isUseCache());
		return builder.build();
	}
 
	public static class BoundSqlSqlSource implements SqlSource {
		BoundSql boundSql; 
		public BoundSqlSqlSource(BoundSql boundSql) {
			this.boundSql = boundSql;
		}
 
		public BoundSql getBoundSql(Object parameterObject) {
			return boundSql;
		}
	} 
}

2.拦截器配置

<?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>
 
	<plugins>
		<plugin interceptor="com.testmybatis.interceptor.SqlInterceptor" />
	</plugins>
 
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.cj.jdbc.Driver" />
				<property name="url"
					value="jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=true" />
				<property name="username" value="root" />
				<property name="password" value="123456" />
			</dataSource>
		</environment>
	</environments>
	
	<mappers>
		<mapper resource="com/testmybatis/dao/TestMapper.xml" />
	</mappers>	
</configuration>

3.测试接口及配置

package com.testmybatis.model; 
import java.io.Serializable; 
public class Test implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private int id;
	private String name;
 
	public int getId() {
		return id;
	}
 
	public void setId(int id) {
		this.id = id;
	}
 
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
	
	public String toString(){
		return "id:"+id+" name:"+name;
	} 
}
package com.testmybatis.dao; 
import java.util.List; 
import org.apache.ibatis.annotations.Select; 
import com.testmybatis.model.Test;  
public interface TestMapper {
	public List<Test> test();
}
<?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.testmybatis.dao.TestMapper">
 
	<select id="test" resultType="com.testmybatis.model.Test">
		select * from test
	</select>
 
</mapper>

4.测试

	try {
			String resource = "com/testmybatis/mybatis-config.xml";
			InputStream inputStream = Resources.getResourceAsStream(resource);
			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
			SqlSession session = sqlSessionFactory.openSession();
			try {
				TestMapper mapper=session.getMapper(TestMapper.class);
				List<Test> tests=mapper.test();
				session.commit();
				log.info(JSON.toJSONString(tests));
				
			} finally {
				session.close();
			}
 
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

5.结果

配置了拦截器的情况下

2018-08-07 14:14:18 DEBUG [com.testmybatis.dao.TestMapper.test] ==> Preparing: select * from test where id=1

2018-08-07 14:14:18 DEBUG [com.testmybatis.dao.TestMapper.test] ==> Parameters:

2018-08-07 14:14:18 DEBUG [com.testmybatis.dao.TestMapper.test] <== Total: 1

2018-08-07 14:14:18 INFO [com.testmybatis.testlanjie] [{"id":1,"name":"adb"}]

没配置拦截器的情况下

2018-08-07 14:15:48 DEBUG [com.testmybatis.dao.TestMapper.test] ==> Preparing: select * from test

2018-08-07 14:15:48 DEBUG [com.testmybatis.dao.TestMapper.test] ==> Parameters:

2018-08-07 14:15:48 DEBUG [com.testmybatis.dao.TestMapper.test] <== Total: 8

2018-08-07 14:15:48 INFO [com.testmybatis.testlanjie] [{"id":1,"name":"adb"},{"id":2,"name":"dafdsa"},{"id":3,"name":"dafa"},{"id":4,"name":"fffff"},{"id":16,"name":"test"},{"id":17,"name":"test"},{"id":18,"name":"test"},{"id":19,"name":"zhenshide"}]

mybatis @Intercepts小例子

这只是一个纯碎的mybatis的只针对@Intercepts应用的小列子,没有和spring做集成。

1.工作目录

2.数据库mysql

建立一个数据库表、实体对象User、UserMapper.java、UserMapper.xml省略。

使用mybatis自动代码生成工具生成:mybatis-generator-core-1.3.2。(此处略)

3.拦截器

MyInterceptor.java

package com.tiantian.mybatis.interceptor;
import java.sql.Connection;
import java.util.Properties;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
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( {
    @Signature(method = "query", type = Executor.class, args = {
           MappedStatement.class, Object.class, RowBounds.class,
           ResultHandler.class }),
    @Signature(method = "prepare", type = StatementHandler.class, args = { Connection.class }) })
public class MyInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object result = invocation.proceed();
        System.out.println("Invocation.proceed()");
        return result;
    }
    @Override
    public Object plugin(Object target) {
        // TODO Auto-generated method stub
        return Plugin.wrap(target, this);
    }
    @Override
    public void setProperties(Properties properties) {
        String prop1 = properties.getProperty("prop1");
        String prop2 = properties.getProperty("prop2");
        System.out.println(prop1 + "------" + prop2);
    }
}

4.配置文件

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>
    <properties resource="jdbc.properties"></properties>
    <typeAliases>
       <package name="com.tiantian.mybatis.model"/>
    </typeAliases>
    <plugins>
       <plugin interceptor="com.tiantian.mybatis.interceptor.MyInterceptor">
           <property name="prop1" value="prop1"/>
           <property name="prop2" value="prop2"/>
       </plugin>
    </plugins>
    <environments default="development">
       <environment id="development">
           <transactionManager type="JDBC" />
           <dataSource type="POOLED">
              <property name="driver" value="${driver}" />
              <property name="url" value="${url}" />
              <property name="username" value="${username}" />
              <property name="password" value="${password}" />
           </dataSource>
       </environment>
    </environments>
    <mappers>
       <mapper resource="com/tiantian/mybatis/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

5.配置文件

jdbc.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/database_yxl
username=root
password=123456
#定义初始连接数
initialSize=0
#定义最大连接数
maxActive=20
#定义最大空闲
maxIdle=20
#定义最小空闲
minIdle=1
#定义最长等待时间
maxWait=60000

6.测试文件

TestMyBatis.java

package com.tiantian.mybatis.service;
import org.apache.ibatis.session.SqlSession;
import com.tiantian.base.MyBatisUtil;
import com.tiantian.mybatis.domain.User;
public class TestMyBatis {
    public static void main(String[] args) {
        SqlSession session = MyBatisUtil.getSqlSession();
        /**
         * 映射sql的标识字符串,
         * com.tiantian.mybatis.mapper.userMapper是userMapper.xml文件中mapper标签的namespace属性的值,
         * selectByPrimaryKey是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL
         */
        String statement = "com.tiantian.mybatis.mapper.UserMapper.selectByPrimaryKey";//映射sql的标识字符串
        //执行查询返回一个唯一user对象的sql
        User user = session.selectOne(statement, 1);
        System.out.println(user);
    }
}

输出结果:

prop1------prop2

Invocation.proceed()

Invocation.proceed()

[id:1;username:测试;password:sfasgfaf]

7.工具类

MyBatisUtil.java

package com.tiantian.base;
import java.io.InputStream;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil {
    public static SqlSessionFactory getSqlSessionFactory() {
        String resource = "mybatis-config.xml";
        // 使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)
        InputStream is = MyBatisUtil.class.getClassLoader().getResourceAsStream(resource);
        // 构建sqlSession的工厂
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
        return sessionFactory;
    }
    public static SqlSession getSqlSession() {
        return getSqlSessionFactory().openSession();
    }
    public static SqlSession getSqlSession(boolean isAutoCommit) {
        return getSqlSessionFactory().openSession(isAutoCommit);
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java读取.properties配置文件的几种方式

    Java读取.properties配置文件的几种方式

    这篇文章主要介绍了Java读取.properties配置文件的几种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Javafx简单实现【我的电脑资源管理器】效果

    Javafx简单实现【我的电脑资源管理器】效果

    这篇文章主要介绍了Javafx简单实现【我的电脑资源管理器】效果,涉及Javafx操作系统文件模拟资源管理器的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-09-09
  • Java创建多线程局域网聊天室实例

    Java创建多线程局域网聊天室实例

    这篇文章主要介绍了Java创建多线程局域网聊天室实例,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • 说一说java关键字final和transient

    说一说java关键字final和transient

    这篇文章主要和大家说一说java关键字final和transient,感兴趣的小伙伴们可以参考一下
    2016-06-06
  • java实现Socket通信之单线程服务

    java实现Socket通信之单线程服务

    这篇文章主要为大家详细介绍了java实现Socket通信的单线程服务,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • Java并发编程示例(七):守护线程的创建和运行

    Java并发编程示例(七):守护线程的创建和运行

    这篇文章主要介绍了Java并发编程示例(七):守护线程的创建和运行,在本节示例中,我们将创建两个线程,一个是普通线程,向队列中写入事件,另外一个是守护线程,清除队列中的事件,需要的朋友可以参考下
    2014-12-12
  • Spring中使用自定义ThreadLocal存储导致的坑及解决

    Spring中使用自定义ThreadLocal存储导致的坑及解决

    这篇文章主要介绍了Spring中使用自定义ThreadLocal存储导致的坑及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java基于jdbc实现的增删改查操作示例

    Java基于jdbc实现的增删改查操作示例

    这篇文章主要介绍了Java基于jdbc实现的增删改查操作,结合实例形式分析了java使用jdbc进行数据库的连接、增删改查等基本操作技巧,需要的朋友可以参考下
    2019-01-01
  • 深入理解Java虚拟机之经典垃圾收集器

    深入理解Java虚拟机之经典垃圾收集器

    这篇文章主要介绍了深入理解Java虚拟机之经典垃圾收集器的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-11-11
  • Struts2学习笔记(8)-Result常用类型

    Struts2学习笔记(8)-Result常用类型

    这篇文章主要介绍Struts2中Result四种常用的类型的用法,希望能给大家做一个参考。
    2016-06-06

最新评论