spring中的JdbcTemplate

spring中的JdbcTemplate

环境:
Idea:2019.3.1
系统:windows10 家庭版
Jdk: 8
spring:5.0.3 release
spring文档
项目代码

1.概述
它是spring框架中提供的一个对象,是对原始Jdbc AOP对象的简单封装,spring框架为我们提供了很多的操作模板类。
操作关系型数据的:
    JDBCTemplate
    HibernateTemplate
操作Nosql数据库的
    RedisTemplate
操作消息队列的:
    JMSTemplate

JdbcTemplate在 spring-jdbc-5.0.2.RELEASE.jar 中,导入包的时候,除了这个jar包,还得导入一个和事务相关的包
spring-tx-5.0.2.RELEASE.jar

2.使用

配置JdbcTemplate及数据源

<?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/myspringspace"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>
</beans>

使用JdbcTemplate插入账户数据

public class JdbcTemplateDemo2 {
    public static void main(String[] args) {
        //1.获取容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.获取JdbcTemplate对象
        JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate",JdbcTemplate.class);
        //3.执行语句
        jt.execute("insert into account(name,money)values('xxx',10000)");
    }
}
3.实现curd操作

保存

jt.update("insert into account(name,money)values(?,?)","zzz",1000f);

更新

jt.update("update account set name=?,money=? where id=?","llll",20000f,8);

删除

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

查询
查询所有

这是所有的query方法,但是并不是都能用到,我们通过2点来过滤

  • 我们提供什么:sql语句,语句的参数
  • 我们需要什么:返回一个List集合

根据这两点我们能定位到,只剩两个方法我们更适合去使用


这两个方法是针对不同的JDK版本使用的,第一个所有版本都能使用,第二个是JDK1.5之后才能使用,因为参数中有了可变参数
我们是JDK1.8所以能够使用第二种,这里我们使用第二种来查询

accountList = jt.query("select * from account where money=?", 第二个参数 ,1000f);


定位到RowMapper后发现,它是一个接口,所以我们要使用它的实现类来作为参数传入进方法

/**
 * 定义account封装策略
 */
class AccountRowMapper implements RowMapper {

    /**
     * 把结果集中的数据封装到Account中,并由spring把每个Account加入到List集合中
     *
     * @param resultSet
     * @param i
     * @return
     * @throws SQLException
     */
    public Object mapRow(ResultSet resultSet, int i) throws SQLException {
    //这里可以将Account的属性和表中的字段对应起来
        Account account = new Account();
        account.setId(resultSet.getInt("id"));
        account.setName(resultSet.getString("name"));
        account.setMoney(resultSet.getFloat("money"));

        return account;
    }
}

完整的查询语句是这样的

List<Account> accountList = jt.query("select * from account where money>?",new AccountRowMapper(),1000f);

当然我们也可以使用spring为我们提供的RowMapper接口实现类BeanPropertyRowMapper<T>

//传入Account字节码
List<Account> accountList = jt.query("select * from account where money>?",new BeanPropertyRowMapper<Account>(Account.class),1000f);

类比一下dbutils中的QueryRunner中的query方法

  • QueryRunner.query:它的返回值类型是一个泛型,它的返回值类型是由ResultSethandler中的返回值类型来觉得的
  • JdbcTemplate.query:它的返回值类型是由不同的query方法来实现返回的,根据最开始截的那张query方法图能发现,有很多query方法,有参数不同的,有返回值不同的

查询一个
还是可以使用查询所有的方法

//传入Account字节码
List<Account> accountList = jt.query("select * from account where id=?",new BeanPropertyRowMapper<Account>(Account.class),1);
//取出查询结果
System.out.println(accountList.isEmpty() ? "没有内容" : accountList.get(0));


可以看到取出来id为1的账户
因为这一个方法可以满足查询任何情况,所以实际开发中也是使用这个方法
查询返回一行一列(使用聚合函数,但是不加group by字句)

//因为要返回一行一列,一行一列可以认为是一个数据,就像count(*)函数的结果,所以不能使用query方法,而是要使用queryForObject方法
//第二个参数填返回值类型的字节码,你传的什么类型的字节码,那么这个方法的返回值就是那个数据类型,我们使用的是long,所以我们用long来接受,int也可以,但是如果实际数据大于int的数据范围就会报错,所以实际上我们直接使用更大的long来接受
long count = jt.queryForObject("select count(*) from account where money>?",long.class,1000f);
System.out.println(count);
4.Jdbc的使用以及Dao的两种配置方式

刚刚是在main方法执行的语句,但是实际开发中,main方法一般是留给测试人员使用,我们应该将语句的执行放在dao层,我们新建dao层,创建IAccountServce接口,创建AccountServceImpl类,如下

AccountServiceImpl代码如下

import com.cbw.dao.IAccountDao;
import com.cbw.domain.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

/**
 * 账户的持久层实现类
 */
public class AccountDaoImpl3 implements IAccountDao {
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

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

    public Account findAccountByName(String accountName) {
        List<Account> accountList = jdbcTemplate.query("select * from account where name =?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
        return accountList.isEmpty()?null:accountList.get(0);
    }

    public void updateAccount(Account account) {
        jdbcTemplate.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
    }
}

试想一下,如果dao层实现类比较多,实际开发肯定不止这一个啊,那么我们每一个daoimp里面都有这段重复代码

    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

新建一个JdbcDaoSupport类

import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

/**
 * 此类用于抽取dao中的重复代码
 */
public class JdbcDaoSupport {
    private JdbcTemplate jdbcTemplate;

    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    public void setDataSource(DataSource dataSource) {
        if(jdbcTemplate == null){
            jdbcTemplate = createJdbcTemplate(dataSource);
        }
    }
    private JdbcTemplate createJdbcTemplate(DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }
}

然后让accountDaoImpl类继承这个类,就只需要使用super关键子调用jdbcTemplate类了

import com.cbw.dao.IAccountDao;
import com.cbw.domain.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;

import java.util.List;

/**
 * 账户的持久层实现类
 */
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {

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

    public Account findAccountByName(String accountName) {
        List<Account> accountList = super.getJdbcTemplate().query("select * from account where name =?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
        return accountList.isEmpty()?null:accountList.get(0);
    }

    public void updateAccount(Account account) {
        super.getJdbcTemplate().update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
    }
}

别忘了在xml文件中,配置accountDao,并在里面注入dataSource

<?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">
<!--    配置账户的持久层-->
    <bean id="accountDao" class="com.cbw.dao.impl.AccountDaoImpl">
            <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/myspringspace"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>
</beans>

执行测试

当然,spring中也给我们实现了这种方式,我们可以直接继承spring中的JdbcDaoSupport类

我们就不需要自己写support类,但是,这样写的话,我们就不能自己用注解配置jdbcTemplate了,因为那个是spring提供的jar包里面的,
所以,当我们使用继承spring中的JdbcDaoSupport类时,我们是使用xml配置dao的,当我们不使用这种方式,我们就可以使用注解方式来配置dao了,怎么选择看我们自己


 上一篇
spring中的事务控制 spring中的事务控制
spring中的事务控制 环境:Idea:2019.3.1系统:windows10 家庭版Jdk: 8spring:5.0.3 releasespring文档项目代码 一.概述1.JavaEE体系进行分层开发,事务处理位于业务层,Spri
2020-04-10
下一篇 
依赖注入,spring基于注解的IoC,spring整合junit 依赖注入,spring基于注解的IoC,spring整合junit
依赖注入,spring基于注解的IoC,spring整合junit 环境:Idea:2019.3.1系统:windows10 家庭版Jdk: 8spring:5.0.3 releasespring文档项目代码 依赖注入spring中的依赖
2020-04-10
  目录