和时间赛跑
我要追上时间
和时间赛跑的人!
我的首页
文章
相册
圈子
留言
管理
 
    当前所在页面:首页>>文章>>Spring中的面向对象查询
Spring中的面向对象查询
    作者:erikchang 来源: 发表时间:2007-12-08

 
 
Spring JDBC的操作还是使用了sql语句,如果对sql不是非常熟悉的程序员可能在运用的过程中还有些麻烦,为此Spring提供了org.springframework.jdbc.object包来设计完全面向对象查询,只要封装一个面向对象的查询类,丝毫不用写任何的sql语句就可以完成JdbcTemplate所有的数据库操作功能。
public class User{
   
private Long id;
   
private String userName;
   
private String passWord;
   
//set/get方法
}

1org.springframework.jdbc.object.SqlQuery
SqlQuery是主查询类,他提供了强大的查询功能,不过他的查询返回值将会放到一个RowMapper中进行处理,所以在使用SqlQuery的时候要定义一个自己的RowMapper,然后给返回值放到自定义的RowMapper中,这样就完成了查询工作,示例如下:
首先定义一个UserRowMapper,该类实现RowMapper接口,代码如下:
public class UserRowMapper implements RowMapper {
    
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
        User user
=new User();
        user.setId(
new Long(rs.getLong("id")));
        user.setUserName(rs.getString(
"username"));
        user.setPassWord(rs.getString(
"password"));
        
return user;
    }

}

 

UserRowMapper类中只有一个mapRow方法,该方法就是将返回结果记录集ResultSet的值封装到User类中;
定义一个UserSqlQuery类,该类继承SqlQuery,代码如下:
public class UserSqlQuery extends SqlQuery {
    
public UserSqlQuery(DataSource dataSource){
        
super(dataSource,"select * from user where id=?");
        
int[] types={Types.LONGVARCHAR};
        setTypes(types);
        compile();
    }

    
protected RowMapper newRowMapper(Object[] args, Map map) {
        UserRowMapper urm
=new UserRowMapper();
        
return urm;
    }

}
 

 

UserSqlQuery类首先定义了一个构造函数,在构造函数中调用了SqlQuery中的
 SqlQuery(DataSource ds, String sql)完成数据源以及sql的注入,在sql中仍然用“?”作为占位符,int[] types数组为占位符设置sql字段属性,这里为LONGVARCHAR,最后调用compile()方法编译,执行sql返回值将有newRowMapper方法返回,这里我们直接使用了自定义的UserRowMapper来记录返回值,完成上述步骤后,就可以在UserDAOfind()方法中使用这个查询了:
public User find(Long id) {
        List list
=userSqlQuery.execute(new Object[]{id});
           
return (User)list.get(0);
    }

 

SqlQuery提供了很多的execute方法来执行查询,详情可以参考SpringAPI文档,这里使用了execute传递一个id参数,因为返回值是一个数组而且数组中只有一个User对象,所以直接使用了(User)list.get(0)
2org.springframework.jdbc.object.MappingSqlQuery
MappingSqlQuery类是SqlQuery类的子类,使用MappingSqlQuery查询就不用使用RowMapper处理返回值了,直接写一个UserMappingSqlQuery类类继承MappingSqlQuery,代码如下:
public class UserMappingSqlQuery extends MappingSqlQuery {
    
public UserMappingSqlQuery(DataSource dataSource) {
        
super(dataSource, "select * from user where id=?");
        
int[] types={Types.LONGVARCHAR};
        setTypes(types);
        compile();
    }

    
protected Object mapRow(ResultSet rs, int rowNum) throws SQLException {    User user=new User();
        user.setId(
new Long(rs.getLong("id")));
        user.setUserName(rs.getString(
"username"));
        user.setPassWord(rs.getString(
"password"));
        
return user;
    }

}

 

UserMappingSqlQuery中首先还是使用SqlQuery中的构造函数完成数据源和sql的注入,返回值直接通过mapRow方法来完成,接着就可以这么使用它了:
 UserMappingSqlQuery userMappingSqlQuery=new UserMappingSqlQuery(dataSource);
userMappingSqlQuery.execute(
new Object[]{id});

 

返回值还是一个list,list中就是查询出来的User对象。
3org.springframework.jdbc.object.SqlUpdate

SqlUpdate类用来表示一个类的更新,当然前面的SqlQueryMappiingSqlQuery同样可以执行更新的sql语句,不过Spring为了适应人们的编程习惯,特意设计了SqlUpdate类来执行更新(update)、记录(insert)等操作,SqlUpdate类的使用更加简单,只要通过构造函数完成数据源和sql注入即可,定义一个自己的UserSqlUpdate,代码如下:

public class UserSqlUpdate extends SqlUpdate {
    
public UserSqlUpdate(DataSource dataSource) {
        
super(dataSource, "insert into user (username,password) values (?,?)");
        
int[] types = { java.sql.Types.VARCHAR, java.sql.Types.VARCHAR };
        setTypes(types);
        compile();
    }

}

 构造方法和上面的SqlQueryMappingSqlQuery一样,这里不过多重复,接着就可以如下来使用了:

UserSqlUpdate userSqlUpdate=new UserSqlUpdate(dataSource);
User user
=new User();
user.setUserName(
"erikchang");
user.setPassWord(
"123456");
userSqlUpdate.update(
new Object[]{user.getUserName(),user.getPassWord});

SqlUpdate实例直接调用update方法来完成参数的传递以及sql的执行。

4org.springframework.jdbc.object.SqlFunction
SqlFunction类是MappingSqlQuery的一个子类,他也就是具备了MappingSqlQuery的所有功能,不过SqlFunction实例的调用使用runrunGeneric方法来完成,同样可以在run()runGeneric()方法中传递一个数组作为sql的参数,其中run()方法返回int类型的,一般用在数量的查询,runGenetic()方法返回一个对象,使用时首先定义一个UserSqlFucntion如下:
public class UserSqlFunction extends SqlFunction {
    
public UserSqlFunction(DataSource dataSource) {
        
super(dataSource, "select * from user where id=?");
        
int[] types = { Types.LONGVARCHAR };
        setTypes(types);
        compile();
    }

}

 接着就可以如下来查询:

UserSqlFunction userSqlFunction=new UserSqlFunction(dataSource);
(User)userSqlFunction.runGeneric(
new Object[]{id});

 如果在UserSqlFunction的构造函数中sql:select count(*) from user,在使用的时候就直接使用userSqlFunction.run();
文章系eirkchang所有,转载注明作者!

 
 

(阅读 )   评论数(:4)
评论】 【收藏】
评论:共4条
spring能面向对象查询吗?说白了spring只是实现简单的jdbc封装而已。他能像hibernate那样:“select c from com.demo.entity.Customer c where c.user=?"这样的真正面向对象查询吗?
评论人: 匿名用户     评论时间: 2007-12-09 10:30:06
hibernate难道不是对sql进行封装然后才能面向对象查询的吗?
评论人: erikchang     评论时间: 2007-12-09 13:38:37
看了楼主的文章,还是没明白Spring中如何实现面向对象的查询,这个方面一直不会。能说详细一点吗?
评论人: 匿名用户     评论时间: 2007-12-09 15:10:54
这里的面向对象查询,更多的是指spring jdbc封装提供的简化。楼上的请不要抠字眼。
评论人: 大峡     评论时间: 2007-12-14 09:53:31

发表评论:
发表人:
评论: 
    
 
关于我们 | 诚聘英才 | 联系我们 | 广告业务 | 网站地图 | 法律声明

EasyJF开源团队版权所有  建议使用1024*768分辨率