学习目标
JDBCTemplate模
一、JDBCTemplate模板
1、JDBCTemplate概述:
JDBC已经能够满足大部分用户最基本的需求,但是在使用JDBC时,必须自己来管理数据库资源如:获取PreparedStatement,设置SQL语句参数,关闭连接等步骤。JdbcTemplate就是Spring对JDBC的封装,目的是使JDBC更加易于使用。JdbcTemplate是Spring的一部分。 JdbcTemplate处理了资源的建立和释放。他帮助我们避免一些常见的错误,比如忘了总要关闭连接。他运行核心的JDBC工作流,如Statement的建立和执行,而我们只需要提供SQL语句和提取结果。
Spring源码地址:https://github.com/spring-projects/spring-framework
在JdbcTemplate中执行SQL语句的方法大致分为3类:
(1)、execute:可以执行所有SQL语句、一般用于执行DDL语句
(2)、update:用于执行insert、update、delete等DML语句
(3)、queryXxx:用于DQL数据查询语句
2、API介绍
public JdbcTemplate(DataSource dataSource)
创建JdbcTemplate对象,方便执行SQL语句
2.1使用步骤:
(1)、准备c3p0数据库连接池、集成到JDBCUtils工具类中
(2)、导入依赖的jar包:
spring-beans-5.0.2.RELEASE.jar`
spring-core-5.0.2.RELEASE.jar
spring-jdbc-5.0.2.RELEASE.jar
spring-tx-5.0.2.RELEASE.jar
com.springsource.org.apache.commons.logging-1.1.1.jar
(3)、创建JDBCTemplate对象、传入c3p0连接池
(4)、调用execute()、update()、queryXxxx()、query()等方法
3、execute案例:
c3p0-config.xml 配置文件 :在src目录 下
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默认配置,c3p0框架默认加载这段默认配置 -->
<default-config>
<!-- 配置JDBC 四个基本属性 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=utf-8</property>
<property name="user">root</property>
<property name="password">123</property>
</default-config>
<!-- 可以自定义配置,为这段配置起一个名字,c3p0指定名称加载配置 -->
<named-config name="baidu">
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=utf-8</property>
<property name="user">root</property>
<property name="password">123</property>
</named-config>
</c3p0-config>
JDBCUtils工具类:
public class JDBCUtils {
// 核心连接池类
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
public static DataSource getDataSource() {
return dataSource;
}
// 获取连接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
// 释放资源
public static void release(Connection conn, Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
release(conn, stmt);
}
public static void release(Connection conn, Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
*JdbcTemplate 的 execute 方法 :**
public class JDBCTemplateExecute {
public static void main(String[] args) {
// 1. 创建表的SQL语句
String sql = "create table product (" +
"pid int primary key auto_increment," +
"pname varchar(20)," +
"price double" +
");";
// 2. 创建 jdbcTemplate 对象, 并将数据库连接池作为参数传入
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
// 3. 使用 jdbcTemplate 对象调用 execute 方法, 执行 sql 语句, 创建数据库表.
jdbcTemplate.execute(sql);
}
}
4、JDBCTemplate的update()方法实现SQL增删改
public int update(final String sql)
用于执行`INSERT`、`UPDATE`、`DELETE`等DML语句。
使用步骤:
A.创建JdbcTemplate对象
B.编写SQL语句
C.使用JdbcTemplate对象的update方法进行增删改
JDBCTemplate的方法update()案例:
Insert 增加数据
@Test
public void insert() {
// 1. 创建一个 JdbcTemplate 对象, 并将连接池作为参数传入
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
// 2. 编写 sql 语句
String sql = "insert into product values(null, ?, ?);";
// 3. 执行 update 方法.
jdbcTemplate.update(sql, "iPhone3GS", 3333);
jdbcTemplate.update(sql, "iPhone4", 5000);
jdbcTemplate.update(sql, "iPhone4S", 5001);
jdbcTemplate.update(sql, "iPhone5", 5555);
jdbcTemplate.update(sql, "iPhone5C", 3888);
jdbcTemplate.update(sql, "iPhone5S", 5666);
jdbcTemplate.update(sql, "iPhone6", 6666);
jdbcTemplate.update(sql, "iPhone6S", 7000);
jdbcTemplate.update(sql, "iPhone6SP", 7777);
jdbcTemplate.update(sql, "iPhoneX", 8888);
update修改数据:
@Test
public void update() {
// 1. 创建一个 JdbcTemplate 对象, 并将数据库连接池作为参数传入
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
// 2. 执行 update 语句
String sql = "update product set pname = ?, price = ? where pid = ?;";
int count = jdbcTemplate.update(sql, "XVIII", 18888, 10);
System.out.println("count = " + count);
}
输出结果 :
count = 1
delete删除数据:
@Test
public void delete() {
// 1. 创建一个 JdbcTemplate 对象, 并将数据库连接池作为参数传入
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
// 2. 执行 delete 操作
String sql = "delete from product where pid = ?;";
int count = jdbcTemplate.update(sql, 7);
System.out.println("count = " + count);
}
输出结果 :
count = 1
5、JDBCTemplate实现查询
5.0、查询方法说明:
(1)、public <T> T queryForObject(String sql, Class<T> requiredType, Object... args):
//单行单列、返回指定Class类型的数据
(2)、public Map<String, Object> queryForMap(String sql, Object... args);
//单行多列、将一条记录放到一个map中
(3)、public List<Map<String, Object>> queryForList(String sql, Object... args);
//多行单列、返回一个list集合、list中存放的是Map类型的数据
(4)、public List<Map<String, Object>> queryForList(String sql, Object... args);
//多行多列、返回一个list集合、list中存放的是map类型数据
(5)、public <T> List<T> query(String sql, RowMapper<T> rowMapper);
//返回一个list集合、list中存放的是RowMapper指定类型的数据
(6)、query(sql,new BeanPropertyRowMapper<>(类.class));
// BeanPropertyRowMapper类实现了RowMapper接口
图解:
5.1、queryForObject返回一个单行单列的指定类型
api介绍:
public <T> T queryForObject(String sql, Class<T> requiredType, Object... args):
传入参数, 执行查询语句,返回一个指定类型的数据。
使用步骤:
创建JdbcTemplate对象
编写查询的SQL语句
使用JdbcTemplate对象的queryForObject方法,并传入需要返回的数据的类型输出结果
QueryForObject方法:
@Test
public void test1() {
// 1. 创建一个 JdbcTemplate 对象
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
// 2. 执行 queryForObject 方法
String sql = "select pname from product where price = 7777";
String pname = jdbcTemplate.queryForObject(sql, String.class);
System.out.println("pname = " + pname);
}
输出结果 :
pname = iPhone6SP
5.2、queryForMap返回一个单行多列Map集合对象
API介绍:
public Map<String, Object> queryForMap(String sql, Object... args)
传入参数,执行查询语句,将一条记录放到一个Map中。
使用步骤
创建JdbcTemplate对象
编写查询的SQL语句
使用JdbcTemplate对象的queryForMap方法
处理结果
queryForMap案例:
@Test
public void test2() {
// 1. 创建一个 JdbcTemplate 对象
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
// 2. 执行 queryForMap 方法
String sql = "select * from product where pid = ?;";
Map<String, Object> map = jdbcTemplate.queryForMap(sql, 6);
System.out.println("map = " + map);
}
输出结果 :
map = {pid=6, pname=iPhone5S, price=5666.0}
5.3、queryForList();
//返回一个list集合、list中存放的是Map类型的数据(分为多行单列、多行多列)
API介绍:
public List<Map<String, Object>> queryForList(String sql, Object... args)
传入参数,执行查询语句,返回一个List集合,List中存放的是Map类型的数据。
使用步骤
创建JdbcTemplate对象
编写查询的SQL语句
使用JdbcTemplate对象的queryForList方法
处理结果
QueryForList()案例代码
@Test
public void test3() {
// 1. 创建一个 JdbcTemplate 对象
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
// 2. 执行 objectForList 方法
String sql = "select * from product where pid < ?;";
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, 8);
for (Map<String, Object> map : list) {
System.out.println(map);
}
}
输出结果 :
{pid=1, pname=iPhone3GS, price=3333.0}
{pid=2, pname=iPhone4, price=5000.0}
{pid=3, pname=iPhone4S, price=5001.0}
{pid=4, pname=iPhone5, price=5555.0}
{pid=5, pname=iPhone5C, price=3888.0}
{pid=6, pname=iPhone5S, price=5666.0}
5.4、query使用RowMapper做映射返回对象
API介绍:
public <T> List<T> query(String sql, RowMapper<T> rowMapper)
执行查询语句,返回一个List集合,List中存放的是RowMapper指定类型的数据。
使用步骤
定义Product类
创建JdbcTemplate对象
编写查询的SQL语句
使用JdbcTemplate对象的query方法,并传入RowMapper匿名内部类
在匿名内部类中将结果集中的一行记录转成一个Product对象
案例:
Product实体类:
public class Product {
private int pid;
private String pname;
private double price;
public Product(int pid, String pname, double price) {
this.pid = pid;
this.pname = pname;
this.price = price;
}
public Product() {
}
public int getPid() {
return pid;
}
@Override
public String toString() {
return "Product{" +
"pid=" + pid +
", pname='" + pname + '\'' +
", price=" + price +
'}';
}
public void setPid(int pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
Query与rowMapper方法:
@Test
public void test4() {
// 1. 创建一个 JdbcTemplate 对象
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
// 2. 执行 query 方法
String sql = "select * from product;";
List<Product> list = jdbcTemplate.query(sql, new RowMapper<Product>() {
@Override
public Product mapRow(ResultSet rs, int i) throws SQLException {
Product product = new Product();
int pid = rs.getInt("pid");
String pname = rs.getString("pname");
double price = rs.getDouble("price");
product.setPid(pid);
product.setPname(pname);
product.setPrice(price);
return product;
}
});
// 遍历 list 集合
for (Product product : list) {
System.out.println(product);
}
}
输出结果 :
Product{pid=1, pname='iPhone3GS', price=3333.0}
Product{pid=2, pname='iPhone4', price=5000.0}
Product{pid=3, pname='iPhone4S', price=5001.0}
Product{pid=4, pname='iPhone5', price=5555.0}
Product{pid=5, pname='iPhone5C', price=3888.0}
Product{pid=6, pname='iPhone5S', price=5666.0}
Product{pid=8, pname='iPhone6S', price=7000.0}
Product{pid=9, pname='iPhone6SP', price=7777.0}
Product{pid=10, pname='XVIII', price=18888.0}
图:
5.5、query使用BeanPropertyRowMapper做映射返回对象
API介绍:
public <T> List<T> query(String sql, RowMapper<T> rowMapper)
执行查询语句,返回一个List集合,List中存放的是RowMapper指定类型的数据。
public class BeanPropertyRowMapper<T> implements RowMapper<T>
BeanPropertyRowMapper类实现了RowMapper接口
使用步骤
定义Product类
创建JdbcTemplate对象
编写查询的SQL语句
使用JdbcTemplate对象的query方法,并传入BeanPropertyRowMapper对象
代码实现:
@Test
public void test5() {
// 1. 创建一个 JdbcTemplate 对象
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
// 2. 执行 query 方法
String sql = "select * from product;";
List<Product> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Product.class));
// 3. 遍历 list 集合
for (Product product : list) {
System.out.println(product);
}
}
输出结果 :
Product{pid=1, pname='iPhone3GS', price=3333.0}
Product{pid=2, pname='iPhone4', price=5000.0}
Product{pid=3, pname='iPhone4S', price=5001.0}
Product{pid=4, pname='iPhone5', price=5555.0}
Product{pid=5, pname='iPhone5C', price=3888.0}
Product{pid=6, pname='iPhone5S', price=5666.0}
Product{pid=8, pname='iPhone6S', price=7000.0}
Product{pid=9, pname='iPhone6SP', price=7777.0}
Product{pid=10, pname='XVIII', price=18888.0}