浏览代码

jfinal 3.4

James 8 年之前
父节点
当前提交
a0832dbc10

+ 82 - 81
src/main/java/com/jfinal/ext/interceptor/SessionInViewInterceptor.java

@@ -58,91 +58,92 @@ public class SessionInViewInterceptor implements Interceptor {
 			c.setAttr("session", session);
 			c.setAttr("session", session);
 		}
 		}
 	}
 	}
-}
-
-@SuppressWarnings({"rawtypes", "deprecation"})
-class JFinalSession extends HashMap implements HttpSession {
-	private static final long serialVersionUID = -6148316613614087335L;
-	private HttpSession session;
-	
-	public JFinalSession(HttpSession session) {
-		this.session = session;
-	}
-	
-	public Object getAttribute(String key) {
-		return session.getAttribute(key);
-	}
-	
-	@SuppressWarnings("unchecked")
-	public Enumeration getAttributeNames() {
-		return session.getAttributeNames();
-	}
-	
-	public long getCreationTime() {
-		return session.getCreationTime();
-	}
-	
-	public String getId() {
-		return session.getId();
-	}
-	
-	public long getLastAccessedTime() {
-		return session.getLastAccessedTime();
-	}
-	
-	public int getMaxInactiveInterval() {
-		return session.getMaxInactiveInterval();
-	}
-	
-	public ServletContext getServletContext() {
-		return session.getServletContext();
-	}
-	
-	public javax.servlet.http.HttpSessionContext getSessionContext() {
-		return session.getSessionContext();
-	}
 	
 	
-	public Object getValue(String key) {
-		return session.getValue(key);
-	}
-	
-	public String[] getValueNames() {
-		return session.getValueNames();
-	}
-	
-	public void invalidate() {
-		session.invalidate();
-	}
-	
-	public boolean isNew() {
-		return session.isNew();
-	}
-	
-	public void putValue(String key, Object value) {
-		session.putValue(key, value);
-	}
-	
-	public void removeAttribute(String key) {
-		session.removeAttribute(key);
-	}
-	
-	public void removeValue(String key) {
-		session.removeValue(key);
-	}
-	
-	public void setAttribute(String key, Object value) {
-		session.setAttribute(key, value);
-	}
-	
-	public void setMaxInactiveInterval(int maxInactiveInterval) {
-		session.setMaxInactiveInterval(maxInactiveInterval);
-	}
-	
-	public String toString() {
-		return session != null ? session.toString() : "null";
+	@SuppressWarnings({"rawtypes", "deprecation"})
+	public static class JFinalSession extends HashMap implements HttpSession {
+		private static final long serialVersionUID = -6148316613614087335L;
+		private HttpSession session;
+		
+		public JFinalSession(HttpSession session) {
+			this.session = session;
+		}
+		
+		public Object getAttribute(String key) {
+			return session.getAttribute(key);
+		}
+		
+		@SuppressWarnings("unchecked")
+		public Enumeration getAttributeNames() {
+			return session.getAttributeNames();
+		}
+		
+		public long getCreationTime() {
+			return session.getCreationTime();
+		}
+		
+		public String getId() {
+			return session.getId();
+		}
+		
+		public long getLastAccessedTime() {
+			return session.getLastAccessedTime();
+		}
+		
+		public int getMaxInactiveInterval() {
+			return session.getMaxInactiveInterval();
+		}
+		
+		public ServletContext getServletContext() {
+			return session.getServletContext();
+		}
+		
+		public javax.servlet.http.HttpSessionContext getSessionContext() {
+			return session.getSessionContext();
+		}
+		
+		public Object getValue(String key) {
+			return session.getValue(key);
+		}
+		
+		public String[] getValueNames() {
+			return session.getValueNames();
+		}
+		
+		public void invalidate() {
+			session.invalidate();
+		}
+		
+		public boolean isNew() {
+			return session.isNew();
+		}
+		
+		public void putValue(String key, Object value) {
+			session.putValue(key, value);
+		}
+		
+		public void removeAttribute(String key) {
+			session.removeAttribute(key);
+		}
+		
+		public void removeValue(String key) {
+			session.removeValue(key);
+		}
+		
+		public void setAttribute(String key, Object value) {
+			session.setAttribute(key, value);
+		}
+		
+		public void setMaxInactiveInterval(int maxInactiveInterval) {
+			session.setMaxInactiveInterval(maxInactiveInterval);
+		}
+		
+		public String toString() {
+			return session != null ? session.toString() : "null";
+		}
 	}
 	}
 }
 }
 
 
+
 /*
 /*
 public void intercept(Invocation inv) {
 public void intercept(Invocation inv) {
 	inv.invoke();
 	inv.invoke();

+ 1 - 1
src/main/java/com/jfinal/plugin/activerecord/CPI.java

@@ -39,7 +39,7 @@ public abstract class CPI {
 	
 	
 	@SuppressWarnings({"unchecked", "rawtypes"})
 	@SuppressWarnings({"unchecked", "rawtypes"})
 	public static final Set<String> getModifyFlag(Model model) {
 	public static final Set<String> getModifyFlag(Model model) {
-		return model.getModifyFlag();
+		return model._getModifyFlag();
 	}
 	}
 	
 	
 	public static <T> List<T> query(Connection conn, String sql, Object... paras) throws SQLException {
 	public static <T> List<T> query(Connection conn, String sql, Object... paras) throws SQLException {

+ 142 - 118
src/main/java/com/jfinal/plugin/activerecord/Model.java

@@ -45,18 +45,19 @@ public abstract class Model<M extends Model> implements Serializable {
 	public static final int FILTER_BY_SAVE = 0;
 	public static final int FILTER_BY_SAVE = 0;
 	public static final int FILTER_BY_UPDATE = 1;
 	public static final int FILTER_BY_UPDATE = 1;
 	
 	
-	public M dao() {
-		attrs = DaoContainerFactory.daoMap;
-		modifyFlag = DaoContainerFactory.daoSet;
-		return (M)this;
-	}
+	private String configName;
+	
+	/**
+	 * Flag of column has been modified. update need this flag
+	 */
+	private Set<String> modifyFlag;
 	
 	
 	/**
 	/**
 	 * Attributes of this model
 	 * Attributes of this model
 	 */
 	 */
-	private Map<String, Object> attrs = getAttrsMap();	// getConfig().containerFactory.getAttrsMap();	// new HashMap<String, Object>();
+	private Map<String, Object> attrs = createAttrsMap();	// getConfig().containerFactory.getAttrsMap();	// new HashMap<String, Object>();
 	
 	
-	private Map<String, Object> getAttrsMap() {
+	private Map<String, Object> createAttrsMap() {
 		Config config = _getConfig();
 		Config config = _getConfig();
 		if (config == null)
 		if (config == null)
 			return DbKit.brokenConfig.containerFactory.getAttrsMap();
 			return DbKit.brokenConfig.containerFactory.getAttrsMap();
@@ -64,9 +65,95 @@ public abstract class Model<M extends Model> implements Serializable {
 	}
 	}
 	
 	
 	/**
 	/**
-	 * Flag of column has been modified. update need this flag
+	 * 将本 model 对象转化为线程安全的 dao 对象.
+	 * 
+	 * 为保障线程安全,转化为线程安全的 dao 对象,只能调用线程安全方法,
+	 * 也即只能调用其 find 系列、paginate 系列、deleteBy 系列方法,
+	 * 不能再调用其 set 系列以及 get 系列方法,更不能再调用其 save()、
+	 * update()、delete() 等方法,否则会抛出异常进行防护
+	 * 
+	 * <pre>
+	 * 强烈建议通过 static 修饰过的 dao 对象都要调用一次 dao() 方法,
+	 * 以免新手误用造成线程安全问题,示例如下:
+	 * 
+	 * public class UserService {
+	 * 
+	 * 	private static User dao = new User().dao();
+	 * 		
+	 * 	public User getUserById(long userId) {
+	 * 		return dao.findFirst("select * from `user` where id = ? limit 1", userId);
+	 * 	}
+	 * }
+	 * </pre>
 	 */
 	 */
-	private Set<String> modifyFlag;
+	public M dao() {
+		attrs = DaoContainerFactory.daoMap;
+		modifyFlag = DaoContainerFactory.daoSet;
+		return (M)this;
+	}
+	
+	/**
+	 * filter () 方法将被 save()、update() 两个方法回调,
+	 * 子类可通过覆盖此方法,实现类似于过滤 XSS 攻击脚本的功能
+	 * 
+	 * @param filterBy 0 表示当前正被 save() 调用, 1 表示当前正被 update() 调用
+	 */
+	protected void filter(int filterBy) {
+		
+	}
+	
+	/**
+	 * Return attribute Map.
+	 * <p>
+	 * Danger! The update method will ignore the attribute if you change it directly.
+	 * You must use set method to change attribute that update method can handle it.
+	 */
+	protected Map<String, Object> _getAttrs() {
+		return attrs;
+	}
+	
+	/**
+	 * Return attribute Set.
+	 */
+	public Set<Entry<String, Object>> _getAttrsEntrySet() {
+		return attrs.entrySet();
+	}
+	
+	/**
+	 * Return attribute names of this model.
+	 */
+	public String[] _getAttrNames() {
+		Set<String> attrNameSet = attrs.keySet();
+		return attrNameSet.toArray(new String[attrNameSet.size()]);
+	}
+	
+	/**
+	 * Return attribute values of this model.
+	 */
+	public Object[] _getAttrValues() {
+		java.util.Collection<Object> attrValueCollection = attrs.values();
+		return attrValueCollection.toArray(new Object[attrValueCollection.size()]);
+	}
+	
+	/**
+	 * Set attributes with other model.
+	 * @param model the Model
+	 * @return this Model
+	 */
+	public M _setAttrs(M model) {
+		return (M)_setAttrs(model._getAttrs());
+	}
+	
+	/**
+	 * Set attributes with Map.
+	 * @param attrs attributes of this model
+	 * @return this Model
+	 */
+	public M _setAttrs(Map<String, Object> attrs) {
+		for (Entry<String, Object> e : attrs.entrySet())
+			set(e.getKey(), e.getValue());
+		return (M)this;
+	}
 	
 	
 	/*
 	/*
 	private Set<String> getModifyFlag() {
 	private Set<String> getModifyFlag() {
@@ -75,7 +162,7 @@ public abstract class Model<M extends Model> implements Serializable {
 		return modifyFlag;
 		return modifyFlag;
 	}*/
 	}*/
 	
 	
-	Set<String> getModifyFlag() {
+	protected Set<String> _getModifyFlag() {
 		if (modifyFlag == null) {
 		if (modifyFlag == null) {
 			Config config = _getConfig();
 			Config config = _getConfig();
 			if (config == null)
 			if (config == null)
@@ -86,20 +173,10 @@ public abstract class Model<M extends Model> implements Serializable {
 		return modifyFlag;
 		return modifyFlag;
 	}
 	}
 	
 	
-	private String configName = null;
-	
-	/**
-	 * Switching data source, dialect and all config by configName
-	 */
-	public M use(String configName) {
-		this.configName = configName;
-		return (M)this;
-	}
-	
 	protected Config _getConfig() {
 	protected Config _getConfig() {
 		if (configName != null)
 		if (configName != null)
 			return DbKit.getConfig(configName);
 			return DbKit.getConfig(configName);
-		return DbKit.getConfig(getUsefulClass());
+		return DbKit.getConfig(_getUsefulClass());
 	}
 	}
 	
 	
 	/*
 	/*
@@ -107,8 +184,24 @@ public abstract class Model<M extends Model> implements Serializable {
 		return DbKit.getConfig(getUsefulClass());
 		return DbKit.getConfig(getUsefulClass());
 	}*/
 	}*/
 	
 	
-	private Table getTable() {
-		return TableMapping.me().getTable(getUsefulClass());
+	protected Table _getTable() {
+		return TableMapping.me().getTable(_getUsefulClass());
+	}
+	
+	protected Class<? extends Model> _getUsefulClass() {
+		Class c = getClass();
+		// guice : Model$$EnhancerByGuice$$40471411
+		// cglib : com.demo.blog.Blog$$EnhancerByCGLIB$$69a17158
+		// return c.getName().indexOf("EnhancerByCGLIB") == -1 ? c : c.getSuperclass();
+		return c.getName().indexOf("$$EnhancerBy") == -1 ? c : c.getSuperclass();
+	}
+	
+	/**
+	 * Switching data source, dialect and all config by configName
+	 */
+	public M use(String configName) {
+		this.configName = configName;
+		return (M)this;
 	}
 	}
 	
 	
 	/**
 	/**
@@ -119,13 +212,13 @@ public abstract class Model<M extends Model> implements Serializable {
 	 * @throws ActiveRecordException if the attribute is not exists of the model
 	 * @throws ActiveRecordException if the attribute is not exists of the model
 	 */
 	 */
 	public M set(String attr, Object value) {
 	public M set(String attr, Object value) {
-		Table table = getTable();	// table 为 null 时用于未启动 ActiveRecordPlugin 的场景
+		Table table = _getTable();	// table 为 null 时用于未启动 ActiveRecordPlugin 的场景
 		if (table != null && !table.hasColumnLabel(attr)) {
 		if (table != null && !table.hasColumnLabel(attr)) {
 			throw new ActiveRecordException("The attribute name does not exist: \"" + attr + "\"");
 			throw new ActiveRecordException("The attribute name does not exist: \"" + attr + "\"");
 		}
 		}
 		
 		
 		attrs.put(attr, value);
 		attrs.put(attr, value);
-		getModifyFlag().add(attr);	// Add modify flag, update() need this flag.
+		_getModifyFlag().add(attr);	// Add modify flag, update() need this flag.
 		return (M)this;
 		return (M)this;
 	}
 	}
 	
 	
@@ -350,7 +443,7 @@ public abstract class Model<M extends Model> implements Serializable {
 			throw new ActiveRecordException("pageNumber and pageSize must more than 0");
 			throw new ActiveRecordException("pageNumber and pageSize must more than 0");
 		}
 		}
 		if (config.dialect.isTakeOverModelPaginate()) {
 		if (config.dialect.isTakeOverModelPaginate()) {
-			return config.dialect.takeOverModelPaginate(conn, getUsefulClass(), pageNumber, pageSize, isGroupBySql, totalRowSql, findSql, paras);
+			return config.dialect.takeOverModelPaginate(conn, _getUsefulClass(), pageNumber, pageSize, isGroupBySql, totalRowSql, findSql, paras);
 		}
 		}
 		
 		
 		List result = Db.query(config, conn, totalRowSql, paras);
 		List result = Db.query(config, conn, totalRowSql, paras);
@@ -407,30 +500,13 @@ public abstract class Model<M extends Model> implements Serializable {
 	}
 	}
 	
 	
 	/**
 	/**
-	 * Return attribute Map.
-	 * <p>
-	 * Danger! The update method will ignore the attribute if you change it directly.
-	 * You must use set method to change attribute that update method can handle it.
-	 */
-	protected Map<String, Object> _getAttrs() {
-		return attrs;
-	}
-	
-	/**
-	 * Return attribute Set.
-	 */
-	public Set<Entry<String, Object>> _getAttrsEntrySet() {
-		return attrs.entrySet();
-	}
-	
-	/**
 	 * Save model.
 	 * Save model.
 	 */
 	 */
 	public boolean save() {
 	public boolean save() {
 		filter(FILTER_BY_SAVE);
 		filter(FILTER_BY_SAVE);
 		
 		
 		Config config = _getConfig();
 		Config config = _getConfig();
-		Table table = getTable();
+		Table table = _getTable();
 		
 		
 		StringBuilder sql = new StringBuilder();
 		StringBuilder sql = new StringBuilder();
 		List<Object> paras = new ArrayList<Object>();
 		List<Object> paras = new ArrayList<Object>();
@@ -451,7 +527,7 @@ public abstract class Model<M extends Model> implements Serializable {
 			config.dialect.fillStatement(pst, paras);
 			config.dialect.fillStatement(pst, paras);
 			result = pst.executeUpdate();
 			result = pst.executeUpdate();
 			config.dialect.getModelGeneratedKey(this, pst, table);
 			config.dialect.getModelGeneratedKey(this, pst, table);
-			getModifyFlag().clear();
+			_getModifyFlag().clear();
 			return result >= 1;
 			return result >= 1;
 		} catch (Exception e) {
 		} catch (Exception e) {
 			throw new ActiveRecordException(e);
 			throw new ActiveRecordException(e);
@@ -464,7 +540,7 @@ public abstract class Model<M extends Model> implements Serializable {
 	 * Delete model.
 	 * Delete model.
 	 */
 	 */
 	public boolean delete() {
 	public boolean delete() {
-		Table table = getTable();
+		Table table = _getTable();
 		String[] pKeys = table.getPrimaryKey();
 		String[] pKeys = table.getPrimaryKey();
 		Object[] ids = new Object[pKeys.length];
 		Object[] ids = new Object[pKeys.length];
 		for (int i=0; i<pKeys.length; i++) {
 		for (int i=0; i<pKeys.length; i++) {
@@ -483,7 +559,7 @@ public abstract class Model<M extends Model> implements Serializable {
 	public boolean deleteById(Object idValue) {
 	public boolean deleteById(Object idValue) {
 		if (idValue == null)
 		if (idValue == null)
 			throw new IllegalArgumentException("idValue can not be null");
 			throw new IllegalArgumentException("idValue can not be null");
-		return deleteById(getTable(), idValue);
+		return deleteById(_getTable(), idValue);
 	}
 	}
 	
 	
 	/**
 	/**
@@ -492,7 +568,7 @@ public abstract class Model<M extends Model> implements Serializable {
 	 * @return true if delete succeed otherwise false
 	 * @return true if delete succeed otherwise false
 	 */
 	 */
 	public boolean deleteById(Object... idValues) {
 	public boolean deleteById(Object... idValues) {
-		Table table = getTable();
+		Table table = _getTable();
 		if (idValues == null || idValues.length != table.getPrimaryKey().length)
 		if (idValues == null || idValues.length != table.getPrimaryKey().length)
 			throw new IllegalArgumentException("Primary key nubmer must equals id value number and can not be null");
 			throw new IllegalArgumentException("Primary key nubmer must equals id value number and can not be null");
 		
 		
@@ -519,11 +595,11 @@ public abstract class Model<M extends Model> implements Serializable {
 	public boolean update() {
 	public boolean update() {
 		filter(FILTER_BY_UPDATE);
 		filter(FILTER_BY_UPDATE);
 		
 		
-		if (getModifyFlag().isEmpty()) {
+		if (_getModifyFlag().isEmpty()) {
 			return false;
 			return false;
 		}
 		}
 		
 		
-		Table table = getTable();
+		Table table = _getTable();
 		String[] pKeys = table.getPrimaryKey();
 		String[] pKeys = table.getPrimaryKey();
 		for (String pKey : pKeys) {
 		for (String pKey : pKeys) {
 			Object id = attrs.get(pKey);
 			Object id = attrs.get(pKey);
@@ -534,7 +610,7 @@ public abstract class Model<M extends Model> implements Serializable {
 		Config config = _getConfig();
 		Config config = _getConfig();
 		StringBuilder sql = new StringBuilder();
 		StringBuilder sql = new StringBuilder();
 		List<Object> paras = new ArrayList<Object>();
 		List<Object> paras = new ArrayList<Object>();
-		config.dialect.forModelUpdate(table, attrs, getModifyFlag(), sql, paras);
+		config.dialect.forModelUpdate(table, attrs, _getModifyFlag(), sql, paras);
 		
 		
 		if (paras.size() <= 1) {	// Needn't update
 		if (paras.size() <= 1) {	// Needn't update
 			return false;
 			return false;
@@ -546,7 +622,7 @@ public abstract class Model<M extends Model> implements Serializable {
 			conn = config.getConnection();
 			conn = config.getConnection();
 			int result = Db.update(config, conn, sql.toString(), paras.toArray());
 			int result = Db.update(config, conn, sql.toString(), paras.toArray());
 			if (result >= 1) {
 			if (result >= 1) {
-				getModifyFlag().clear();
+				_getModifyFlag().clear();
 				return true;
 				return true;
 			}
 			}
 			return false;
 			return false;
@@ -565,7 +641,7 @@ public abstract class Model<M extends Model> implements Serializable {
 		PreparedStatement pst = conn.prepareStatement(sql);
 		PreparedStatement pst = conn.prepareStatement(sql);
 		config.dialect.fillStatement(pst, paras);
 		config.dialect.fillStatement(pst, paras);
 		ResultSet rs = pst.executeQuery();
 		ResultSet rs = pst.executeQuery();
-		List<M> result = config.dialect.buildModelList(rs, getUsefulClass());	// ModelBuilder.build(rs, getUsefulClass());
+		List<M> result = config.dialect.buildModelList(rs, _getUsefulClass());	// ModelBuilder.build(rs, getUsefulClass());
 		DbKit.close(rs, pst);
 		DbKit.close(rs, pst);
 		return result;
 		return result;
 	}
 	}
@@ -662,7 +738,7 @@ public abstract class Model<M extends Model> implements Serializable {
 	 * @param columns the specific columns to load
 	 * @param columns the specific columns to load
 	 */
 	 */
 	public M findByIdLoadColumns(Object[] idValues, String columns) {
 	public M findByIdLoadColumns(Object[] idValues, String columns) {
-		Table table = getTable();
+		Table table = _getTable();
 		if (table.getPrimaryKey().length != idValues.length)
 		if (table.getPrimaryKey().length != idValues.length)
 			throw new IllegalArgumentException("id values error, need " + table.getPrimaryKey().length + " id value");
 			throw new IllegalArgumentException("id values error, need " + table.getPrimaryKey().length + " id value");
 		
 		
@@ -672,33 +748,13 @@ public abstract class Model<M extends Model> implements Serializable {
 	}
 	}
 	
 	
 	/**
 	/**
-	 * Set attributes with other model.
-	 * @param model the Model
-	 * @return this Model
-	 */
-	public M _setAttrs(M model) {
-		return (M)_setAttrs(model._getAttrs());
-	}
-	
-	/**
-	 * Set attributes with Map.
-	 * @param attrs attributes of this model
-	 * @return this Model
-	 */
-	public M _setAttrs(Map<String, Object> attrs) {
-		for (Entry<String, Object> e : attrs.entrySet())
-			set(e.getKey(), e.getValue());
-		return (M)this;
-	}
-	
-	/**
 	 * Remove attribute of this model.
 	 * Remove attribute of this model.
 	 * @param attr the attribute name of the model
 	 * @param attr the attribute name of the model
 	 * @return this model
 	 * @return this model
 	 */
 	 */
 	public M remove(String attr) {
 	public M remove(String attr) {
 		attrs.remove(attr);
 		attrs.remove(attr);
-		getModifyFlag().remove(attr);
+		_getModifyFlag().remove(attr);
 		return (M)this;
 		return (M)this;
 	}
 	}
 	
 	
@@ -711,7 +767,7 @@ public abstract class Model<M extends Model> implements Serializable {
 		if (attrs != null)
 		if (attrs != null)
 			for (String a : attrs) {
 			for (String a : attrs) {
 				this.attrs.remove(a);
 				this.attrs.remove(a);
-				this.getModifyFlag().remove(a);
+				this._getModifyFlag().remove(a);
 			}
 			}
 		return (M)this;
 		return (M)this;
 	}
 	}
@@ -725,7 +781,7 @@ public abstract class Model<M extends Model> implements Serializable {
 			Entry<String, Object> e = it.next();
 			Entry<String, Object> e = it.next();
 			if (e.getValue() == null) {
 			if (e.getValue() == null) {
 				it.remove();
 				it.remove();
-				getModifyFlag().remove(e.getKey());
+				_getModifyFlag().remove(e.getKey());
 			}
 			}
 		}
 		}
 		return (M)this;
 		return (M)this;
@@ -744,7 +800,7 @@ public abstract class Model<M extends Model> implements Serializable {
 			for (String a : attrs) {
 			for (String a : attrs) {
 				if (this.attrs.containsKey(a))	// prevent put null value to the newColumns
 				if (this.attrs.containsKey(a))	// prevent put null value to the newColumns
 					newAttrs.put(a, this.attrs.get(a));
 					newAttrs.put(a, this.attrs.get(a));
-				if (this.getModifyFlag().contains(a))
+				if (this._getModifyFlag().contains(a))
 					newModifyFlag.add(a);
 					newModifyFlag.add(a);
 			}
 			}
 			this.attrs = newAttrs;
 			this.attrs = newAttrs;
@@ -752,7 +808,7 @@ public abstract class Model<M extends Model> implements Serializable {
 		}
 		}
 		else {
 		else {
 			this.attrs.clear();
 			this.attrs.clear();
-			this.getModifyFlag().clear();
+			this._getModifyFlag().clear();
 		}
 		}
 		return (M)this;
 		return (M)this;
 	}
 	}
@@ -765,16 +821,16 @@ public abstract class Model<M extends Model> implements Serializable {
 	public M keep(String attr) {
 	public M keep(String attr) {
 		if (attrs.containsKey(attr)) {	// prevent put null value to the newColumns
 		if (attrs.containsKey(attr)) {	// prevent put null value to the newColumns
 			Object keepIt = attrs.get(attr);
 			Object keepIt = attrs.get(attr);
-			boolean keepFlag = getModifyFlag().contains(attr);
+			boolean keepFlag = _getModifyFlag().contains(attr);
 			attrs.clear();
 			attrs.clear();
-			getModifyFlag().clear();
+			_getModifyFlag().clear();
 			attrs.put(attr, keepIt);
 			attrs.put(attr, keepIt);
 			if (keepFlag)
 			if (keepFlag)
-				getModifyFlag().add(attr);
+				_getModifyFlag().add(attr);
 		}
 		}
 		else {
 		else {
 			attrs.clear();
 			attrs.clear();
-			getModifyFlag().clear();
+			_getModifyFlag().clear();
 		}
 		}
 		return (M)this;
 		return (M)this;
 	}
 	}
@@ -785,7 +841,7 @@ public abstract class Model<M extends Model> implements Serializable {
 	 */
 	 */
 	public M clear() {
 	public M clear() {
 		attrs.clear();
 		attrs.clear();
-		getModifyFlag().clear();
+		_getModifyFlag().clear();
 		return (M)this;
 		return (M)this;
 	}
 	}
 	
 	
@@ -811,7 +867,7 @@ public abstract class Model<M extends Model> implements Serializable {
 	public boolean equals(Object o) {
 	public boolean equals(Object o) {
 		if (!(o instanceof Model))
 		if (!(o instanceof Model))
             return false;
             return false;
-		if (getUsefulClass() != ((Model)o).getUsefulClass())
+		if (_getUsefulClass() != ((Model)o)._getUsefulClass())
 			return false;
 			return false;
 		if (o == this)
 		if (o == this)
 			return true;
 			return true;
@@ -819,7 +875,7 @@ public abstract class Model<M extends Model> implements Serializable {
 	}
 	}
 	
 	
 	public int hashCode() {
 	public int hashCode() {
-		return (attrs == null ? 0 : attrs.hashCode()) ^ (getModifyFlag() == null ? 0 : getModifyFlag().hashCode());
+		return (attrs == null ? 0 : attrs.hashCode()) ^ (_getModifyFlag() == null ? 0 : _getModifyFlag().hashCode());
 	}
 	}
 	
 	
 	/**
 	/**
@@ -904,44 +960,12 @@ public abstract class Model<M extends Model> implements Serializable {
 	}
 	}
 	
 	
 	/**
 	/**
-	 * Return attribute names of this model.
-	 */
-	public String[] _getAttrNames() {
-		Set<String> attrNameSet = attrs.keySet();
-		return attrNameSet.toArray(new String[attrNameSet.size()]);
-	}
-	
-	/**
-	 * Return attribute values of this model.
-	 */
-	public Object[] _getAttrValues() {
-		java.util.Collection<Object> attrValueCollection = attrs.values();
-		return attrValueCollection.toArray(new Object[attrValueCollection.size()]);
-	}
-	
-	/**
 	 * Return json string of this model.
 	 * Return json string of this model.
 	 */
 	 */
 	public String toJson() {
 	public String toJson() {
 		return com.jfinal.kit.JsonKit.toJson(attrs);
 		return com.jfinal.kit.JsonKit.toJson(attrs);
 	}
 	}
 	
 	
-	protected Class<? extends Model> getUsefulClass() {
-		Class c = getClass();
-		// guice : Model$$EnhancerByGuice$$40471411
-		// cglib : com.demo.blog.Blog$$EnhancerByCGLIB$$69a17158
-		// return c.getName().indexOf("EnhancerByCGLIB") == -1 ? c : c.getSuperclass();
-		return c.getName().indexOf("$$EnhancerBy") == -1 ? c : c.getSuperclass();
-	}
-	
-	/**
-	 * filter () 方法将被 save()、update() 调用,可用于过滤类似于 XSS 攻击脚本
-	 * @param filterBy 0 表示当前正被 save() 调用, 1 表示当前正被 update() 调用
-	 */
-	protected void filter(int filterBy) {
-		
-	}
-	
 	public String getSql(String key) {
 	public String getSql(String key) {
 		return _getConfig().getSqlKit().getSql(key);
 		return _getConfig().getSqlKit().getSql(key);
 	}
 	}

+ 22 - 0
src/main/java/com/jfinal/plugin/redis/Cache.java

@@ -1148,6 +1148,28 @@ public class Cache {
 		finally {close(jedis);}
 		finally {close(jedis);}
 	}
 	}
 	
 	
+	/**
+	 * 删除当前 db 所有数据
+	 */
+	public String flushDB() {
+		Jedis jedis = getJedis();
+		try {
+			return jedis.flushDB();
+		}
+		finally {close(jedis);}
+	}
+	
+	/**
+	 * 删除所有 db 的所有数据
+	 */
+	public String flushAll() {
+		Jedis jedis = getJedis();
+		try {
+			return jedis.flushAll();
+		}
+		finally {close(jedis);}
+	}
+	
 	// ---------
 	// ---------
 	
 	
 	protected byte[] keyToBytes(Object key) {
 	protected byte[] keyToBytes(Object key) {

+ 98 - 99
src/main/java/com/jfinal/template/ext/spring/JFinalView.java

@@ -59,105 +59,105 @@ public class JFinalView extends AbstractTemplateView {
 		OutputStream os = response.getOutputStream();
 		OutputStream os = response.getOutputStream();
 		JFinalViewResolver.engine.getTemplate(getUrl()).render(model, os);
 		JFinalViewResolver.engine.getTemplate(getUrl()).render(model, os);
 	}
 	}
-}
 
 
-@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
-class InnerSession extends HashMap<Object, Object> implements HttpSession {
-	
-	private static final long serialVersionUID = -8679493647540628009L;
-	private HttpSession session;
-	
-	public InnerSession(HttpSession session) {
-		this.session = session;
-	}
-	
-	// HashMap 相关方法处理 ----------------------------------------------------
-	/**
-	 * 覆盖 HashMap 的 put
-	 */
-	public Object put(Object name, Object value) {
-		session.setAttribute((String)name, value);
-		return null;
-	}
-	
-	/**
-	 * 覆盖 HashMap 的 get
-	 */
-	public Object get(Object name) {
-		return session.getAttribute((String)name);
-	}
-	
-	// Session 相关方法处理 ----------------------------------------------------
-	public Object getAttribute(String key) {
-		return session.getAttribute(key);
-	}
-	
-	public Enumeration getAttributeNames() {
-		return session.getAttributeNames();
-	}
-	
-	public long getCreationTime() {
-		return session.getCreationTime();
-	}
-	
-	public String getId() {
-		return session.getId();
-	}
-	
-	public long getLastAccessedTime() {
-		return session.getLastAccessedTime();
-	}
-	
-	public int getMaxInactiveInterval() {
-		return session.getMaxInactiveInterval();
-	}
-	
-	public ServletContext getServletContext() {
-		return session.getServletContext();
-	}
-	
-	public javax.servlet.http.HttpSessionContext getSessionContext() {
-		return session.getSessionContext();
-	}
-	
-	public Object getValue(String key) {
-		return session.getValue(key);
-	}
-	
-	public String[] getValueNames() {
-		return session.getValueNames();
-	}
-	
-	public void invalidate() {
-		session.invalidate();
-	}
-	
-	public boolean isNew() {
-		return session.isNew();
-	}
-	
-	public void putValue(String key, Object value) {
-		session.putValue(key, value);
-	}
-	
-	public void removeAttribute(String key) {
-		session.removeAttribute(key);
-	}
-	
-	public void removeValue(String key) {
-		session.removeValue(key);
-	}
-	
-	public void setAttribute(String key, Object value) {
-		session.setAttribute(key, value);
-	}
-	
-	public void setMaxInactiveInterval(int maxInactiveInterval) {
-		session.setMaxInactiveInterval(maxInactiveInterval);
-	}
-	
-	public String toString() {
-		return session != null ? session.toString() : "null";
+	@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
+	public static class InnerSession extends HashMap<Object, Object> implements HttpSession {
+		
+		private static final long serialVersionUID = -8679493647540628009L;
+		private HttpSession session;
+		
+		public InnerSession(HttpSession session) {
+			this.session = session;
+		}
+		
+		// HashMap 相关方法处理 ----------------------------------------------------
+		/**
+		 * 覆盖 HashMap 的 put
+		 */
+		public Object put(Object name, Object value) {
+			session.setAttribute((String)name, value);
+			return null;
+		}
+		
+		/**
+		 * 覆盖 HashMap 的 get
+		 */
+		public Object get(Object name) {
+			return session.getAttribute((String)name);
+		}
+		
+		// Session 相关方法处理 ----------------------------------------------------
+		public Object getAttribute(String key) {
+			return session.getAttribute(key);
+		}
+		
+		public Enumeration getAttributeNames() {
+			return session.getAttributeNames();
+		}
+		
+		public long getCreationTime() {
+			return session.getCreationTime();
+		}
+		
+		public String getId() {
+			return session.getId();
+		}
+		
+		public long getLastAccessedTime() {
+			return session.getLastAccessedTime();
+		}
+		
+		public int getMaxInactiveInterval() {
+			return session.getMaxInactiveInterval();
+		}
+		
+		public ServletContext getServletContext() {
+			return session.getServletContext();
+		}
+		
+		public javax.servlet.http.HttpSessionContext getSessionContext() {
+			return session.getSessionContext();
+		}
+		
+		public Object getValue(String key) {
+			return session.getValue(key);
+		}
+		
+		public String[] getValueNames() {
+			return session.getValueNames();
+		}
+		
+		public void invalidate() {
+			session.invalidate();
+		}
+		
+		public boolean isNew() {
+			return session.isNew();
+		}
+		
+		public void putValue(String key, Object value) {
+			session.putValue(key, value);
+		}
+		
+		public void removeAttribute(String key) {
+			session.removeAttribute(key);
+		}
+		
+		public void removeValue(String key) {
+			session.removeValue(key);
+		}
+		
+		public void setAttribute(String key, Object value) {
+			session.setAttribute(key, value);
+		}
+		
+		public void setMaxInactiveInterval(int maxInactiveInterval) {
+			session.setMaxInactiveInterval(maxInactiveInterval);
+		}
+		
+		public String toString() {
+			return session != null ? session.toString() : "null";
+		}
 	}
 	}
 }
 }
 
 
@@ -166,4 +166,3 @@ class InnerSession extends HashMap<Object, Object> implements HttpSession {
 
 
 
 
 
 
-