最近几天在研究Java分布式技术如:Socket、Mina、Web Service、Hessian、REST等。
今天早上看到DBUtils,试用了起来,并写了测试单元。
1、创建了一个日志表,用DBUtils读写日志,然后进行了测试,在测试过程中,发现
new BeanHandler(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.class), "1");
System.out.println(" " + r4.toString());
}
}