Spring 的 JdbcTemplate 和 JdbcDaoSupport

Spring JDBC 开发中,我们发现必须在所有DAO模式里的查询,插入,更新和删除操作中创建大量的冗余代码(创建连接,关闭连接,处理异常)。它的效率并不是很高,容易出错和乏味。不过,我们可以使用 JdbcTemplate 和 JdbcDaoSupport 类来简化整个数据库的操作过程。

1. JdbcTemplate

1.1 JdbcTemplate插入操作

1.1.1 单条插入

private DataSource dataSource;
private JdbcTemplate jdbcTemplate;

public void setDataSource(DataSource dataSource) {
	this.dataSource = dataSource;
}
	
public void insert(Article article) {
	String sql = "INSERT INTO ARTICLE (ID, TITLE, CONTENT) VALUES (?, ?, ?)";
		
	jdbcTemplate = new JdbcTemplate(dataSource);
	jdbcTemplate.update(sql, new Object[]{article.getId(), article.getTitle(), article.getContent()});
}

1.1.2 批量插入

在某些情况下,可能需要将一批记录插入到数据库中。如果你对每条记录调用一个插件的方法,SQL语句将被重复编译,造成系统缓慢进行。解决上述问题,可以使用 JdbcTemplate BATCHUPDATE()方法来执行批量插入操作。用这种方法,该语句只被编译一次,执行多次。

public void insertArticles(final List<Article> articles) {
	String sql = "INSERT INTO ARTICLE (ID, TITLE, CONTENT) VALUES (?, ?, ?)";

	jdbcTemplate = new JdbcTemplate(dataSource);
	jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
		
		public void setValues(PreparedStatement ps, int i) throws SQLException {
			Article article = articles.get(i);
			ps.setLong(1, article.getId());
			ps.setString(2, article.getTitle());
			ps.setString(3, article.getContent());
		}

		public int getBatchSize() {
			return articles.size();
		}
	});
}

1.2 JdbcTemplate查询

1.2.1 查询单行数据

有两种方法来查询或从数据库中提取单行记录,并将其转换成一个模型类。

  • 自定义RowMapper
  • BeanPropertyRowMapper

自定义RowMapper

建议实现 RowMapper 接口来创建自定义的RowMapper

public class ArticleRowMapper implements RowMapper<Article> {

	public Article mapRow(ResultSet rs, int rowNum) throws SQLException {
		return  new Article(rs.getInt("ID"), rs.getString("TITLE"), rs.getString("CONTENT"));
	}
}

 传递给 queryForObject()方法,返回的结果将调用自定义 mapRow()方法的值匹配到属性。

public Article getArticleById(int id) {
	String sql = "SELECT * FROM ARTICLE WHERE ID = ?";
		
	jdbcTemplate = new JdbcTemplate(dataSource);
	return jdbcTemplate.queryForObject(sql, new Object[]{id}, new ArticleRowMapper());
}

BeanPropertyRowMapper

public Article getArticleById(int id) {
	String sql = "SELECT * FROM ARTICLE WHERE ID = ?";
		
	jdbcTemplate = new JdbcTemplate(dataSource);
	return jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<Article>(Article.class));
}

使用BeanPropertyRowMapper,需要在实体类Article里有默认的构造函数。负责初始化Article失败。

1.2.2 查询多行

手动映射

由于 RowMapper 不支持 queryForList()方法,需要手动映射它。

public List<Article> getArticles() {
	String sql = "SELECT * FROM ARTICLE";
	jdbcTemplate = new JdbcTemplate(dataSource);

	List<Article> articles = new ArrayList<Article>();

	List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql);
	for (Map row : rows) {
		Article article = new Article((Long)row.get("ID"), (String)row.get("TITLE"), (String)row.get("CONTENT"));
		articles.add(article);
	}
	
	return articles;
}

BeanPropertyRowMapper

public List<Article> getArticles() {
	String sql = "SELECT * FROM ARTICLE";
	jdbcTemplate = new JdbcTemplate(dataSource);
	return jdbcTemplate.query(sql, new BeanPropertyRowMapper<Article>(Article.class));
}

2. JdbcDaoSupport

通过扩展 JdbcDaoSupport,设置数据源,并且 JdbcTemplate 在类中不再是必需的,只需要正确的数据源注入DAO。就可以使用 getJdbcTemplate()方法得到 JdbcTemplate。

public class JdbcArticleDao extends JdbcDaoSupport implements ArticleDao {

	/*private DataSource dataSource;
	private JdbcTemplate jdbcTemplate;

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}*/

	public void insert(Article article) {
		String sql = "INSERT INTO ARTICLE (ID, TITLE, CONTENT) VALUES (?, ?, ?)";

		//jdbcTemplate = new JdbcTemplate(dataSource);
		getJdbcTemplate().update(sql, new Object[]{article.getId(), article.getTitle(), article.getContent()});
	}

	public List<Article> getArticles() {
		String sql = "SELECT * FROM ARTICLE";
		//bcTemplate = new JdbcTemplate(dataSource);
		return getJdbcTemplate().query(sql, new BeanPropertyRowMapper<Article>(Article.class));
	}

	public Article getArticleById(int id) {
		String sql = "SELECT * FROM ARTICLE WHERE ID = ?";

		//jdbcTemplate = new JdbcTemplate(dataSource);
		return getJdbcTemplate().queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<Article>(Article.class));
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AngeliaZheng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值