Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Signed-off-by: wendal chen <wendal1985@gmail.com>
  • Loading branch information
wendal committed Aug 19, 2016
1 parent a591197 commit 7c48583
Show file tree
Hide file tree
Showing 9 changed files with 555 additions and 202 deletions.
12 changes: 12 additions & 0 deletions src/org/nutz/dao/DaoInterceptor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.nutz.dao;

/**
* Dao操作拦截器
* @author wendal
* @see org.nutz.dao.impl.interceptor.DaoLogInterceptor
* @see org.nutz.dao.impl.interceptor.DaoTimeInterceptor
*/
public interface DaoInterceptor {

void filter(DaoInterceptorChain chain) throws DaoException;
}
226 changes: 226 additions & 0 deletions src/org/nutz/dao/DaoInterceptorChain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
package org.nutz.dao;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import org.nutz.dao.impl.DaoExecutor;
import org.nutz.dao.sql.DaoStatement;
import org.nutz.dao.sql.SqlContext;
import org.nutz.lang.random.R;
import org.nutz.log.Log;
import org.nutz.log.Logs;

/**
* Dao执行拦截器链.
*
* @author wendal
* @see org.nutz.dao.impl.interceptor.DaoLogInterceptor
* @see org.nutz.dao.impl.interceptor.DaoTimeInterceptor
*/
public class DaoInterceptorChain implements ConnCallback {

private static final Log log = Logs.get();

protected int autoTransLevel;

protected Connection connection;

protected int current = 0;

protected DaoStatement daoStatement;

protected DaoExecutor executor;

protected List<DaoInterceptor> interceptors = new ArrayList<DaoInterceptor>();

protected int updateCount;

protected DaoStatement[] sts;

protected String id;

/**
* 新建一个DaoInterceptorChain.
*
* @param sts
* 将要进行的Dao操作(不一定是SQL操作,有可能是EL)
*/
public DaoInterceptorChain(DaoStatement... sts) {
this.sts = sts;
id = R.UU32();
}

/**
* 继续下一个拦截器,如果已经是最后一个拦截器,那么执行executor.exec
*
* @return 本对象,用于链式操作
* @throws Exception
*/
public DaoInterceptorChain doChain() throws DaoException {
if (hasNext()) {
DaoInterceptor interceptor = next();
current++;
interceptor.filter(this);
} else {
executor.exec(getConnection(), getDaoStatement());
updateCount += getDaoStatement().getUpdateCount();
}
return this;
}

/**
* 获取当前自动事务级别,DaoRunner中使用强制事务时会使用之.拦截器不能修改,即使修改也不会生效
*
* @return 当前自动(强制)事务级别
*/
public int getAutoTransLevel() {
return autoTransLevel;
}

/**
* 当前执行的DaoStatement
*
* @return 当前执行的DaoStatement
*/
public DaoStatement getDaoStatement() {
return daoStatement;
}

/**
* 全部DaoStatement,可能不止一条
*
* @return 全部DaoStatement
*/
public DaoStatement[] getDaoStatements() {
return sts;
}

/**
* 拦截器列表(暂不开放修改)
*
* @return 全体拦截器列表
*/
public List<DaoInterceptor> getInterceptors() {
return interceptors;
}

/**
* 更新总数,用于DaoSupport(NutDao)获取更新总数.
*
* @return 更新记录总数
*/
public int getUpdateCount() {
return updateCount;
}

/**
* 是否还有下一个拦截器
*
* @return true,如果还有拦截器要执行
*/
public boolean hasNext() {
return current < interceptors.size();
}

/**
* 这是DaoExecutor会执行的方法,拦截器内不要执行这个方法!! 这里也是拦截器开始生效的地方.
*/
public void invoke(Connection conn) throws Exception {
for (DaoStatement st : sts) {
if (st == null) {
if (log.isInfoEnabled())
log.info("Found a null DaoStatement(SQL), ingore it ~~");
continue;
}
daoStatement = st;
this.connection = conn;
doChain();
}
}

/**
* 获取下一个拦截器. 调用前必须先调用hasNext进行判断
*
* @return 下一个拦截器
*/
public DaoInterceptor next() {
return interceptors.get(current);
}

/**
* 设置强制事务的级别,对拦截器来说无意义.
*
* @param autoTransLevel
* 与DaoSupport(NutDao)内的值一致
*/
public void setAutoTransLevel(int autoTransLevel) {
this.autoTransLevel = autoTransLevel;
}

/**
* 设置当前拦截器索引. 若设置值大于拦截器列表的大小,那么效果就等同于跳过剩余拦截器,直接执行DaoStatement
*
* @param current
*/
public void setCurrent(int current) {
this.current = current;
}

/**
* 设置DaoExecutor. 典型应用是在拦截器中替换成daocache提供的DaoExecutor
*
* @param executor
* 新的DaoExecutor,不可以是null
*/
public void setExecutor(DaoExecutor executor) {
this.executor = executor;
}

/**
* 设置新的拦截器列表.
*
* @param interceptors
* 新的拦截器列表
*/
public void setInterceptors(List<DaoInterceptor> interceptors) {
this.interceptors = interceptors;
}

/**
* 设置当前使用的数据库连接
*
* @param connection
* 新的数据库连接,不可以是null
*/
public void setConnection(Connection connection) {
this.connection = connection;
}

/**
* 获取当前数据库连接
*
* @return 当前数据库连接
*/
public Connection getConnection() {
return connection;
}

/**
* 获取当前DaoStatement的上下文,注意,一个拦截器链可能包含多个DaoStatement
*
* @return 当前DaoStatement的上下文
*/
public SqlContext getSqlContext() {
return getDaoStatement().getContext();
}

/**
* 拦截器链的id, 为一个uu32识别符.
*
* @return 本拦截器链的id
*/
public String getId() {
return id;
}
}
Loading

0 comments on commit 7c48583

Please sign in to comment.