先不管mybatis的設定,先寫個main method,注意內部類別:
public static void main(String[] args) { List<String> list = (List<String>) new MyInterceptor() .plugin(new ArrayList<>()); list.add(0, "aaa"); } @Intercepts(value = { @Signature(args = { int.class, Object.class }, method = "add", type = List.class) }) private static class MyInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { System.out.println("intercept"); return invocation.proceed(); } @Override public Object plugin(Object target) { System.out.println("plugin"); return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { System.out.println("setProperties"); } }
結果:
plugin
intercept
.args是小括弧的參數
.只要執行了add方法,就會攔截
.setProperties會先執行,但目前還沒寫,再來是plugin method,最後是intercept method
.如果想攔截其他方法,但沒有參數,就寫args = {}
.只要設定有錯,就會拋找不到方法的錯誤訊息
※先用Mybatis3.x(九)的例子,可以run再說
由於我Mybatis3.x(九)的程式碼不見了,只好再做一次了,這一次做不一樣的好了CREATE TABLE DEPT ( DEPTNO NUMBER NOT NULL, DNAME VARCHAR2(255 BYTE), LOC VARCHAR2(255 BYTE), CONSTRAINT DEPT_PK PRIMARY KEY(DEPTNO) ); INSERT INTO DEPT (DEPTNO,DNAME,LOC) VALUES (10, 'ACCOUNTING', 'NEW YORK'); INSERT INTO DEPT (DEPTNO,DNAME,LOC) VALUES (20, 'RESEARCH', 'DALLAS'); INSERT INTO DEPT (DEPTNO,DNAME,LOC) VALUES (30, 'SALES', 'CHICAGO'); INSERT INTO DEPT (DEPTNO,DNAME,LOC) VALUES (40, 'OPERATIONS', 'BOSTON');
vo類,故意和資料庫取不一樣的名字
public class Department { private Integer deptno; private String dname; private String loc; //setter/getter... }
DAO:
public interface IDepartmentDAO { @Insert("INSERT INTO DEPT(DEPTNO, DNAME, LOC) VALUES (#{deptno}, #{dname}, #{loc})") public boolean insert(Department vo); @Select("SELECT DEPTNO, DNAME, LOC FROM DEPT") public List<Department> findAll(); }
mybatis-config.xml最後要加這一段,有四種方式,可參考Mybatis3.x(九)
<mappers> <mapper class="dao.IDepartmentDAO"/> </mappers>
測試類:
SqlSession sqlSession = MybatisUtil.getSession(); //查詢 IDepartmentDAO dao = sqlSession.getMapper(IDepartmentDAO.class); Iterator<Department> iter = dao.findAll().iterator(); while (iter.hasNext()) { Department dept = iter.next(); System.out.println("getDeptno=" + dept.getDeptno()); System.out.println("getDname=" + dept.getDname()); System.out.println("getLoc=" + dept.getLoc()); System.out.println("========================="); } //新增 Department dept2 = new Department(); dept2.setDeptno(50); dept2.setDname("MONEY"); dept2.setLoc("FRANCH"); IDepartmentDAO dao2 = sqlSession.getMapper(IDepartmentDAO.class); System.out.println(dao2.insert(dept2)); sqlSession.commit(); MybatisUtil.closeSession();
都可以run後,再加攔截器的程式碼
※攔截器
有兩個地方要加mybatis-config.xml加這一段,注意順序,錯誤會有提示
<plugins> <plugin interceptor="plugin.MyInterceptor"> <property name="param1" value="abc" /> <property name="param2" value="123" /> </plugin> </plugins>
繼承Interceptor的類別:
@Intercepts(value = { @Signature(args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }, method = "query", type = Executor.class), @Signature(args = { Connection.class }, method = "prepare", type = StatementHandler.class) }) public class MyInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { Object result = invocation.proceed(); System.err.println("result=" + result); return result; } @Override public Object plugin(Object target) { System.err.println("target=" + target); return Plugin.wrap(target, this); } // 取得properties,設定在mybatis-config.xml @Override public void setProperties(Properties properties) { String param1 = properties.getProperty("param1"); String param2 = properties.getProperty("param2"); System.err.println("param1 = " + param1); System.err.println("param2 = " + param2); } }
官方提供四種支援如下:
.org.apache.ibatis.executor.Executor
.org.apache.ibatis.executor.parameter.ParameterHandler
.org.apache.ibatis.executor.resultset.ResultSetHandler
.org.apache.ibatis.executor.statement.StatementHandler
其中StatementHandler又有兩個實作類別
BaseStatementHandler(抽象)和RoutingStatementHandler
BaseStatementHandler又有三個兒子
CallableStatementHandler:處理CallableStatement
PreparedStatementHandler:處理PreparedStatement
SimpleStatementHandler:處理Statement
abstract <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler)
.第二個Signature有連資料庫就在呼叫方法之前攔截,所以增刪改查都OK
abstract Statement prepare(Connection connection)
.測試時,result有印出來才表示有成功攔截
.使用這些方法時,我是理解出來的,因為官方網站的API,都沒寫註解,原始碼我也看不太懂
沒有留言:
張貼留言