Appearance
JdbcTemplate
概述
JdbcTemplate 是 Spring Framework 中的一个核心类,它提供了一种简单而有效的方式来处理 Java 应用程序中的 JDBC 操作。JdbcTemplate 封装了 JDBC 操作的细节,使得开发人员可以专注于业务逻辑的实现,而不必过多地关心底层的 JDBC API。
JdbcTemplate 主要提供以下几个方面的功能:
数据源配置和管理:JdbcTemplate 可以轻松地配置和管理数据源,可以使用内置的连接池或者自定义的连接池。
SQL 语句的执行和结果集的处理:JdbcTemplate 封装了 SQL 语句的执行过程,可以使用预编译的 SQL 语句或者命名参数的 SQL 语句。在执行 SQL 语句之后,JdbcTemplate 可以将结果集转换为 Java 对象或者基本类型。
事务管理:JdbcTemplate 可以轻松地实现事务管理,可以使用编程式事务或者声明式事务。
JdbcTemplate入门
核心API
快速入门
- 准备连接池
c3p0与druid任选其一即可,本文使用druid
- 导入 spring-jdbc
- spring-beans.jar
- spring-core.jar
- spring-jdbc.jar
- spring-tx.jar
- commons-logging.jar
- 创建 JdbcTemplate 对象
调用JdbcTemplate构造器,传入连接池对象
- 调用 update、query、queryForObject 等方法
java
@Test
public void testQuery() throws Exception {
JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
List<Product> list = jdbcTemplate.query(
"SELECT * FROM product",
new BeanPropertyRowMapper<>(Product.class)
);
System.out.println(list);
}
JdbcTemplate深入
实现聚合查询
JdbcTemplate
的queryForObject
方法,与query
方法大致相同,不同点在于query
用于处理多条结果,而queryForObject
用于处理单条结果。
java
@Test
public void testCount() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
int count = jdbcTemplate.queryForObject(
"SELECT COUNT(*) FROM product",
Integer.class
);
System.out.println(count);
}
实现增删改
JdbcTemplate
的update
方法用于执行DML
语句。同时还可以在 SQL 语句中使用?
占位,在update
方法的Object... args
可变参数中传入对应的参数。
新增数据
java
@Test
public void testInsert() throws Exception {
JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.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);
}
修改数据
java
@Test
public void testUpdate() throws Exception {
JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
String sql = "UPDATE product SET pname=?, price=? WHERE pid=?";
int i = jdbcTemplate.update(sql, "XVIII", 18888, 10);
System.out.println("受影响的行数: " + i);
}
删除数据
java
@Test
public void testDelete() throws Exception {
JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
String sql = "DELETE FROM product WHERE pid=?";
int i = jdbcTemplate.update(sql, 7);
System.out.println("受影响的行数: " + i);
}
事务控制
借助TransactionSynchronizationManager
java
@Test
public void testTx() {
DataSource dataSource = DataSourceUtils.getDataSource();
//实例jdbcTemplate
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
//启动事务管理器(获取datasource操作数据库连接对象并绑定到当前线程中)
TransactionSynchronizationManager.initSynchronization();
//从数据源中获取jdbcTemplate操作的当前连接对象
Connection connection = DataSourceUtils.getConnection(dataSource);
try {
connection.setAutoCommit(false);
//添加收藏数: uid rid date
int addFlag = favoriteDao.addFavorite(jdbcTemplate,uid, rid, new Date());
//更新收藏数量
int updateFlag = routeDao.updateRouteCountByRid(jdbcTemplate,rid);
connection.commit();
return true;
} catch (Exception e) {
//出现异常则回滚
try {
connection.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
System.out.println("回滚了!");
return false;
} finally {
try {
//释放资源
//释放当前线程与连接对象的绑定
TransactionSynchronizationManager.clearSynchronization();
//重置当前连接为自动提交事务
connection.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
借助TransactionTemplate
java
@Bean(name="transactionManager")
public DataSourceTransactionManager transactionManager(@Autowired DruidDataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "txTemplate")
public TransactionTemplate transactionTemplate (@Autowired DataSourceTransactionManager transactionManager){
return new TransactionTemplate(transactionManager);
}
@Test
public void testTx() {
String sql1 = "INSERT INTO user_tmp(`id`, `username`) VALUES(?, ?)";
Object[] args1 = new Object[] {22, 222};
String sql2 = "INSERT INTO user_tmp(`id`, `username`) VALUES(?, ?)";
Object[] args2 = new Object[] {1, 111};
txTemplate.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus transactionStatus) {
Object savepoint = transactionStatus.createSavepoint();
// DML执行
try {
int rs1 = jdbcTemplate.update(sql1, args1);
int rs2 = jdbcTemplate.update(sql2, args2);
} catch (Throwable e) {
LOG.error("Error occured, cause by: {}", e.getMessage());
transactionStatus.setRollbackOnly();
// transactionStatus.rollbackToSavepoint(savepoint);
}
return null;
}
});
}
学习目标总结
- 能够使用 JdbcTemplate 执行 SQL 语句
- 能够理解 JdbcTemplate 的原理