Spring中的JdbcTemplate

柔光的暖阳◎ 2023-02-14 01:37 81阅读 0赞

目录

  • 概述
  • 环境搭建
  • 实例演示
  • JdbcTemplate的CRUD操作
    • **保存**
    • **更新**
    • **删除**
    • **查询所有**
    • 查询单个
    • 查询返回一行一列
  • JdbcTemplate在DAO中的使用
    • 方式1:在 dao 中定义 JdbcTemplate
    • 方式2:让 dao 继承 JdbcDaoSupport
    • 两种方式的区别

概述

JdbcTemplate是 spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装。 spring 框架为我们提供了很多
的操作模板类,它只是其中的一个。下面直接上实例演示用法。

环境搭建

我们今天的主角在 spring-jdbc-5.0.2.RELEASE.jar 中,我们在导包的时候,除了要导入这个 jar 包
外,还需要导入一个 spring-tx-5.0.2.RELEASE.jar。
pom.xml:

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>5.0.2.RELEASE</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework</groupId>
  9. <artifactId>spring-jdbc</artifactId>
  10. <version>5.0.2.RELEASE</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework</groupId>
  14. <artifactId>spring-tx</artifactId>
  15. <version>5.0.2.RELEASE</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>mysql</groupId>
  19. <artifactId>mysql-connector-java</artifactId>
  20. <version>5.1.6</version>
  21. </dependency>
  22. </dependencies>

准备表:
在这里插入图片描述
创建其对应的实体类:

  1. package com.zhu;
  2. import java.io.Serializable;
  3. /** * 账户的实体类 */
  4. public class Account implements Serializable {
  5. private Integer id;
  6. private String name;
  7. private Float money;
  8. public Integer getId() {
  9. return id;
  10. }
  11. public void setId(Integer id) {
  12. this.id = id;
  13. }
  14. public String getName() {
  15. return name;
  16. }
  17. public void setName(String name) {
  18. this.name = name;
  19. }
  20. public Float getMoney() {
  21. return money;
  22. }
  23. public void setMoney(Float money) {
  24. this.money = money;
  25. }
  26. @Override
  27. public String toString() {
  28. return "Account{" +
  29. "id=" + id +
  30. ", name='" + name + '\'' +
  31. ", money=" + money +
  32. '}';
  33. }
  34. }

实例演示

  • 先写个最简单的例子:

    /* JdbcTemplate的最基本用法 */
    public class JdbcTemplateDemo1 {

    1. public static void main(String[] args) {
    2. //准备数据源:spring的内置数据源
    3. DriverManagerDataSource ds = new DriverManagerDataSource();
    4. ds.setDriverClassName("com.mysql.jdbc.Driver");
    5. ds.setUrl("jdbc:mysql://localhost:3306/springstudy?useUnicode=true&characterEncoding=utf8");
    6. ds.setUsername("root");
    7. ds.setPassword("root");
    8. //1.创建JdbcTemplate对象
    9. JdbcTemplate jt = new JdbcTemplate();
    10. //给jt设置数据源
    11. jt.setDataSource(ds);
    12. //2.执行操作
    13. jt.execute("insert into account(name,money)values('ccc',1000)");
    14. }

    }

执行完后:
在这里插入图片描述

  • 上面的例子还有许多值得改进的地方,比如写死了配置,类间的依赖等等,那么可以通过IOC来解决:
    配置bean.xml:

    <?xml version=”1.0” encoding=”UTF-8”?>











    //localhost:3306/springstudy?useUnicode=true&characterEncoding=utf8">



这样上面的Demo就能大大简化了:

  1. /** * JdbcTemplate的最基本用法:IOC */
  2. public class JdbcTemplateDemo2 {
  3. public static void main(String[] args) {
  4. //1.获取容器
  5. ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
  6. //2.获取对象
  7. JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);
  8. //3.执行操作
  9. jt.execute("insert into account(name,money)values('ddd',2222)");
  10. }
  11. }

JdbcTemplate的CRUD操作

上边的SQL语句是写死的,现在看看如何用带参数的来进行CRUD吧~

保存

  1. jt.update("insert into account(name,money)values(?,?)","eee",3333f);

更新

  1. jt.update("update account set name=?,money=? where id=?","test",4567,7);

删除

  1. jt.update("delete from account where id=?",8);

以上三个单表操作,都是用的update()方法。

查询所有

使用的是这个方法:
在这里插入图片描述
参数 rowMapper定义了从查询结果如何封装为对象,如果要自己定义:

  1. /** * 定义Account的封装策略 */
  2. class AccountRowMapper implements RowMapper<Account>{
  3. /** * 把结果集中的数据封装到Account中,然后由spring把每个Account加到集合中 * @param rs * @param rowNum * @return * @throws SQLException */
  4. @Override
  5. public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
  6. Account account = new Account();
  7. account.setId(rs.getInt("id"));
  8. account.setName(rs.getString("name"));
  9. account.setMoney(rs.getFloat("money"));
  10. return account;
  11. }
  12. }

当然,Spring也提供了RowMapper的实现类BeanPropertyRowMapper,我们直接传它就行:

  1. List<Account> accounts = jt.query("select * from account where money > ?",new BeanPropertyRowMapper<Account>(Account.class),1000f);
  2. for(Account account : accounts){
  3. System.out.println(account);
  4. }

执行结果:
在这里插入图片描述

查询单个

仍然用的上面的query方法:在这里插入图片描述

  1. List<Account> accounts = jt.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),1);
  2. System.out.println(accounts.isEmpty()?"没有内容":accounts.get(0));

在这里插入图片描述

查询返回一行一列

上面查询返回的都是结果集,如何查询单个值呢?
在这里插入图片描述

  1. //查询返回一行一列(使用聚合函数,但不加group by子句)
  2. Long count = jt.queryForObject("select count(*) from account where money > ?",Long.class,1000f);
  3. System.out.println(count);

执行后打印2.

JdbcTemplate在DAO中的使用

方式1:在 dao 中定义 JdbcTemplate

上面的写法都是测试的写法,实际开发中一般采用DAO的方式。
先提供一个接口:
定义了两个查询和一个更新方法——

  1. /** * 账户的持久层接口 */
  2. public interface IAccountDao {
  3. /** * 根据Id查询账户 * @param accountId * @return */
  4. Account findAccountById(Integer accountId);
  5. /** * 根据名称查询账户 * @param accountName * @return */
  6. Account findAccountByName(String accountName);
  7. /** * 更新账户 * @param account */
  8. void updateAccount(Account account);
  9. }

实现类,JdbcTemplate通过spring注入:

  1. /** * 账户的持久层实现类 */
  2. public class AccountDaoImpl implements IAccountDao {
  3. private JdbcTemplate jdbcTemplate;
  4. public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
  5. this.jdbcTemplate = jdbcTemplate;
  6. }
  7. @Override
  8. public Account findAccountById(Integer accountId) {
  9. List<Account> accounts = jdbcTemplate.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),accountId);
  10. return accounts.isEmpty()?null:accounts.get(0);
  11. }
  12. @Override
  13. public Account findAccountByName(String accountName) {
  14. List<Account> accounts = jdbcTemplate.query("select * from account where name = ?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
  15. if(accounts.isEmpty()){
  16. return null;
  17. }
  18. if(accounts.size()>1){
  19. throw new RuntimeException("结果集不唯一");
  20. }
  21. return accounts.get(0);
  22. }
  23. @Override
  24. public void updateAccount(Account account) {
  25. jdbcTemplate.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
  26. }
  27. }

当然,想要能注入,必须配置bean:

  1. <!-- 配置账户的持久层-->
  2. <bean id="accountDao" class="com.zhu.dao.impl.AccountDaoImpl">
  3. <property name="jdbcTemplate" ref="jdbcTemplate"></property>
  4. </bean>

测试:

  1. /** * JdbcTemplate在DAO中的使用 */
  2. public class JdbcTemplateDemo4 {
  3. public static void main(String[] args) {
  4. //1.获取容器
  5. ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
  6. //2.获取对象
  7. IAccountDao accountDao = ac.getBean("accountDao",IAccountDao.class);
  8. Account account = accountDao.findAccountById(1);
  9. System.out.println(account);
  10. account.setMoney(30000f);
  11. accountDao.updateAccount(account);
  12. }
  13. }

方式2:让 dao 继承 JdbcDaoSupport

JdbcDaoSupport 是 spring 框架为我们提供的一个类,该类中定义了一个 JdbcTemplate 对象,我们可以
直接获取使用,但是要想创建该对象,需要为其提供一个数据源:具体源码如下:

  1. public abstract class JdbcDaoSupport extends DaoSupport {
  2. //定义对象
  3. private JdbcTemplate jdbcTemplate;
  4. //set 方法注入数据源,判断是否注入了,注入了就创建 JdbcTemplate
  5. public final void setDataSource(DataSource dataSource) {
  6. if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource())
  7. { //如果提供了数据源就创建 JdbcTemplate
  8. this.jdbcTemplate = createJdbcTemplate(dataSource);
  9. initTemplateConfig();
  10. }
  11. }
  12. //使用数据源创建 JdcbTemplate
  13. protected JdbcTemplate createJdbcTemplate(DataSource dataSource) {
  14. return new JdbcTemplate(dataSource);
  15. }
  16. //当然,我们也可以通过注入 JdbcTemplate 对象
  17. public final void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
  18. this.jdbcTemplate = jdbcTemplate;
  19. initTemplateConfig();
  20. }
  21. //使用 getJdbcTmeplate 方法获取操作模板对象
  22. public final JdbcTemplate getJdbcTemplate() {
  23. return this.jdbcTemplate;
  24. }
  25. ...
  26. }

此版本 dao,只需要给它的父类注入一个数据源:

  1. /** * 账户的持久层实现类 */
  2. public class AccountDaoImpl2 extends JdbcDaoSupport implements IAccountDao {
  3. @Override
  4. public Account findAccountById(Integer accountId) {
  5. List<Account> accounts = super.getJdbcTemplate().query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),accountId);
  6. return accounts.isEmpty()?null:accounts.get(0);
  7. }
  8. @Override
  9. public Account findAccountByName(String accountName) {
  10. List<Account> accounts = super.getJdbcTemplate().query("select * from account where name = ?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
  11. if(accounts.isEmpty()){
  12. return null;
  13. }
  14. if(accounts.size()>1){
  15. throw new RuntimeException("结果集不唯一");
  16. }
  17. return accounts.get(0);
  18. }
  19. @Override
  20. public void updateAccount(Account account) {
  21. super.getJdbcTemplate().update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
  22. }
  23. }

bean.xml

  1. <!-- 配置 dao2 -->
  2. <bean id="accountDao2" class="com.zhu.dao.impl.AccountDaoImpl2">
  3. <!-- 注入 dataSource -->
  4. <property name="dataSource" ref="dataSource"></property>
  5. </bean>

两种方式的区别

第一种在 Dao 类中定义 JdbcTemplate 的方式,适用于所有配置方式( xml 和注解都可以)。
第二种让 Dao 继承 JdbcDaoSupport 的方式,只能用于基于 XML 的方式,注解用不了。

因为无法给jar包中的JdbcDaoSupport类的代码加@Autowired注解。

发表评论

表情:
评论列表 (有 0 条评论,81人围观)

还没有评论,来说两句吧...

相关阅读

    相关 SpringJDBCTemplate

    当hql等查询方式不能满足性能或灵活性的要求,必须使用SQL时,大家有三种选择: 第一、使用Hibernate 的sql 查询函数,将查询结果对象转为Entity对象。 第