Spring系列之(九)Spring中的JdbcTemplate

Spring中的JdbcTemplate

持久层总图
在这里插入图片描述

1. JdbcTemplate相关的jar包

spring-jdbc-5.2.11.RELEASE.jar

2. JdbcTemplate的学习路径

  1. JdbcTemplate的作用
    用于和数据库交互,实现对表的CRUD操作
  2. 如何创建JdbcTemplate对象
    在这里插入图片描述
  3. 对象中的常用方法
方法 功能
void setDataSource(DataSource dataSource) 设置数据源
void execute(String sql) 执行操作(参数写死)
int update(String sql, Object... args) 增、删、改操作(可传参数)
<T> List<T> query(String sql, RowMapper<T> rowMapper, Object... args) 查询操作(可传参数),JDK 1.5之后使用
<T> List<T> query(String sql, Object[] args, RowMapper<T> rowMapper) 查询操作(可传参数),所有版本均可
<T> T queryForObject(String sql, Class<T> requiredType, Object... args) 查询一行一列
如何定位需要的重载方法:
  1. 我们有什么(参数列表)
  2. 我们要什么(返回值)

JDBCTemplate是靠不同的query方法来实现返回void、T、List&lt;T>的;

DBUtils是靠ResultSetHandler的返回值来实现返回不同的内容

3. JdbcTemplate在Spring的IOC中使用实现CRUD

3.1 pom中导入坐标

导入Spring核心框架、JdbcTemplate、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.itheima</groupId>
    <artifactId>day08_eesy_01jdbctemplate</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.11.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.11.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>
    </dependencies>

</project>

3.2 数据表和实体类

在这里插入图片描述

package com.itheima.domain;

/**
 * @author 商务小本本
 */
public class Account {

    private Integer id;
    private String name;
    private Float 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 +
                '}';
    }
}

3.3 配置文件

创建Spring内部的数据源Bean和JdbcTemplateBean并进行依赖注入(set方法方式注入)

<?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="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/eesy_spring?serverTimezone=GMT"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
</beans>

3.4 测试

  1. CUD操作
    在这里插入图片描述
  2. R操作-查询结果为多行
package com.itheima.jdbctemplate;

import com.itheima.domain.Account;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * @author 商务小本本
 */
public class JdbcTemplateDemo3 {

    public static void main(String[] args) {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);
        List<Account> accounts =  jdbcTemplate.query("select * from account where name = ?", new AccountRowMapper(), "ccc");
        for (Account account : accounts){
            System.out.println(account);
        }
    }
}
class AccountRowMapper implements RowMapper<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;
    }
}

在这里插入图片描述
上面的封装结果集的操作是由我们自己来做的,也可交给Spring来做
在这里插入图片描述

  1. R操作-查询结果为一行多列
package com.itheima.jdbctemplate;

import com.itheima.domain.Account;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * @author 商务小本本
 */
public class JdbcTemplateDemo3 {

    public static void main(String[] args) {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);

        List<Account> accounts = jdbcTemplate.query("select * from account where id = ?",
                new BeanPropertyRowMapper<Account>(Account.class), 2);
        System.out.println(accounts.isEmpty()?"没有元素":accounts.get(0));
    }
}
  1. R操作-查询结果为一行一列(使用聚合函数,但不加group by子句)
package com.itheima.jdbctemplate;

import com.itheima.domain.Account;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * @author 商务小本本
 */
public class JdbcTemplateDemo3 {

    public static void main(String[] args) {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);

        Integer idCount = jdbcTemplate.queryForObject("select count(*) from account where id = ?", Integer.class, 2);
        System.out.println(idCount);
    }
}

在这里插入图片描述

4. JdbcTemplate在Dao中的使用

继续修改上述的例子

  1. 创建Dao
package com.itheima.dao;

import com.itheima.domain.Account;

import java.util.List;

/**
 * @author 商务小本本
 */
public interface IAccountDao {

    /**
     * 查询所有
     * @return
     */
    List<Account> selectAllAccount();

    /**
     * 根据Id查询一个
     * @param id
     * @return
     */
    Account selectAccountById(Integer id);

    /**
     * 保存
     * @param account
     */
    void saveAccount(Account account);

    /**
     * 修改
     * @param account
     */
    void updateAccount(Account account);

    /**
     * 删除
     * @param id
     */
    void deleteAccountById(Integer id);
}
  1. Dao的实现类
package com.itheima.dao.impl;

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

import java.util.List;

/**
 * @author 商务小本本
 */
public class AccountDao implements IAccountDao {
    private JdbcTemplate jdbcTemplate;

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

    public List<Account> selectAllAccount() {
        return jdbcTemplate.query("select * from account where money = ?",
                new BeanPropertyRowMapper<Account>(Account.class), 1000);
    }

    public Account selectAccountById(Integer id) {
        List<Account> accounts = jdbcTemplate.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class), id);
        if (accounts.isEmpty()){
            return null;
        }
        if (accounts.size()>1){
            throw new RuntimeException("查询出错");
        }
        return accounts.get(0);
    }

    public void saveAccount(Account account) {
        jdbcTemplate.update("insert into account (NAME, money ) values (?, ?);", account.getName(), account.getMoney());
    }

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

    public void deleteAccountById(Integer id) {
        jdbcTemplate.update("delete from account where id = ?", id);
    }
}

  1. bean.xml在上面例子的基础上增加如下内容
<bean id="accountDao" class="com.itheima.dao.impl.AccountDao">
    <property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
  1. 测试
package com.itheima.jdbctemplate;

import com.itheima.dao.IAccountDao;
import com.itheima.domain.Account;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import java.util.List;

/**
 * @author 商务小本本
 */
public class JdbcTemplateDemo4 {

    public static void main(String[] args) {
        
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        IAccountDao accountDao = applicationContext.getBean("accountDao", IAccountDao.class);

//        List<Account> accounts = accountDao.selectAllAccount();
//        for (Account account:accounts){
//            System.out.println(account);
//        }
//        Account account = accountDao.selectAccountById(2);
//        System.out.println(account);
        Account account = new Account();
        account.setName("xxx");
        account.setMoney(1400f);
//        accountDao.saveAccount(account);
        account.setId(6);

//        accountDao.updateAccount(account);
        accountDao.deleteAccountById(6);
    }
}

5. 项目中存在多个Dao的实现类导致的代码冗余问题

每个Dao中都会有下面部分
在这里插入图片描述
在这里插入图片描述

6. JdbcTemplate在Dao中的第二种使用方式

首先抽取Dao中的冗余部分作为单独的一个类
在这里插入图片描述
其他Dao继承这个类
在这里插入图片描述
但由于JdbcDaoSupport类的JdbcTemplate被private修饰,子类访问该属性需要父类提供一个get方法
在这里插入图片描述
子类中通过get方法调用
在这里插入图片描述
在公共类中增加DataSource的set方法和JdbcTemplate对象的创建方法,这样可以精简配置文件的内容
在这里插入图片描述
配置文件
在这里插入图片描述
JdbcDaoSupport这个公共类,Spring其实已经提供了,不再需要我们进行创建,直接使用即可

7. JdbcTemplate在Dao中两种使用方式的应用场景

使用方式 应用场景
不进行继承(存在冗余代码) 基于注解和XML开发均可
继承JdbcDaoSupport 只能基于XML开发

事务在业务层解决

posted @   刘二水  阅读(176)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示