Spring的JDBC模板
Spring是一個分層的JavaSE/EEfull-stack(一站式)輕量級開源框架。它針對JavaEE三層中的每一層都提供了不同的解決技術,在dao層,Spring提供了JDBC模板的技術,可對數據庫進行CRUD操作。Spring提供了很多持久層技術的模板類簡化了編程,如下圖:
我再次加以說明:Spring框架對不同的持久層技術做了封裝,如對傳統的JDBC使用JdbcTemplate進行了封裝,對Hibernate框架使用HibernateTemplate進行了封裝。JdbcTemplate對JDBC進行了簡單封裝,使用類似於dbutils,但是使用並沒有dbutils方便,只是提供了一種實現的方式而已。下面來演示使用JdbcTemplate模板類實現CRUD操作。
使用JdbcTemplate模板類實現CRUD操作
首先創建數據庫和表,如下:
create database spring_lee;
use spring_lee;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`username` varchar(100) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
使用JdbcTemplate模板類還須導入jar包,先引入JdbcTemplate的jar包:
但我們要知道spring-jdbc-4.2.4.RELEASE.jar包纔是最主要的。除此之外還須導入MySQL數據庫驅動的jar包。
添加操作
在src目錄下創建一個cn.itcast.jdbcTemplate包,並在該包下編寫一個JdbcTemplateDemo1單元測試類。現在要編寫一個add方法來測試添加操作。
public class JdbcTemplateDemo1 {
// 1.添加操作
@Test
public void add() {
// 1.設置數據庫相關信息(JDBC模板依賴連接池獲得數據庫連接,所以必須先構造連接池)
DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 數據源
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_lee");
dataSource.setUsername("root");
dataSource.setPassword("yezi");
// 2.做添加的操作
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "insert into user values(?,?)";
int rows = jdbcTemplate.update(sql, "liayun", "lee");
System.out.println(rows);
}
}
注意:JDBC模板依賴連接池獲得數據庫連接,所以必須先構造連接池,然後再創建JdbcTemplate模板類對象。而且還須用到JdbcTemplate模板類的update方法:
這個方法中有兩個參數:
- 第一個參數是sql語句。
- 第二個參數是傳遞的參數值,Object類型的可變參數。
修改操作
現在要在單元測試類中編寫一個update方法來測試修改操作。
public class JdbcTemplateDemo1 {
// 2.修改操作
@Test
public void update() {
// 1.設置數據庫相關信息
DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 數據源
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_lee");
dataSource.setUsername("root");
dataSource.setPassword("yezi");
// 實現修改操作
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "update user set password=? where username=?";
int rows = jdbcTemplate.update(sql, "9999", "liayun");
System.out.println(rows);
}
}
刪除操作
現在要在單元測試類中編寫一個delete方法來測試刪除操作。
public class JdbcTemplateDemo1 {
// 3.刪除操作
@Test
public void delete() {
// 1.設置數據庫相關信息
DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 數據源
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_lee");
dataSource.setUsername("root");
dataSource.setPassword("yezi");
// 實現刪除操作
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "delete from user where username=?";
int rows = jdbcTemplate.update(sql, "liayun");
System.out.println(rows);
}
}
查詢操作
查詢表中的記錄數
現在要在單元測試類中編寫一個testCount方法來測試查詢表中記錄數的操作。
public class JdbcTemplateDemo1 {
// 查詢表記錄數
@Test
public void testCount() {
// 1.設置數據庫相關信息
DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 數據源
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_lee");
dataSource.setUsername("root");
dataSource.setPassword("yezi");
// 2.創建JdbcTemplate模板類的對象
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// 3.sql語句
String sql = "select count(*) from user";
// 4.調用JdbcTemplate模板類裏面的方法
// 返回int類型
int count = jdbcTemplate.queryForObject(sql, Integer.class);
System.out.println(count);
}
}
在查詢表中記錄數的操作時,用到了JdbcTemplate模板類裏面的queryForObject方法,如下:
這個方法中有兩個參數:
- 第一個參數:sql語句
- 第二個參數:返回類型的class
查詢返回對象
使用JdbcTemplate模板類進行查詢操作的時候,還是比較麻煩的。前面我也說過JdbcTemplate對JDBC進行了簡單封裝,使用類似於dbutils,但是使用並沒有dbutils方便,只是提供了一種實現的方式而已。我是爲何這麼說呢?因爲在dbutils裏面幫我們編寫好了一些實現類,使用這些實現類可以封裝結果,這些實現類都實現了接口ResultSetHandler;使用JdbcTemplate模板類進行查詢操作返回數據結果的時候,雖然在JdbcTemplate模板類中有個接口,但是並沒有提供實現類,故還需要自己編寫實現類來封裝結果。
好了,接下來複習一下編寫JDBC最原始的代碼做查詢操作,基本功不要忘記了啊!
首先在cn.itcast.jdbcTemplate包下編寫一個User類。
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
然後再在該包下編寫一個JdbcTemplateDemo2單元測試類,編寫JDBC最原始的代碼做查詢操作。
public class JdbcTemplateDemo2 {
// jdbc最原始的代碼做查詢操作
@Test
public void testJDBC() {
Connection conn = null;
PreparedStatement psmt = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///spring_lee", "root", "yezi");
String sql = "select * from user where username=?";
// 對sql進行預編譯操作
psmt = conn.prepareStatement(sql);
psmt.setString(1, "mary");
// 執行sql
rs = psmt.executeQuery();
// 遍歷結果
while (rs.next()) {
String username = rs.getString("username");
String password = rs.getString("password");
User user = new User();
user.setUsername(username);
user.setPassword(password);
System.out.println(user);
}
} catch (Exception e) {
} finally {
try {
rs.close();
psmt.close();
conn.close();
} catch (Exception e2) {
}
}
}
}
接下來,就來講如何使用JdbcTemplate模板類進行查詢操作並返回一個User類的對象。其中就要用到JdbcTemplate模板類裏面的queryForObject方法:
這個方法有3個參數:
- 第一個參數:sql語句
- 第二個參數:RowMapper接口
- 之前使用dbutils進行查詢時,返回結果有ResultSetHandler接口,但是在dbutils裏面有其對應的實現類。
- 使用JdbcTemplate模板類的時候,雖然提供了RowMapper接口,但是這個接口沒有實現類,需要自己進行實現,然後進行數據封裝。
- 第三個參數:可變參數
現在要在JdbcTemplateDemo2單元測試類中編寫一個testObject方法來測試查詢時返回一個User類對象的操作。
public class JdbcTemplateDemo2 {
// 1.查詢返回對象
@Test
public void testObject() {
// 1.設置數據庫相關信息
DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 數據源
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_lee");
dataSource.setUsername("root");
dataSource.setPassword("yezi");
// 2.創建JdbcTemplate對象
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// 3.sql語句
String sql = "select * from user where username=?";
// 4.調用方法執行
// 第二個參數是接口,RowMapper,要自己創建一個類實現這個接口,在裏面進行封裝
User user = jdbcTemplate.queryForObject(sql, new MyRowMapper(), "mary");
System.out.println(user);
}
}
注意,還要編寫RowMapper接口的一個實現類。在以上JdbcTemplateDemo2.java源代碼文件中編寫RowMapper接口的一個MyRowMapper實現類。
// T:表示要將數據封裝到哪個類的對象中
class MyRowMapper implements RowMapper<User> {
// 實現接口裏面的方法,在方法中實現數據封裝
// 第一個參數:返回的結果集,第二個參數是當前的行數(即第幾行)
@Override
public User mapRow(ResultSet rs, int rows) throws SQLException {
// 從結果集得到數據
String username = rs.getString("username");
String password = rs.getString("password");
// 封裝到對象裏面
User user = new User();
user.setUsername(username);
user.setPassword(password);
return user;
}
}
查詢返回List集合
現在要在JdbcTemplateDemo2單元測試類中編寫一個testList方法來測試查詢時返回List集合的操作。
public class JdbcTemplateDemo2 {
// 2.返回List集合
@Test
public void testList() {
// 1.設置數據庫相關信息
DriverManagerDataSource dataSource = new DriverManagerDataSource(); // 數據源
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_lee");
dataSource.setUsername("root");
dataSource.setPassword("yezi");
// 2.查詢操作
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "select * from user";
List<User> list = jdbcTemplate.query(sql, new MyRowMapper());
System.out.println(list);
}
}
- MyRowMapper實現類與對象的相同。
在進行查詢並返回List集合的操作時,須用到JdbcTemplate模板類裏面的query方法:
或