Spring JDBC是Spring框架用來處理關系型數據庫的模塊,對JDBC的API進行了封裝。
Spring JDBC的核心類為JdbcTemplate,提供數據CRUD方法
Spring JDBC使用步驟
- Maven工程引入依賴spring-jdbc
<dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.6.RELEASE</version>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.27</version>
</dependency>
- xml中配置DataSource數據源
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property><property name="url" value="jdbc:mysql://localhost:3306/test"></property><property name="username" value="root"></property><property name="password" value="root"></property>
</bean>
- xml中定義JdbcTemplate Bean,讓IoC容器初始化時自動實例化
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property>
</bean>
- 在需要增刪改查的Dao中,持有JdbcTemplate屬性,并設置getter和setter方法,然后在對應的業務處理方法中,調用JdbcTemplate的指定方法。
public class EmployeeDao {private JdbcTemplate jdbcTemplate;//數據查詢方法public Employee findById(Integer eno){String sql="select * from employee where eno = ?";Employee employee = jdbcTemplate.queryForObject(sql,new Object[]{eno},new BeanPropertyRowMapper<>(Employee.class));return employee;}public JdbcTemplate getJdbcTemplate() {return jdbcTemplate;}public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}
}
- 在xml中為Dao類注入JdbcTemplate對象
<bean id="employeeDao" class="spring.jdbc.dao.EmployeeDao"><property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
JdbcTemplate數據查詢方法:
例:
public List<Employee> findByDname(String dname){String sql = "select * from employee where dname = ?";List<Employee> list = jdbcTemplate.query(sql,new Object[]{dname},new BeanPropertyRowMapper<>(Employee.class));return list;
}
public List<Map<String, Object>> findMapByDname(String dname){String sql = "select eno as empno,salary as s from employee where dname = ?";List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, new Object[]{dname});return maps;
}
JdbcTemplate數據寫入方法:
例:
public void insert(Employee employee){String sql = "insert into employee(eno,ename,salary,dname) values(?,?,?,?)";//利用update方法實現數據寫入操作jdbcTemplate.update(sql,new Object[]{employee.getEno(),employee.getEname(),employee.getSalary(), employee.getDname()});}public int update(Employee employee){String sql = "update employee set ename=?,salary=?,dname=? where eno=?";//利用update方法實現數據更新操作int count = jdbcTemplate.update(sql,new Object[]{employee.getEname(),employee.getSalary(), employee.getDname(),employee.getEno()});return count;}public int delete(Integer eno){String sql = "delete from employee where eno = ?";//利用update方法實現數據刪除操作return jdbcTemplate.update(sql,new Object[]{eno});}
Spring事務管理
事務是一種可靠、一致的方式,是訪問操作數據庫的程序單元,事務要么把事情做完,要么不做,不會做一半停止。
事務依賴數據庫實現,MySQL通過事務區
作為數據緩沖地帶。
編程式事務
通過代碼手動提交回滾事務的事務控制方式。
SpringJDBC通過TransactionManager事務管理器實現事務控制。
TransactionManager事務管理器提供commit、rollback方法進行事務提交和回滾。
編程式事務使用步驟:
- 配置事務管理器
<!-- 事務管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean>
- 在需要開啟事務的業務類中,持有事務管理器屬性,并設置getter和setter方法
private DataSourceTransactionManager transactionManager;public DataSourceTransactionManager getTransactionManager() {return transactionManager;}public void setTransactionManager(DataSourceTransactionManager transactionManager) {this.transactionManager = transactionManager;}
- 配置事務管理器對象注入
<bean id="employeeService" class="spring.jdbc.service.EmployeeService"><property name="employeeDao" ref="employeeDao"></property><property name="transactionManager" ref="transactionManager"></property>
</bean>
- 定義事務默認的標準配置,開啟事務,進行事務管理
聲明式事務
在不修改代碼的情況下通過配置的形式實現事務控制,本質就是AOP環繞通知。
聲明式事務的觸發時機:
- 當目標方法執行成功時,自動提交事務
- 當目標方法拋出
運行時異常
時,自動事務回滾
聲明式事務配置過程:
- 需要添加AOP依賴
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version>
</dependency>
- 添加tx和aop命名空間
- 配置TransactionManager事務管理器
<!-- 事務管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean>
- 配置事務通知與事務屬性
<!--事務通知配置,決定哪些方法使用事務,哪些方法不使用事務--><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!--propagation事務傳播行為--><!--當目標方法名為batchImport時,啟用聲明式事務,運行成功提交事務,運行時異常回滾--><!--目標方法允許使用通配符*--><tx:method name="batchImport" propagation="REQUIRED"/><!--設置所有findXXX方法不啟用事務--><tx:method name="find*" propagation="NOT_SUPPORTED" read-only="true"/><tx:method name="get*" propagation="NOT_SUPPORTED" read-only="true"/><!--設置其他方法不啟用事務--><tx:method name="*" propagation="NOT_SUPPORTED" read-only="true"/></tx:attributes></tx:advice>
- 為事務通知綁定PointCut切點
<!--定義聲明式事務的作用范圍--><aop:config><aop:pointcut id="pointcut" expression="execution(* spring.jdbc..*Service.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/></aop:config>
事務傳播行為propagation
多個擁有事務的方法在嵌套調用時的事務控制方式。
注解配置聲明式事務
- xml配置
<context:component-scan base-package="spring.jdbc"/><!--數據源--><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property><property name="url" value="jdbc:mysql://localhost:3306/test"></property><property name="username" value="root"></property><property name="password" value="root"></property></bean><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean><!--事務管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!--啟用注解形式聲明式事務--><tx:annotation-driven transaction-manager="transactionManager"/>
- 分層添加組件注解,實例化對象
@Repository
public class EmployeeDao {@Resourceprivate JdbcTemplate jdbcTemplate;...
@Service
public class EmployeeService {@Resourceprivate EmployeeDao employeeDao;...
- 需要開啟事務的類添加@Transactional注解,可以設置事務傳播行為,如
@Transactional(propagation = Propagation.REQUIRED
或者為方法單獨設置事務管理方式,程序執行時優先應用方法上的配置