-
JDBC的__优势__
(1) 不需要掌握其他查询语言, 建立在SQL之上
(2) 可以在比较底层处理数据, 便于对数据访问进行性能调优
-
失控的JDBC代码
(1) 如果直接使用JDBC提供的操作数据库的API, 那么总是要写很多"模板代码": 建立连接、 准备语句、 关闭资源、 catch异常
(2) 这些代码都是必要的, 否则会有资源泄漏的隐患
-
使用JDBC模板
(1) Spring将数据访问的模板代码抽象到了模板方法类之中
(2) Spring提供了三个模板类
1° JdbcTemplate
2° NamedParameterJdbcTemplate
3° SimpleJdbcTemplate
对于大多数JDBC任务来说, 使用JdbcTemplate都是最好的方案
(3) 将DataSource装配到一个JdbcTemplate对象中; 将JdbcTemplate装配到操作数据的Repository对象中, 就可以使用了!
示例
@Configuration public class JdbcConfig { @Bean @Profile("embedded") public DataSource dataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .addScripts("classpath:spittr/db/jdbc/schema.sql", "classpath:spittr/db/jdbc/test-data.sql") .build(); } @Bean public JdbcTemplate jdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } @Bean public SpitterRepository spitterRepository(JdbcTemplate jdbcTemplate) { return new JdbcSpitterRepository(jdbcTemplate); } @Bean public SpittleRepository spittleRepository(JdbcTemplate jdbcTemplate) { return new JdbcSpittleRepository(jdbcTemplate); } }
这样, 样本代码就被隐藏在JdbcTemplate类中了
-
RowMapper接口
(1) 源码
public interface RowMapper<T> { T mapRow(ResultSet rs, int rowNum) throws SQLException; }
(2) 作用: 将ResultSet返回的每一行数据封装成用户自定义的对象, 从而实现解耦
(3) 对于查询返回的每一行数据, JdbcTemplate都会调用一次RowMapper的mapRow()方法
(4) 实现示例
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); } }
-
增删改查的实现
public class JdbcSpitterRepository implements SpitterRepository { private JdbcTemplate jdbcTemplate; public JdbcSpitterRepository(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } ... }
(1) 增
1° 不需要获取结果
jdbcTemplate.update("INSERT INTO Spitter (username, password, fullname, email, updateByEmail) VALUES (?, ?, ?, ?, ?)", spitter.getUsername(), spitter.getPassword(), spitter.getFullName(), spitter.getEmail(), spitter.isUpdateByEmail());
函数形式
public int update(String sql, Object... args) throws DataAccessException
返回的是插入操作影响的行数
2° 使用SimpleJdbcInsert对象获取插入的某一列的结果
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()); args.put("fullname", spitter.getFullName()); args.put("email", spitter.getEmail()); args.put("updateByEmail", spitter.isUpdateByEmail()); long spitterId = jdbcInsert.executeAndReturnKey(args).longValue();
在指定了key为id以后, 可以在执行后获取key的值
(2) 删
jdbcTemplate.update("DELETE FROM Spittle WHERE id=?", id);
(3) 改
jdbcTemplate.update("UPDATE Spitter SET username=?, password=?, fullname=?, email=?, updateByEmail=? where id=?", spitter.getUsername(), spitter.getPassword(), spitter.getFullName(), spitter.getEmail(), spitter.isUpdateByEmail(), id);
(4) 查
1° 使用RowMapper接口, 返回一行
Spitter spitter = jdbcTemplate.queryForObject( "SELECT id, username, password, fullname, email, updateByEmail FROM Spitter WHERE id=?", new SpitterRowMapper(), id);
其中, SpitterRowMapper是我们实现的RowMapper接口, 它会将ResultSet的一行包装成我们需要的对象
函数形式是
public <T> T queryForObject( String sql, RowMapper<T> rowMapper, Object... args) throws DataAccessException;
2° 使用RowMapper接口, 返回一个List
List<Spitter> spitterList = jdbcTemplate.query( "SELECT id, username, password, fullname, email, updateByEmail FROM Spitter ORDER BY id", new SpitterRowMapper());
函数形式是
public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException;
3° 不带RowMapper的形式
long count = jdbcTemplate.queryForObject( "SELECT COUNT(id) FROM Spitter", Long.class);
函数形式是
public <T> T queryForObject(String sql, Class<T> requiredType) throws DataAccessException
需要什么类型的返回值, 在Class中指定;
阅读源码可以发现, 其实内部也有一个默认实现的SingleColumnRowMapper作为RowMapper
return queryForObject(sql, getSingleColumnRowMapper(requiredType));
chapter10_通过Spring和JDBC征服数据库_3_在Spring中使用JDBC
最新推荐文章于 2023-03-30 21:38:40 发布