Spring系列之(九)Spring中的JdbcTemplate

2025-10-06 00:25:04

Spring中的JdbcTemplate

持久层总图

1. JdbcTemplate相关的jar包

spring-jdbc-5.2.11.RELEASE.jar

2. JdbcTemplate的学习路径

JdbcTemplate的作用

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

如何创建JdbcTemplate对象

对象中的常用方法

方法

功能

void setDataSource(DataSource dataSource)

设置数据源

void execute(String sql)

执行操作(参数写死)

int update(String sql, Object... args)

增、删、改操作(可传参数)

List query(String sql, RowMapper rowMapper, Object... args)

查询操作(可传参数),JDK 1.5之后使用

List query(String sql, Object[] args, RowMapper rowMapper)

查询操作(可传参数),所有版本均可

T queryForObject(String sql, Class requiredType, Object... args)

查询一行一列

如何定位需要的重载方法:

我们有什么(参数列表)

我们要什么(返回值)

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

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

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

3.1 pom中导入坐标

导入Spring核心框架、JdbcTemplate、MySQL

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">

4.0.0

com.itheima

day08_eesy_01jdbctemplate

1.0-SNAPSHOT

jar

org.springframework

spring-context

5.2.11.RELEASE

org.springframework

spring-jdbc

5.2.11.RELEASE

mysql

mysql-connector-java

8.0.19

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方法方式注入)

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">

3.4 测试

CUD操作

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 accounts = jdbcTemplate.query("select * from account where name = ?", new AccountRowMapper(), "ccc");

for (Account account : accounts){

System.out.println(account);

}

}

}

class AccountRowMapper implements RowMapper{

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来做

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 accounts = jdbcTemplate.query("select * from account where id = ?",

new BeanPropertyRowMapper(Account.class), 2);

System.out.println(accounts.isEmpty()?"没有元素":accounts.get(0));

}

}

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中的使用

继续修改上述的例子

创建Dao

package com.itheima.dao;

import com.itheima.domain.Account;

import java.util.List;

/**

* @author 商务小本本

*/

public interface IAccountDao {

/**

* 查询所有

* @return

*/

List 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);

}

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 selectAllAccount() {

return jdbcTemplate.query("select * from account where money = ?",

new BeanPropertyRowMapper(Account.class), 1000);

}

public Account selectAccountById(Integer id) {

List accounts = jdbcTemplate.query("select * from account where id = ?", new BeanPropertyRowMapper(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);

}

}

bean.xml在上面例子的基础上增加如下内容

测试

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 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开发

事务在业务层解决