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 { conn = JDBCUtils.getConnection();
conn.setAutoCommit(false);
String outSql = "update account set money = money - ? where name = ?;"; stmt = conn.prepareStatement(outSql); stmt.setInt(1, 1000); stmt.setString(2, "tom"); stmt.executeUpdate();
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 { 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包
\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: <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: <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) {
String sql = "create table product (" + "pid int primary key auto_increment," + "pname varchar(20)," + "price double" + ");";
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
jdbcTemplate.execute(sql); } }
|
4通过jdbcTemplate实现增删改
API介绍
1 2 3
| 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() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
String sql = "insert into product values(null, ?, ?);";
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() { JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
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类型的数据。
public <T> List<T> query(String sql, RowMapper<T> rowMapper) 执行查询语句,返回一个List集合,List中存放的是RowMapper指定类型的数据。
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() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
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() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
String sql = "select * from product where pid = ?;"; Map<String, Object> map = jdbcTemplate.queryForMap(sql, 6); System.out.println("map = " + map); }
@Test public void test3() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
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() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
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; } });
for (Product product : list) { System.out.println(product); } }
@Test public void test5() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
String sql = "select * from product;"; List<Product> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Product.class));
for (Product product : list) { System.out.println(product); } }
|
三、小结:
JDBCTemplate的query方法用于执行SQL语句,简化JDBC的代码。同时还可以在SQL语句中使用?占位,在query方法的Object... args可变参数中传入对应的参数。