很多时候、我们做批量更新的时候不希望用hibernate,那么就可以考虑简单的做一点配置、就可以把很好的把springjdbc 整合到项目中。
用过hibernateTemplate的老程序员、肯定很多、springjdbc 也是用的模板方法: jdbctemplate,很方便的哦,注入就可以用咯。
simple eg:
@Autowired
private JdbcTemplate jdbcTemplate;
........
String sql=".......";
jdbcTemplate.execute(sql);
不言而喻、很简单、很好用,
配置文件: 配个数据源
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate"
p:dataSource-ref="dataSource"/>
具体的crud都可以用update方法去实现(insert,update,delete都可以使用update方法),
比如:
final String sql = "INSERT INTO t_forum(forum_name,forum_desc) VALUES(?,?)"; // 占位符 对应params
Object[] params = new Object[] { forum.getForumName(),
forum.getForumDesc() };
jdbcTemplate.update(sql, params);
接下来看如何获得自增主键
spring使用KeyHolder接口的一个实现类GeneratedKeyHolder返回每次插入后的自增键;
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection conn)
throws SQLException {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, forum.getForumName());
ps.setString(2, forum.getForumDesc());
return ps;
}
}, keyHolder);
forum.setForumId(keyHolder.getKey().intValue());
keyHolder.getKey().intValue()这里就获得了递增加的主键了;
好多年没有玩jdbc了。忘了那时候怎么获取刚刚自增的主键了。
接下来看下如何查询数据,这个是很基本的了,spring jdbc使用了
RowCallbackHandler的回调接口
String sql = "SELECT ......";
final List<Forum> forums = new ArrayList<Forum>();
jdbcTemplate.query(sql, new Object[]{fromId,toId}, new RowCallbackHandler(){
public void processRow(ResultSet rs) throws SQLException {
Forum forum = new Forum();
forum.setForumId(rs.getInt("forum_id"));
forum.setForumName(rs.getString("forum_name"));
forum.setForumDesc(rs.getString("forum_desc"));
forums.add(forum);
}}); return forums;
另外一种常用的方法是使用rowmapper处理结果集
@Override
public Person getPerson(String lastName) {
String query = "select personId, personFirstName, personLastName from personTbl where personLastName = ?";
return this.getJdbcTemplate().queryForObject(query, new PersonMapper(), lastName);
}
注意的是,这里用rowmapper方法的话,会自动把查出来的每个行记录集自动添加到List中去的,如果数量太多,比如100万个,则list很大,容易内存溢出;而采用
rowbcallbackhandler的话,则在processrow中获得数据后马上进行处理(比如群发邮件时,马上发送邮件)。
查询单值数据,典型的有如queryForObject,queryForInt;
int rowCount = this.getJdbcTemplate().queryForInt("select count(0) from personTbl");
return rowCount;
}
-
String firstName = this.getJdbcTemplate().queryForObject(
-
"select personFirstName from personTbl where personLastName = ?",
-
String.class,
-
lastName ) ;
NamedParameterJDBCTemplate,这是一个很好用的JDBC模板类,解决的是?号占位符号的麻烦(容易对错位置等)
例子如下:
String sql = "select count(0) from personTbl where personFirstName = :first_name";
SqlParameterSource namedParameters = new MapSqlParameterSource("first_name", firstName);
return this.getNamedParameterJdbcTemplate().queryForInt(sql, namedParameters);
这里可以看到,SQL中的使用:first_name了,并且用MapSqlParameterSource来进行绑定;还有种方法是使用BeanPropertySqlParameterSource;比如:
public List<Person> getPerson(Person personSkeleton)
{
SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(personSkeleton);
List<Person> people = this.getNamedParameterJdbcTemplate().query(
"select personID, personFirstName, personLastName from personTbl " +
" where personLastName = :personLastName and personFirstName = :personFirstName",
namedParameters,
new PersonMapper()
);
这里其实就是参数整个javabean传进来,其中:personLastName,personFirstName都必须是javabean中的属性,这样才能一一匹配;
还有一个就是simplejdbctemplate,例子如下:
public void addPerson(Person newPerson) {
SimpleJdbcInsert insertPerson =
new SimpleJdbcInsert(this.getDataSource())
.withTableName("personTbl").usingGeneratedKeyColumns("personID");
Map<String, Object> parameters = new HashMap<String, Object>(3);
parameters.put("personFirstName", newPerson.getPersonFirstName() );
parameters.put("personLastName", newPerson.getPersonLastName() );
insertPerson.execute(parameters);
}
也是很简单容易理解吧。
下面提及下最新的spring jdbc 3.2.2中,
queryForInt("select count(0) from personTbl")
这个写法换了,换成:
queryForObject("select count(0) from personTbl", Integer.class)
详细的更换和丢弃的方法见:
http://static.springsource.org/spring/docs/3.2.x/javadoc-api/deprecated-list.html