980
技術社區[雲棲]
第四章 Spring與JDBC的整合
這裏選擇的是mysql數據庫。
4.1引入aop、tx的命名空間
為了事務配置的需要,我們引入aop、tx的命名空間
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://www.springframework.org/schema/beans" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:p="https://www.springframework.org/schema/p" xmlns:context="https://www.springframework.org/schema/context" xmlns:aop="https://www.springframework.org/schema/aop" xmlns:tx="https://www.springframework.org/schema/tx" xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.0.xsd https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-3.0.xsd https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
4.2配置數據源
<!-- 配置數據源 --> <bean destroy-method="close"> <!-- jdbc連接的4個必須參數 --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/> <property name="username" value="root"/> <property name="password" value="test"/> <!-- 連接池啟動初始值 --> <property name="initialSize" value="5"/> <!-- 最大空閑值 --> <property name="maxIdle" value="20"/> <!-- 最小空閑值 --> <property name="minIdle" value="5"/> <!-- 最大連接值 --> <property name="maxActive" value="500"/> </bean>
4.3配置事務
4.3.1 基於Schema的方式
<!-- 指定事務管理器 --> <bean > <property name="dataSource" ref="dataSource"></property> </bean> <!-- 設置事務增強 --> <tx:advice transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" read-only="true"/> <tx:method name="add*" rollback-for="Exception"/> </tx:attributes> </tx:advice> <!-- 作用Shcema的方式配置事務,這裏是把事務設置到了service層--> <aop:config> <aop:pointcut expression="execution(* cn.framelife.spring.jdbc.*ServiceImpl.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut"/> </aop:config>
4.3.2基於注解的方式
基本配置:
<!-- 配置數據源 --> <bean destroy-method="close"> <!-- jdbc連接的4個必須參數 --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/> <property name="username" value="root"/> <property name="password" value="test"/> <!-- 連接池啟動初始值 --> <property name="initialSize" value="5"/> <!-- 最大空閑值 --> <property name="maxIdle" value="20"/> <!-- 最小空閑值 --> <property name="minIdle" value="5"/> <!-- 最大連接值 --> <property name="maxActive" value="500"/> </bean> <!-- 指定事務管理器 --> <bean > <property name="dataSource" ref="dataSource"></property> </bean> <!-- 打開tx事務注解管理功能 --> <tx:annotation-driven transaction-manager="txManager"/>
@Transactional的使用
放在需要事務的類的頭上。如:我們想把事務集中在業務層管理,那就在service層的各個類上標注上@Transactional注解。
@Transactional @Repository public class UserDaoImpl implements UserDao { }
4.3.3事務的傳播行為
Spring給我們提供了7種類型的事務傳播行為:
PROPAGATION_REQUIRED--支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。
PROPAGATION_SUPPORTS--支持當前事務,如果當前沒有事務,就以非事務方式執行。
PROPAGATION_MANDATORY--支持當前事務,如果當前沒有事務,就拋出異常。
PROPAGATION_REQUIRES_NEW--新建事務,如果當前存在事務,把當前事務掛起。
PROPAGATION_NOT_SUPPORTED--以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
PROPAGATION_NEVER--以非事務方式執行,如果當前存在事務,則拋出異常。
我們可以通過事務的propagation屬性來進行配置。
4.3.4事務的隔離級別
事務的隔離級別是由數據庫本身提供的,一般不需要我們去改變什麼東西。
-
事務並發會產生的問題
-
髒讀 如:事務A讀到事務B未提交的數據
-
不可重複讀如:多次讀取同一個事務得到的結果不同
-
幻讀如:事務A讀到事務B已提交的數據
-
隔離級別
隔離級別 |
解釋 |
允許並發的問題 |
相應數據庫 |
READUNCOMMITED |
可讀取未提交的數據 |
ABC |
|
READCOMMITED |
讀已提交事務 |
BC |
SQLServer默認 |
REPEATABLEREAD |
可重複讀 |
C |
MySQL默認 |
SERIALIZABLE |
序列化 |
|
|
4.4JDBCTemplate的使用
public class UserDaoImpl implements UserDao { private JdbcTemplate jdbcTemplate; /** * 通過dataSource的setter方法,在運行時注入一個dataSouce對象,然後根據這個對象創建一個JdbcTemplate對象 * @param dataSource */ public void setDataSource(DataSource dataSource){ this.jdbcTemplate = new JdbcTemplate(dataSource); } /** * 增加、修改、刪除都是使用的JdbcTemplate的update方法。 * update方法中第一個參數是sql語句,未知的值用占位符?代替 * 第二個參數是一個Object數組。數組裏麵的各項是上麵的占位符的值 * 第三個參數是一個int數組。數組的各項是第二個參數中的值在數據庫中的類型 */ public void save(User user) { jdbcTemplate.update("insert into user(username,password) values(?,?)", new Object[]{user.getUsername(),user.getPassword()}, new int[]{java.sql.Types.VARCHAR,java.sql.Types.VARCHAR} ); } public void update(User user) { jdbcTemplate.update("update user set username=?,password=? where id=?", new Object[]{user.getUsername(),user.getPassword(),user.getId()}, new int[]{java.sql.Types.VARCHAR,java.sql.Types.VARCHAR,java.sql.Types.INTEGER} ); } public void delete(Integer id) { jdbcTemplate.update("delete from user where id = ?", new Object[]{id}, new int[]{java.sql.Types.INTEGER} ); } /** * 根據id獲取單個數據是通過queryForObject方法 * 這個方法前麵三個參數都與update方法一樣 * 第四個參數是一個org.springframework.jdbc.core.RowMapper接口的對象 * 實現RowMapper接口,必須實現裏麵的mapRow(ResultSet rs, int rowNum)方法 * 這個方法是通過ResultSet把一條記錄放到一個實體類對象中,並返回這個實體類對象 */ public User getUserById(Integer id) { User user = jdbcTemplate.queryForObject("select * from user where id=?", new Object[]{id}, new int[]{java.sql.Types.INTEGER}, new RowMapper<User>() { public User mapRow(ResultSet rs, int rowNum) throws SQLException { User user = new User(); user.setId(rs.getInt("id")); user.setUsername(rs.getString("username")); user.setPassword(rs.getString("password")); return user; } }); return user; } /** * 通過一條沒有占位符的select語句來查詢多條記錄,並返回一個List集合 * query方法裏麵的兩個參數 * 第一個是select語句 * 第二個是RowMapper接口的對象 */ public List<User> getUsersBySql(String sql) { return jdbcTemplate.query(sql, new RowMapper<User>() { public User mapRow(ResultSet rs, int rowNum) throws SQLException { User user = new User(); user.setId(rs.getInt("id")); user.setUsername(rs.getString("username")); user.setPassword(rs.getString("password")); return user; } }); } }
4.5完整的配置
4.5.1基於Schema
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://www.springframework.org/schema/beans" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:p="https://www.springframework.org/schema/p" xmlns:context="https://www.springframework.org/schema/context" xmlns:aop="https://www.springframework.org/schema/aop" xmlns:tx="https://www.springframework.org/schema/tx" xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.0.xsd https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-3.0.xsd https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <!-- 配置數據源 --> <bean destroy-method="close"> <!-- jdbc連接的4個必須參數 --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/> <property name="username" value="root"/> <property name="password" value="test"/> <!-- 連接池啟動初始值 --> <property name="initialSize" value="5"/> <!-- 最大空閑值 --> <property name="maxIdle" value="20"/> <!-- 最小空閑值 --> <property name="minIdle" value="5"/> <!-- 最大連接值 --> <property name="maxActive" value="500"/> </bean> <!-- 指定事務管理器 --> <bean > <property name="dataSource" ref="dataSource"></property> </bean> <!— 設置事務增強 read-only 表示對應的事務應該被最優化為隻讀事務。 rollback-for="Exception" 是指出現異常的時候回滾事務 --> <tx:advice transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" read-only="true"/> <tx:method name="add*" rollback-for="Exception"/> <tx:method name="update*"/> </tx:attributes> </tx:advice> <!-- 作用Shcema的方式配置事務 --> <aop:config> <aop:pointcut expression="execution(* cn.framelife.spring.jdbc.*ServiceImpl.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut"/> </aop:config> <!-- 把相關的Bean交由Spring管理 --> <bean > <property name="dataSource" ref="dataSource"></property> </bean> <bean > <property name="userDao" ref="userDao"></property> </bean> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://www.springframework.org/schema/beans" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:p="https://www.springframework.org/schema/p" xmlns:context="https://www.springframework.org/schema/context" xmlns:aop="https://www.springframework.org/schema/aop" xmlns:tx="https://www.springframework.org/schema/tx" xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.0.xsd https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-3.0.xsd https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <context:component-scan base-package="cn.framelife.spring"></context:component-scan> <!-- 配置數據源 --> <bean destroy-method="close"> <!-- jdbc連接的4個必須參數 --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/> <property name="username" value="root"/> <property name="password" value="test"/> <!-- 連接池啟動初始值 --> <property name="initialSize" value="5"/> <!-- 最大空閑值 --> <property name="maxIdle" value="20"/> <!-- 最小空閑值 --> <property name="minIdle" value="5"/> <!-- 最大連接值 --> <property name="maxActive" value="500"/> </bean> <!-- 指定事務管理器 --> <bean > <property name="dataSource" ref="dataSource"></property> </bean> <!-- 打開tx事務注解管理功能 --> <tx:annotation-driven transaction-manager="txManager"/> </beans>
最後更新:2017-04-03 16:48:36