JDBC提供了SQLException异常,它是一个检查异常,必须要捕获。 但该异常过于笼统,只要是数据访问发生问题都抛出这个异常。因此很难在抛出该异常后进行恢复,因此该异常就没有抛出的必要。 Spring对JDBC的异常进行了转换,并进行了扩充,使得异常更加具体化,能够根据异常来进行恢复。 此外,Spring的数据访问异常均继承自DataAccessException,它是一个非检查型异常,因此Spring的数据访问异常可抛可不抛。
Spring的数据访问采用了模板方法模式,模板方法定义了数据处理过程的主要框架,某些特定的步骤采用抽象函数的方式让子类去实现。这样子类在使用时只需关注数据访问逻辑即可,避免了大量重复代码。
Spring针对不同的持久化方案,提供了多种数据访问模板: - JdbcTemplate - NamedParameterJdbcTemplate - HibernateTemplate - SqlMapClientTemplate //MyBatis的模板
Spring提供了三种数据源配置方案: 1. 通过JDBC驱动程序定义的数据源; 2. 通过JNDI定义的数据源; 3. 通过连接池定义的数据源。
JNDI是 Java 命名与目录接口(Java Naming and Directory Interface)。 JNDI配置数据源就是将数据库的连接信息配置在Tomcat等Web容器中,这样数据库的连接信息完全可以在应用程序之外进行管理,当数据源发生变化时,就不需要修改程序代码。
Spring并没有提供数据库连接池的实现,但可以使用第三方开源方案。 只需定义一个名为dataSource的bean即可,并配置好各项连接信息。
只需定义一个名为dataSource的bean即可,并配置好各项连接信息。
Spring提供两种JDBC模板: 1. JdbcTemplate:基本的Jdbc模板 2. NamedParameterJdbcTemplate:在执行查询时,可以以命名参数的形式绑定到SQl中。
@Bean
public JdbcTemplate jdbcTemplate( DataSource dataSource ){
return new JdbcTemplate( dataSource );
}
@Repository
public class XXXDAOImpl implements XXXDAO{
private JdbcOptions jdbcOptions;
@Inject
public XXXDAOImpl( JdbcOptions jdbcOptions ){
this.jdbcOptions = jdbcOptions;
}
}
public void add(User user){
jdbcOptions.update(
"insert into user (username, passwd) values(?,?)",
user.getUsername(),
user.getPasswd()
);
}
public User get(long id){
return jdbcOptions.queryForObject(
"select username,passwd from user id=?",
new UserMapper(), // 结果映射对象
id // 参数
);
}
class UserMapper implments RowMapper<User> {
public User mapRow( ResultSet rs, int rowNum ){
return new User(
rs.getLong("id"),
rs.getString("username"),
rs.getPasswd("passwd")
);
}
}
JdbcTemplate中的参数是按照顺序传入的,也就是SQL中“问号”的顺序和参数的顺序要严格一致,而是用NamedParamterJdbcTemplate可以显示指定参数的顺序。
public void add(User user){
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("username",user.getUsername());
paramMap.put("passwd",user.getPasswd());
jdbcOptions.update(
"insert into user (username, passwd) values(:username, :passwd)",
paramMap
);
}