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 = newDriverManagerDataSource(); // 數據源 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模板類中有個接口,但是並沒有提供實現類,故還需要自己編寫實現類來封裝結果。
首先在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 + "]"; } }
接下來,就來講如何使用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); } }
在進行查詢並返回List集合的操作時,須用到JdbcTemplate模板類裏面的query方法:
或
Spring配置連接池
在實際開發中,一般都會用Spring配置C3P0連接池,所以下面我就來重點介紹在Spring中如何配置C3P0連接池。
首先引入Spring的配置文件,主要是引入約束:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> </beans>
接著導入Spring的基本jar包,除此之外,還要導入C3P0的jar包:
試想要是以前在Web項目中配置C3P0連接池,勢必會寫這樣的代碼:
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setUser(user);
dataSource.setPassword(password);
而現在我們就可以在Spring配置文件(bean2.xml)中配置C3P0連接池了,即在Spring配置文件中添加如下配置:
<!-- 配置C3P0連接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql:///spring_lee"></property> <property name="user" value="root"></property> <property name="password" value="yezi"></property> </bean>
現在舉例來演示如何在Spring中配置C3P0連接池了。創建一個UserService類和一個UserDao類,然後在UserService類裏面調用UserDao類的方法,在UserDao類中使用JdbcTemplate模板類進行數據庫CRUD操作,並且用上C3P0連接池。
先在src目錄下創建一個cn.itcast.c3p0包,並在該包下編寫一個UserDao類。
public class UserDao { // 在Dao裏面要得到JdbcTemplate對象 private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } // 添加操作,使用JdbcTemplate模板來實現添加 public void add() { String sql = "insert into user values(?,?)"; jdbcTemplate.update(sql, "李阿昀", "lee"); } }
再在該包下編寫一個UserService類,並在UserService類裏面調用UserDao類的add方法。
public class UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void add() { userDao.add(); } }
那麽Spring核心配置文件就應該像下面這樣配置:
<!-- 配置service和dao以及它們的註入 --> <bean id="userService" class="cn.itcast.c3p0.UserService"> <property name="userDao" ref="userDao"></property> </bean> <bean id="userDao" class="cn.itcast.c3p0.UserDao"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <!-- 配置JdbcTemplate模板類的對象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!-- 註入dataSource,因為在其源代碼中dataSource屬性有其對應的set方法,故可直接註入 --> <property name="dataSource" ref="dataSource"></property> </bean>
從上面的配置可看出:UserDao中註入了JdbcTemplate對象,JdbcTemplate對象裏面又註入了dataSource。
最後再在該包下編寫一個TestDemo單元測試類。
public class TestDemo { @Test public void testBook() { ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml"); UserService userService = (UserService) context.getBean("userService"); userService.add(); } }
Spring的JDBC模板