精华帖 (0) :: 良好帖 (0) :: 新手帖 (17) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-05-25
最后修改:2010-05-26
ActiveRecordBase通过反射和命名约定,自动匹配子类属性和子类指定表字段。 例User.userId <-> t_user.user_id等等 ActiveRecordBase里还内置了Spring JdbcTemplate(非常好用的东西,推荐还在使用Jdbc的同学使用). public class User extends ActiveRecordBase { public User() { this.setTableName_("t_user"); } public BigDecimal userId; public String userName; public String password; public Timestamp insertTime; public String toString(){ return "user_id="+this.userId+" userName="+this.getUserName()+" password="+this.getPassword()+" insert_time"+this.getInsertTime(); } public static void main(String[] args) throws Exception { User user = new User(); user.setUserId(new BigDecimal(1)); user.setUserName("user"); user.setPassword("pwd"); user.setInsertTime(new Timestamp(new Date().getTime())); //save object to db user.insert(); System.out.println("t_user info after insert:"+(User)user.getJdbcTemplate_().queryForObject("select * from t_user where user_id="+user.userId,new BeanPropertyRowMapper(User.class))); user.setPassword("pwdChanged"); //update user.update(); System.out.println("t_user info after update:"+(User)user.getJdbcTemplate_().queryForObject("select * from t_user where user_id="+user.userId,new BeanPropertyRowMapper(User.class))); user.delete(); System.out.println("t_user count after delete:"+user.getJdbcTemplate_().queryForInt("select count(1) from t_user where user_id="+user.userId)); } } 测试结果: --一条记录生成了 Activerecord sql=INSERT INTO T_USER(USER_ID,USER_NAME,PASSWORD,INSERT_TIME) VALUES (?,?,?,?) t_user info after insert:user_id=1 userName=user password=pwd insert_time2010-05-24 00:00:00.0 --password被修改了 Activerecord sql=UPDATE T_USER SET USER_ID=?,USER_NAME=?,PASSWORD=?,INSERT_TIME=? WHERE USER_ID=? t_user info after update:user_id=1 userName=user password=pwdChanged insert_time2010-05-24 00:00:00.0 --记录被删除了 Activerecord sql=DELETE FROM T_USER WHERE USER_ID=? t_user count after delete:0 注意:User类main方法里的sql语句仅仅是为了使用JdbcTemplate来验证ActiveRecord的操作是成功的,本身并不需要sql语句。但我们同时也可以看到JdbcTemplate的强大,使用BeanPropertyRowMapper后,具有一条语句将表直接映射成对象的能力。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-05-25
ActiveRecordBase中动态组合sql。以insert和delete为例:
public class ActiveRecordBase { public String tableName_; public void insert() { SqlParameters sqlParams = this.getInsertSqlParams(); this.getJdbcTemplate_().update(sqlParams.getSql(), sqlParams.getParameters(), sqlParams.getTypes()); } public SqlParameters getInsertSqlParams() { SqlParameters sqlParams = new SqlParameters(); List tableColumnsList = this.getTableColumns(); Iterator iter = tableColumnsList.iterator(); StringBuffer placeholder = new StringBuffer(""); StringBuffer insertStr = new StringBuffer("INSERT INTO ").append( this.getTableName_()).append("("); Object[] params = new Object[tableColumnsList.size()]; int[] types = new int[tableColumnsList.size()]; int index = 0; for (int i = 0; i < tableColumnsList.size(); i++) { Column c = (Column) iter.next(); params[index] = getClassProperties().get(c.getColumnName()); types[index] = c.getColumnType(); index++; insertStr.append(c.getColumnName()); placeholder.append("?"); if (index != tableColumnsList.size()) { insertStr.append(","); placeholder.append(","); } } insertStr.append(") VALUES (").append(placeholder).append(")"); sqlParams.setSql(insertStr.toString()); sqlParams.setParameters(params); sqlParams.setTypes(types); return sqlParams; } public void delete() { StringBuffer sql = new StringBuffer("DELETE FROM ").append( this.getTableName_()).append(" WHERE ").append( this.getPK().getColumnName()).append("=?"); Object[] params = new Object[] { this.getClassProperties().get( this.getPK().getColumnName()) }; this.getJdbcTemplate_().update(sql.toString(), params); } } |
|
返回顶楼 | |
发表时间:2010-05-25
第一次执行时,取表结构。取到后cache住。
public List getTableColumns() { if (Cache.tableColumnsCache.get(this.getTableName_()) == null) { List list = (List) jdbcTemplate_.execute(new ConnectionCallback() { public Object doInConnection(Connection con) throws SQLException, DataAccessException { DatabaseMetaData dbMetaData = con.getMetaData(); ResultSet rsColumns = dbMetaData.getColumns(null, null, getTableName_(), null); List columnsList = new ArrayList(); while (rsColumns.next()) { Column c = new Column(); c.setColumnName(rsColumns.getObject(4).toString() .toUpperCase()); c.setColumnType(((BigDecimal) rsColumns.getObject(5)) .intValue()); columnsList.add(c); } ResultSet rsPK = dbMetaData.getPrimaryKeys(null, null, getTableName_()); if (rsPK.next()) { Column c = new Column(); c.setColumnName(rsPK.getObject(4).toString()); c.setColumnType(((BigDecimal) rsPK.getObject(5)) .intValue()); Cache.tablePKCache.put(getTableName_(), c); } return columnsList; } }); Cache.tableColumnsCache.put(this.getTableName_(), list); } return (List) Cache.tableColumnsCache.get(this.getTableName_()); } |
|
返回顶楼 | |
发表时间:2010-05-27
这种方案似乎没考虑多表的情况,比如父子关系。
|
|
返回顶楼 | |
发表时间:2010-05-27
我觉得找表结构不好,要通过bean反射
|
|
返回顶楼 | |
发表时间:2010-05-27
joehe 写道 我觉得找表结构不好,要通过bean反射
1. 值就是通过反射得到的。 2. 如果user表中有一些不属于表本身的属性时,我需要取bean的属性和表结构的共同部分,所以表结构还是要取的。 |
|
返回顶楼 | |
发表时间:2010-05-27
可以看看http://www.scooterframework.com的activerecord实现,目前发现这个框架挺强的,相对于playframework来说,controller全都是静态方法来说好多了~~
|
|
返回顶楼 | |
发表时间:2010-05-27
Arden 写道 可以看看http://www.scooterframework.com的activerecord实现,目前发现这个框架挺强的,相对于playframework来说,controller全都是静态方法来说好多了~~
谢谢,我之前看过他们。但我不太能接受他这样的写法,它不是直接操作属性,而是全部用setData(key, value)来做的。 http://www.scooterframework.com/docs/activerecord_basics.html Create a record in database: ActiveRecord post = new Post(); post.setData("title", "Happy Java Programming"); post.setData("body", "Java programming is fun."); post.create(); The last line above is equivalent to the following sql statement: insert into posts (title, body) values ('Happy Java Programming', 'Java programming is fun.'); |
|
返回顶楼 | |
发表时间:2010-06-19
最近花时间完善了一下,现在稳定下来的api如下:
特别是findByWhere,支持任何查找条件,就是支持写where条件的sql。对Jdbc熟悉的人来说,用起来几乎没有任何学习曲线。 --按主键查找,pk为1的 User user = (User)User.find(User.Class,1); --查找user_name="sean.zhou"的 User user = (User)User.findByWhere(User.Class,"user_name = ?", new Object[]{"sean.zhou"}); --查找所有sean打头的 List<User> users = User.findList(User.class,"user_name like ?", new Object[]{"sean%"}); --插入一条新记录 user.insert(); --更新记录 user.update(); --删除记录 user.delete(); |
|
返回顶楼 | |
发表时间:2010-06-19
最后修改:2010-06-19
建议楼主考虑下一对多和多对多的情况,还有就是联合主键的情况,还有查询的时候如果是单表的最好把查询条件封装对象
|
|
返回顶楼 | |