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

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: