-
将数据访问的功能放到一个或多个专注于此项任务的组件,这样的组件称为数据访问对象。
-
编写良好的数据访问对象应该以接口的方式暴露功能,Spring 遵循面向对象中的 针对接口编程,将持久层隐藏在接口之后。
-
Spring 提供了统一的异常体系,提供了多个数据访问异常,分别描述异常发生所对应的问题,可以用在所支持的所有持久化方案中。
-
Spring 将数据访问过程中固定的和可变的部分划分为模板(template)和回调(callback),将过程中与特定实现的部分委托给接口,用接口的不同实现定义过程中的具体行为。
-
Spring 提供了在上下文中配置数据源 bean 的多种方式,包括通过 JDBC 驱动程序定义的数据源,通过 JNDI 查找的数据源 和 连接池的数据源。
-
位于 jee 命名空间的
<jee:jndi-lookup>
元素可以用于检索 JNDI 中的对象(包括数据源)并装配到 Spring 中,如<jee:jndi-lookup id="dataSource" jndi-name="/jdbc/xxxDS" resource-ref="true">
。resource-ref 属性为 true 时,jndi-name 将会自动添加"java:comp/env/"前缀。 -
JavaConfig 配置 JNDI:
@Bean public JndiObjectFactoryBean dataSource() { JndiObjectFactoryBean jndiObjectFB = new JndiObjectFactoryBean(); jndiObjectFB.setJndiname("jdbc/xxxDS"); jndiObjectFB.setResourceRef(true); jndiObjectFB.setProxyInterface(javax.sql.DataSource.class); return jndiObjectFB; }
-
Spring 中可直接配置数据源连接池,虽然 Spring 中未提供数据源连接池的实现,但有多项可用方案,如c3p0、BoneCP 等开源实现。
-
Spring 提供了通过 JDBC 驱动定义数据源的类,例如:
@Bean public DataSource dateSource() { DriverManagerDataSource ds = new DriverManagerDataSource(); ds.setDriverClassName("org.h2.Driver"); ds.setUrl("jdbc:xxxxx"); ds.setUsername("root"); ds.setPassword(""); return ds; }
-
配合
@Profile
注解可以从多个数据源中选择需要的数据源。 -
Spring 的 JDBC 框架负责管理资源和处理异常,开发者只需编写从数据库读写数据的必须代码,从而简化 JDBC 代码。需要使用命名参数时,需要使用
NamedParameterJdbcTemplate
,对于多数 JDBC 任务来说JdbcTemplate
就是最好的选择。 -
JdbcTemplate 需要 DataSource 参数,可以在需要 JDBCTemplate 的位置声明 JdbcOperations 接口,并注入 JdbcTemplate 对象。
-
RowMapper 用于从 ResultSet 中提取数据并构建域对象,如
private static final class SpitterRowMapper implements RowMapper<Spitter> { public Spitter mapRow(ResultSet rs, int rowNum) throws SQLException { long id = rs.getLong("id"); String username = rs.getString("username"); String password = rs.getString("password"); String fullName = rs.getString("fullname"); String email = rs.getString("email"); boolean updateByEmail = rs.getBoolean("updateByEmail"); return new Spitter(id, username, password, fullName, email, updateByEmail); } }
-
几个 JdbcTemplate 使用示例:
public long count() { return jdbcTemplate.queryForLong("select count(id) from Spitter"); }
public Spitter save(Spitter spitter) {
Long id = spitter.getId();
if (id == null) {
long spitterId = insertSpitterAndReturnId(spitter);
return new Spitter(spitterId, spitter.getUsername());
} else {
jdbcTemplate.update("update Spitter set username=?",
spitter.getUsername(),
spitter.getPassword(),
id);
}
return spitter;
}private long insertSpitterAndReturnId(Spitter spitter) {
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate).withTableName("Spitter");
jdbcInsert.setGeneratedKeyName("id");
Map<String, Object> args = new HashMap<String, Object>();
args.put("username", spitter.getUsername());
args.put("password", spitter.getPassword());
long spitterId = jdbcInsert.executeAndReturnKey(args).longValue();
return spitterId;
}public Spitter findOne(long id) {
return jdbcTemplate.queryForObject(
SELECT_SPITTER + " where id=?", new SpitterRowMapper(), id);
}public void delete(long id) {
jdbcTemplate.update("delete from Spittle where id=?", id);
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于