18JavaSEJDBC_事务&JDBCTemplate

一、JDBC_事务

通过JDBC来操作银行转账的事务

1.API介绍

Connection接口中与事务有关的方法
1
2
3
4
5
6
void setAutoCommit(boolean autoCommit) throws SQLException;
false:开启事务, ture:关闭事务
void commit() throws SQLException;
提交事务
void rollback() throws SQLException;
回滚事务

案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JDBCTransactionTest {
public static void main(String[] args) {

Connection conn = null;
PreparedStatement stmt = null;

try {
// 1. 获取连接对象
conn = JDBCUtils.getConnection();

// 第一步 : 开启事务
conn.setAutoCommit(false);

// 2. 操作数据
// 2.1 账户转出
String outSql = "update account set money = money - ? where name = ?;";
stmt = conn.prepareStatement(outSql);
stmt.setInt(1, 1000);
stmt.setString(2, "tom");
stmt.executeUpdate();

// 模拟异常 ...
// int num = 10 / 0;

// 2.2 账户转入
String inSql = "update account set money = money + ? where name = ?;";
stmt = conn.prepareStatement(inSql);
stmt.setInt(1, 1000);
stmt.setString(2, "jery");
stmt.executeUpdate();

// 第二步 : 提交事务
conn.commit();

System.out.println("转账成功!");

} catch (Exception e) {
// 如果出现异常, 需要进行事务回滚.
// 第三步 : 回滚事务
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}

System.out.println("转账失败!");

} finally {
// 3. 释放资源
JDBCUtils.release(conn, stmt);
}
}
}

二、jdbcTemplate

1.API介绍

org.springframework.jdbc.core.JdbcTemplate类方便执行SQL语句
1
2
3
4
public JdbcTemplate(DataSource dataSource)
创建JdbcTemplate对象,方便执行SQL语句
public void execute(final String sql)
execute可以执行所有SQL语句,因为没有返回值,一般用于执行DML语句。

2.使用步骤

1. 准备DruidDataSource连接池

\2. 导入依赖的jar包

  • spring-beans

  • spring-core

  • spring-jdbc

  • spring-tx

  • com.springsource.org.apache.commons.logging.jar

\3. 创建JdbcTemplate对象,传入c3p0连接池

\4. 调用execute、update、queryXxx等方法

3.案例

(1)c3p0-config.xml配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默认配置,c3p0框架默认加载这段默认配置 -->
<default-config>
<!-- 配置JDBC 四个基本属性 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb?</property>
<property name="user">root</property>
<property name="password">111</property>
</default-config>
<!-- 可以自定义配置,为这段配置起一个名字,c3p0指定名称加载配置 -->
<named-config name="xxxxx">
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb?</property>
<property name="user">root</property>
<property name="password">111</property>
</named-config>
</c3p0-config>
(2)JDBCUtils工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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的exeucte方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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实现增删改

API介绍
1
2
3
// org.springframework.jdbc.core.JdbcTemplate类方便执行SQL语句
public int update(final String sql)
用于执行`INSERT`、`UPDATE`、`DELETE`等DML语句

使用步骤:

1.创建JdbcTemplate对象

2.编写SQL语句

3.使用JdbcTemplate对象的update方法进行增删改

1.insert 增加数据 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@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);
}

2.update 修改数据 :

1
2
3
4
5
6
7
8
9
10
11
@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);
}

3.delete 删除数据 :

1
2
3
4
5
6
7
8
9
10
@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);
}

小结:

JdbcTemplate的update方法用于执行DML语句。同时还可以在SQL语句中使用?占位,在update方法的Object… args可变参数中传入对应的参数。

5 jdbcTemplate实现查询

API介绍

 queryForObject返回一个指定类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 单行单列的查询
public <T> T queryForObject(String sql, Class<T> requiredType, Object... args):
传入参数, 执行查询语句,返回一个指定类型的数据。

// 单行多列
public Map<String, Object> queryForMap(String sql, Object... args)
传入参数,执行查询语句,将一条记录放到一个Map中。

// 多行多列
public List<Map<String, Object>> queryForList(String sql, Object... args)
传入参数,执行查询语句,返回一个List集合,List中存放的是Map类型的数据。

// 返回一个List 存放对象数据
public <T> List<T> query(String sql, RowMapper<T> rowMapper)
执行查询语句,返回一个List集合,List中存放的是RowMapper指定类型的数据。

// 提供了一个上述方法的一个实现类 RowMapper 行映射接口 BeanPropertyRowMapper 实体类属性行映射
public class BeanPropertyRowMapper<T> implements RowMapper<T>
BeanPropertyRowMapper类实现了RowMapper接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
@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);
}

@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);
}

@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);
}
}



@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);
}
}



@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);
}
}

三、小结:

JDBCTemplate的query方法用于执行SQL语句,简化JDBC的代码。同时还可以在SQL语句中使用?占位,在query方法的Object... args可变参数中传入对应的参数。 

Powered by Hexo and Hexo-theme-hiker

Copyright © 2016 - 2018 Francis的个人博客 All Rights Reserved.

UV : | PV :