浏览 3890 次
锁定老帖子 主题:让你的DBUtils支持enum
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-09-09
最后修改:2010-09-09
最近几天在研究Java分布式技术如:Socket、Mina、Web Service、Hessian、REST等。 今天早上看到DBUtils,试用了起来,并写了测试单元。
1、创建了一个日志表,用DBUtils读写日志,然后进行了测试,在测试过程中,发现 new BeanHandler<ActionLog>(ActionLog.class) 这个过程中出现有些数据为空 ,仔细一看数据库字段,如:log_id,log_tag有下划线的都取不出数据来 。然后google了一下发现JE里有个文章正好解决了这个问题:http://www.iteye.com/topic/381714
2、根据文章说的在 org.apache.commons.dbutils.BeanProcessor 添加了个方法columnPropEquals(表字段和类属性比较) private boolean columnPropEquals(String columnName, String propName) { { return (columnName.replace("_", "").equalsIgnoreCase(propName.replace("_", ""))); }} 并且在mapColumnsToProperties 中调用些方法 protected int[] mapColumnsToProperties(ResultSetMetaData rsmd, PropertyDescriptor[] props) throws SQLException { int cols = rsmd.getColumnCount(); int columnToProperty[] = new int[cols + 1]; Arrays.fill(columnToProperty, PROPERTY_NOT_FOUND); for (int col = 1; col <= cols; col++) { String columnName = rsmd.getColumnLabel(col); if (null == columnName || 0 == columnName.length()) { columnName = rsmd.getColumnName(col); } for (int i = 0; i < props.length; i++) { //在这里进行调用新的比较方法 if (columnPropEquals(columnName, props[i].getName())) { columnToProperty[col] = i; break; } } } return columnToProperty; } 3、继续跑单元测试,然后又报错 Exception in thread "main" java.sql.SQLException Cannot set logType: incompatible types. 然后我用DEBUG跟踪后发现是数据类型 的问题,BeanProcessor.callSetter 无法把Object 转成Enum类型 // Don't call setter if the value object isn't the right type if (this.isCompatibleType(value, params[0])) { setter.invoke(target, new Object[] { value }); }
4、找到BeanProcessor.callSetter 方法,在[3]中的if后面 添加了特有Enum类型的值设置 // Don't call setter if the value object isn't the right type if (this.isCompatibleType(value, params[0])) { setter.invoke(target, new Object[] { value }); } else if (params[0].isEnum()) { try { //value == null时,让Domain设置默认值 //只有value != null时对进行转换设置值 if(value != null) { //Class转换对应enum Class cz = Class.forName(params[0].getName()); setter.invoke(target, Enum.valueOf(cz, (String) value)); } } catch (ClassNotFoundException e) { throw new SQLException("Cannot set " + prop.getName() + ": incompatible types."); } } 5、继续跑单元测试,成功 ActionLog [logContent=测试, logId=1, logLevel=INFO, logSourceId=, logTag=测试, logType=ACTION, opdate=2010-09-08 05:53:22.0, opip=192.168.1.159, opuser=JWinder]
6、总结 有的时候发现很多开源的项目并没有我们想像得那么完美,当你发现不完美(缺陷)时,修正它,并把你的经验分享给每一个人,让别人站在你的时间上节约时间,所以希望大家一起分享你的快乐
7、附件,附上我的ActionLog和单元测试 ActionLog.java public class ActionLog implements Serializable { private static final long serialVersionUID = 1L; private Long logId; // 日志ID private LogType logType = LogType.NORMAL; // 日志类型 private LogLevel logLevel = LogLevel.INFO; // 事件级别 private String opuser; // 操作人ID private Date opdate; // 操作时间 private String opip; // 操作IP private String logSourceId; // 操作关联源对象ID private String logTag; // 操作事件内容标签(提供更好的搜索) private String logContent; // 事件内容 public enum LogType { /** 一般日志 */ NORMAL("NORMAL"), /** 登录日志 */ LOGIN("LOGIN"), /** 活动操作日志 */ ACTION("ACTION"), /** 错误日志 */ ERROR("ERROR"), ; private String name; LogType(String name) { this.name = name; } public String getName() { return this.name; } } public enum LogLevel { INFO("INFO"), SUCCESS("SUCCESS"), WARN("WARN"), ERROR("ERROR"), ; private String name; LogLevel(String name) { this.name = name; } public String getName() { return this.name; } } public Long getLogId() { return logId; } public void setLogId(Long logId) { this.logId = logId; } public LogType getLogType() { return logType; } public void setLogType(LogType logType) { this.logType = logType; } public LogLevel getLogLevel() { return logLevel; } public void setLogLevel(LogLevel logLevel) { this.logLevel = logLevel; } public String getOpuser() { return opuser; } public void setOpuser(String opuser) { this.opuser = opuser; } public Date getOpdate() { return opdate; } public void setOpdate(Date opdate) { this.opdate = opdate; } public String getOpip() { return opip; } public void setOpip(String opip) { this.opip = opip; } public String getLogSourceId() { return logSourceId; } public void setLogSourceId(String logSourceId) { this.logSourceId = logSourceId; } public String getLogTag() { return logTag; } public void setLogTag(String logTag) { this.logTag = logTag; } public String getLogContent() { return logContent; } public void setLogContent(String logContent) { this.logContent = logContent; } @Override public String toString() { return "ActionLog [logContent=" + logContent + ", logId=" + logId + ", logLevel=" + logLevel + ", logSourceId=" + logSourceId + ", logTag=" + logTag + ", logType=" + logType + ", opdate=" + opdate + ", opip=" + opip + ", opuser=" + opuser + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((logId == null) ? 0 : logId.hashCode()); result = prime * result + ((logLevel == null) ? 0 : logLevel.hashCode()); result = prime * result + ((logType == null) ? 0 : logType.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; ActionLog other = (ActionLog) obj; if (logId == null) { if (other.logId != null) return false; } else if (!logId.equals(other.logId)) return false; if (logLevel == null) { if (other.logLevel != null) return false; } else if (!logLevel.equals(other.logLevel)) return false; if (logType == null) { if (other.logType != null) return false; } else if (!logType.equals(other.logType)) return false; return true; } public static String getInsertSQL() { return ("INSERT INTO action_log (log_type, log_level, opuser, opdate, opip, log_source_id, log_tag, log_content) values (?, ?, ?, ?, ?, ?, ?, ?)"); } public static Object[] toArray(ActionLog log) { return new Object[] {log.logType, log.logLevel, log.opuser, log.opdate, log.opip, log.logSourceId, log.logTag, log.logContent}; } public static ActionLog getTestActionLog() { ActionLog log = new ActionLog(); log.setLogType(LogType.ACTION); log.setLogLevel(LogLevel.INFO); log.setOpuser("JWinder"); log.setOpdate(new Date()); log.setOpip("192.168.1.159"); log.setLogSourceId(""); log.setLogTag("测试 操作日志"); log.setLogContent("测试日志系统数据"); return log; } public static void main(String[] args) { System.err.println(LogType.ACTION); } } action_log表SQL create database logservice; use logservice; drop table `logservice`.`action_log`; create table `logservice`.`action_log`( `log_id` INT not null auto_increment, `log_type` VARCHAR(16) not null, `log_level` VARCHAR(16) not null, `opuser` VARCHAR(32) not null, `opdate` DATETIME not null, `opip` VARCHAR(32) not null, `log_source_id` VARCHAR(64), `log_tag` VARCHAR(256), `log_content` TEXT not null, primary key (`log_id`) );
DBUtilsTest.java public class DBUtilsTest { public static void main(String[] args) throws SQLException, ClassNotFoundException { // Connection conn = null; // Statement stmt = null; // ResultSet rs = null; // Class.forName("com.mysql.jdbc.Driver"); // conn = DriverManager.getConnection("jdbc:mysql://192.168.1.82:3306/logservice", "root", "123456"); // stmt = conn.createStatement(); // stmt.executeUpdate("INSERT INTO action_log (log_type, log_level, opuser, opdate, opip, log_source_id, log_tag, log_content) values " + // "('ACTION', 'INFO', 'JWinder','2010-09-08 05:53:22.123', '192.168.1.159', '', '测试 操作日志', '测试日志系统数据')"); DBUtilsTest example = new DBUtilsTest(); //example.batch(); //example.fillStatement(); //example.query(); //example.update(); example.qq(); example.closeDataSource(); } private DataSource dataSource = null; private QueryRunner runner = null; public DBUtilsTest() { initDataSource(); runner = new QueryRunner(dataSource); } private void closeDataSource() throws SQLException { ((BasicDataSource) dataSource).close(); } private DataSource initDataSource() { if (dataSource == null) { BasicDataSource basicDs = new BasicDataSource(); basicDs.setDriverClassName("com.mysql.jdbc.Driver"); basicDs.setUrl("jdbc:mysql://192.168.1.82:3306/logservice"); basicDs.setUsername("root"); basicDs.setPassword("123456"); this.dataSource = basicDs; } return dataSource; } private void qq() throws SQLException { String sql = "SELECT * FROM action_log WHERE log_id = ?"; ActionLog r4 = runner.query(sql, new BeanHandler<ActionLog>(ActionLog.class), "1"); System.out.println(" " + r4.toString()); } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-12-31
yes,的确如此,另外它好像对成员变量的类型为java.util.Date的字段也不能转换,所以我改了它的processColumn(ResultSet rs, int index,Class<?> propType)方法:
将 ... else if (propType.equals(Timestamp.class)) { return rs.getTimestamp(index); } ... 改为了 ... else if (propType.equals(java.util.Date.class) || propType.equals(Timestamp.class)) { //变动 return rs.getTimestamp(index); } else if (propType.equals(java.sql.Date.class)) { //变动 return rs.getDate(index); } else if (propType.equals(java.sql.Time.class)) { //变动 return rs.getTime(index); } ... |
|
返回顶楼 | |