spring-JdbcTemplate学习笔记

spring-JdbcTemplate学习总结

1、持久层总图

在这里插入图片描述

spring 框架提供很多操作模板类

  1. 操作关系型数据:
    • JdbcTemplate
    • HibernateTemplate
  2. 操作 nosql 数据库:
    • RedisTemplate
  3. 操作消息队列:
    • JmsTemplate

Mybatis 与 Spring-JdbcTemplate 的选择

  • 小型项目
    • Spring-JdbcTemplate 的性能更好,更适合管理域的sql语句
  • 大型项目
    • mybatis可以将sql语句批量的管理起来,还可以达到sql的重用
    • mybatis还做数据库的驱动注册加载,数据库连接的创建与销毁等数据库的管理
      • 可以让开发人员更关注于业务,更适合在业务域使用

2、JdbcTemplate:概述

  • spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装
  • 导包:spring-jdbc-5.0.2.RELEASE.jar、spring-tx-5.0.2.RELEASE.jar(事务)

3、JdbcTemplate:作用

  • 用于和数据库进行交互,实现对数据库表的 CRUD操作

4、JdbcTemplate:对象

  • 创建 spring16_JdbcTemplate 的工程,演示 JdbcTemplate对象的创建和使用

1. 编写 账户实体类

  • 对应 spring_test 数据库中的 account账户表创建账户实体类,并实现序列化接口
// 账户的实体类
public class Account implements Serializable {

    private Integer id;
    private String name;
    private Float money;

    public Account() {
    }

    public Account(Integer id, String name, Float money) {
        this.id = id;
        this.name = name;
        this.money = money;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Float getMoney() {
        return money;
    }

    public void setMoney(Float money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

2. 编写 Pom.xml 文件

  • 导入 spring-context、spring-jdbc、spring-tx、mysql 的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.idea.spring</groupId>
    <artifactId>spring16_JdbcTemplate</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>
        <dependency>
           <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.3.14.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>4.3.14.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.8</version>
        </dependency>
    </dependencies>
</project>

3. 编写 JdbcTemplate类

  • 数据源的选择与配置

    1. 使用 spring的内置数据源:DriverManagerDataSource 类

    2. 配置 C3P0 数据源

      • 导入 c3p0 的 Jar包
      • 配置文件中配置数据源:
      <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
          <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
          <property name="url" value="jdbc:mysql://localhost:3306/spring_test"></property>
          <property name="username" value="root"></property>
          <property name="password" value="123456"></property>
      </bean>
      
    3. 配置 DBCP 数据源

      • 导入 dbcp 的 Jar包
      • 配置文件中配置数据源:
      <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
          <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
          <property name="url" value="jdbc:mysql://localhost:3306/spring_test"></property>
          <property name="username" value="root"></property>
          <property name="password" value="123456"></property>
      </bean>
      
  • 编写 JdbcTemplate1 类:

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

    public static void main(String[] args){
        // 准备数据源:spring的内置数据源
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_test");
        ds.setUsername("root");
        ds.setPassword("123456");
        
        //1.创建JdbcTemplate对象
        JdbcTemplate jt = new JdbcTemplate();
        // 给jt设置数据源
        jt.setDataSource(ds);
        //2.执行操作
        jt.execute("insert into  account(name,money) values('ccc',1000)");
    }
} 
=================================================================
运行结果:	插入账户 ccc 成功

4. 发现、解决问题

  • 问题:

    • 数据源的设置被固定,并且是以 Set 方法设置数据源的基本信息
    • JdbcTemplate 对象是以 构造函数 创建
  • 解决方式:

    1. 可以在 Spring框架的 IOC配置文件中直接配置

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans.xsd">
      
          <!-- 配置JdbcTemplate -->
          <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
              <property name="dataSource" ref="dataSource"></property>
          </bean>
      
          <!-- 配置数据源 -->
          <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
              <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
              <property name="url" value="jdbc:mysql://localhost:3306/spring_test"></property>
              <property name="username" value="root"></property>
              <property name="password" value="123456"></property>
          </bean>
      </beans>
      
    2. 引入外部配置文件

    配置属性文件 jdbc.properties:

    jdbc.driverClass=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/spring_test
    jdbc.username=root
    jdbc.password=123456
    

    方式一:

    <bean>
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
     	<property name="location" value="classpath:jdbc.properties"/>
    </bean>
    

    方式二:

    <context:property-placeholder location="classpath:jdbc.properties"/>
    
  • 运行 JdbcTemplateDemo2 类:

// JdbcTemplate的最基本用法
public class JdbcTemplateDemo2 {

    public static void main(String[] args){
        //1.获取容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.获取对象
        JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
        //3.执行操作
        jt.execute("insert into  account(name,money) values('ddd',2000)");
    }
}
  • 运行结果:插入账户 ddd 成功
  • 配置文件的方式:创建 JdbcTemplate 对象并调用 execute ( ) 方法,避免数据源信息固定的弊端

5、JdbcTemplate:CRUD

  • 创建 JdbcTemplateDemo3 类,测试 JdbcTemplate对象的 CRUD操作
1. 获取容器和对象
//1.获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.获取对象
JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
2. 保存
  • 调用 update ( Insert 语句、参数 ) 方法
jt.update("insert into account(name,money) values(?,?)","eee",3333f);
3. 更新
  • 调用 update ( update 语句、参数 ) 方法
jt.update("update account set name = ? , money = ? where id = ?","test",4567f,10);
3. 删除
  • 调用 update ( delete 语句、参数 ) 方法
jt.update("delete from account where id = ? ",8);
4. 查询所有

在这里插入图片描述

① 方式一:
  • 手动创建 AccountRomMapper 类继承 RowMapper
// 定义 Account 的封装策略
class AccountRomMapper implements RowMapper<Account>{
    @Override
    // 把结果集中的数据封装到Account中,然后由spring把每个Account加到集合中
    public Account mapRow(ResultSet resultSet, int i) throws SQLException {
        Account account = new Account();
        account.setId(resultSet.getInt("id"));
        account.setName(resultSet.getString("name"));
        account.setMoney(resultSet.getFloat("money"));
        return account;
    }
}
  • 调用 query( 查询语句、new RowMapper ( )、参数)方法
List<Account> accounts = jt.query("select * from account where money > ? ",new AccountRomMapper(),1000f);
for (Account account : accounts) {
    System.out.println(account);
}
② 方式二:
  • Spring框架提供的 BeanPropertyRowMapper< 封装类型 >( .class字节码 )
  • 调用 query(查询语句、new BeanPropertyRowMapper<>()、参数)方法
List<Account> accounts = jt.query("select * from account where money > ? ",new BeanPropertyRowMapper<Account>(Account.class),1000f);
for(Account account : accounts) {
     System.out.println(account);
}
5. 与 QueryRunner 区别
  • QueryRunner 的 query ( ) 方法返回的结果只有一个泛型
  • Spring-JdbcTemplate 的 query ( ) 方法返回的结果可以是泛型、集合等
    在这里插入图片描述
6. 查询一个
  • 查询单个记录时,与查询多条记录时调用方法相同
    • 调用 query ( 查询语句+条件、new BeanPropertyRowMapper<>(),参数 )
    • 也存在专门查询单条记录的方法,只不过使用较少
List<Account> accounts = jt.query("select * from account where id =  ? ",new BeanPropertyRowMapper<Account>(Account.class),1);
System.out.println(accounts.isEmpty()?"没有内容":accounts.get(0));
7. 查询返回一行一列
  • 调用 queryForObject(查询语句、结果类型、参数)方法
Long count = jt.queryForObject("select count(*) from account where money > ?", Long.class, 1000f);
System.out.println(count);
  • 问题:spring-jdbc版本过新,无法查询到结果,会报异常
  • 解决:将 spring-jdbc 的 Jar包版本选用低版本的,即可查询成功

6、JdbcTemplate:Dao 使用

  • 创建 jdbcTemplateDemo4 类,演示 JdbcTemplate 在 Dao持久层的使用
1. 编写 账户持久层
  • 编写 账户持久层接口 AccountDao
// 账户的持久层接口
public interface AccountDao {

    // 根据Id查询账户
    Account findAccountById(Integer accountId);

    // 根据名称查询账户
    Account findAccountByName(String accountName);

    // 更新账户
    void updateAccount(Account account);

}
  • 编写 账户持久层接口实现类 AccountDaoImpl
// 账户的持久层实现类
public class AccountDaoImpl implements AccountDao {

    private JdbcTemplate jdbcTemplate;

    // Set方法等待spring注入
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public Account findAccountById(Integer accountId) {
        List<Account> accounts = jdbcTemplate.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class), accountId);
        return accounts.isEmpty()?null:accounts.get(0);
    }

    @Override
    public Account findAccountByName(String accountName) {
        List<Account> accounts = jdbcTemplate.query("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class), accountName);
        if(accounts.isEmpty()){
            return null;
        }else if(accounts.size()>1){
            throw new RuntimeException("结果集不唯一");
        }else {
            return accounts.get(0);
        }
    }

    @Override
    public void updateAccount(Account account) {
        jdbcTemplate.update("update account set name = ? ,money = ? where id = ? ",account.getName(),account.getMoney(),account.getId());
    }
}
2. 方法测试
  • 在 JdbcTemplateDemo4 类中,对 Dao层方法进行测试
// JdbcTemplate的CRUD操作
public class JdbcTemplateDemo4 {

    public static void main(String[] args){
        //1.获取容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.获取 accountDao对象
        AccountDao accountDao = (AccountDao) ac.getBean("accountDao");
        //3.执行方法
        Account account1 = accountDao.findAccountById(1);
        System.out.println(account1);

        Account account2 = accountDao.findAccountByName("ccc");
        System.out.println(account2);

        account2.setMoney(9999f);
        accountDao.updateAccount(account2);
    }
}
3. 发现问题
  • 问题:Dao类有很多,每个Dao接口实现类中,都存在重复代码
private JdbcTemplate jdbcTemplate;

// Set方法等待spring注入
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
}
  • 解决:

    • 每个Dao接口实现类继承 spring框架提供的 JdbcDaoSupport 类
    import org.springframework.jdbc.core.support.JdbcDaoSupport;
    
4. 解决问题
  • 使用情况不同:

    1. 当使用 注解配置时,不继承 JdbcDaoSupport 类,使用注解等待 spring框架自动依赖注入

      // 账户的持久层实现类
      //      演示基于注解配置时,不需要继承 JdbcDaoSupport类,直接使用注解配置等待注入即可
      @Repository
      public class AccountDaoImpl2 implements AccountDao {
      
          @Autowired
          private JdbcTemplate jdbcTemplate;
      
          @Override
          public Account findAccountById(Integer accountId) {
              List<Account> accounts = jdbcTemplate.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class), accountId);
              return accounts.isEmpty()?null:accounts.get(0);
          }
      
          @Override
          public Account findAccountByName(String accountName) {
              List<Account> accounts = jdbcTemplate.query("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class), accountName);
              if(accounts.isEmpty()){
                  return null;
              }else if(accounts.size()>1){
                  throw new RuntimeException("结果集不唯一");
              }else {
                  return accounts.get(0);
              }
          }
      
          @Override
          public void updateAccount(Account account) {
              jdbcTemplate.update("update account set name = ? ,money = ? where id = ? ",account.getName(),account.getMoney(),account.getId());
          }
      }
      
    2. 当使用 XML配置时,继承 spring框架提供的 JdbcDaoSupport 类

      • 修改 bean.xml 文件中,向 AccountDaoImpl1 类中注入 dataSource 数据源即可
      <bean id="accountDao" class="dao.Impl.AccountDaoImpl1">
              <property name="dataSource" ref="dataSource"></property>
      </bean>
      
      // 账户的持久层实现类
      // 		演示继承 spring框架提供的 JdbcDaoSupport 类
      public class AccountDaoImpl1 extends JdbcDaoSupport implements AccountDao {
      
          @Override
          public Account findAccountById(Integer accountId) {
              List<Account> accounts = super.getJdbcTemplate().query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class), accountId);
              return accounts.isEmpty()?null:accounts.get(0);
          }
      
          @Override
          public Account findAccountByName(String accountName) {
              List<Account> accounts = super.getJdbcTemplate().query("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class), accountName);
              if(accounts.isEmpty()){
                  return null;
              }else if(accounts.size()>1){
                  throw new RuntimeException("结果集不唯一");
              }else {
                  return accounts.get(0);
              }
          }
      
          @Override
          public void updateAccount(Account account) {
              super.getJdbcTemplate().update("update account set name = ? ,money = ? where id = ? ",account.getName(),account.getMoney(),account.getId());
          }
      }
      
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值