Jdbc的使用 和 Spring進行事務控制
1.Spring與JDBC
我們知道使用JDBC開發特點是 固定程式碼+動態引數 ;
場景描述:通過客戶id查詢客戶資訊;
(1) 圖解 Spring與JDBC操作
(2) dao實現
public interface ClientDao {
FClient findClientByid(int id) throws Exception;
int insertClient(FClient client) throws Exception;
}
介面實現類 :注入 dataSource
public class ClientDaoImpl implements ClientDao{ private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } @Override public FClient findClientByid(int id) throws Exception { FClient fClient = new FClient(); Connection conn = dataSource.getConnection(); String sql="select * from f_client where id=?"; PreparedStatement pstm = conn.prepareStatement(sql); pstm.setInt(1,id); ResultSet rs = pstm.executeQuery(); while (rs.next()) { fClient.setUsername(rs.getString("username")); } return fClient; } @Override public int insertClient(FClient client) throws Exception { // TODO Auto-generated method stub return 0; } }
(3)ApplicationContext.xml
<?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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <context:property-placeholder location="classpath:db.properties"/> <bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${oracle.driver}"></property> <property name="url" value="${oracle.url}"></property> <property name="username" value="${oracle.name}"></property> <property name="password" value="${oracle.pass}"></property> </bean> <!-- 使用dao測試資料載入 --> <bean id="ClientDao" class="cn.labelnet.dao.impl.ClientDaoImpl"> <property name="dataSource" ref="datasource"></property> </bean> </beans>
(4)測試
private ApplicationContext applicationContext; @Before public void setUp() throws Exception { applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml"); } @Test public void test() throws Exception { ClientDao dao=(ClientDao) applicationContext.getBean("ClientDao"); FClient clientByid = dao.findClientByid(15); System.out.println(clientByid); }
2.Spring 與 JDBC 使用 SqlTemplate 操作
(1)圖解
(2)dao實現
public interface ClientDao {
FClient findClientByid(int id) throws Exception;
int insertClient(FClient client) throws Exception;
}
介面 :
public class ClientDaoTwo extends JdbcDaoSupport implements ClientDao{
@Override
public FClient findClientByid(int id) throws Exception {
String sql="select * from f_client where id="+id;
List<FClient> query = this.getJdbcTemplate().query(sql,new ClientRowMapper());
return query.get(0);
}
@Override
public int insertClient(FClient client) throws SQLException{
String sql="insert into yuan_test(id,uname) values("+client.getId()+",'"+client.getUsername()+"')";
System.out.println(sql);
this.getJdbcTemplate().execute(sql);
return 1;
}
}
幫助類 :
說明: 實現RowMapper介面,相當與在執行ResultSet的迴圈體中的內容;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
import cn.labelnet.po.FClient;
public class ClientRowMapper implements RowMapper<FClient> {
@Override
public FClient mapRow(ResultSet rs, int arg1) throws SQLException {
FClient client=new FClient();
client.setId(rs.getInt("id"));
client.setUsername(rs.getString("username"));
client.setClient_certificate_no(rs.getString("client_certificate_no"));
return client;
}
}
(3)ApplicationContext.xml 配置實現
注意: 配置資料來源 dataSource ,實現是 org.apache.commons.dbcp.BasicDataSource;
配置bean-jdbcTemplete,實現是 org.springframework.jdbc.core.JdbcTemplate;
配置bean-daoimpl介面實現類 ,繼承 jdbcDaoSupport;
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${oracle.driver}"></property>
<property name="url" value="${oracle.url}"></property>
<property name="username" value="${oracle.name}"></property>
<property name="password" value="${oracle.pass}"></property>
</bean>
<!-- 使用jdbcTemplete,載入資料 -->
<bean id="jdbcTemplete" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="datasource"></property>
</bean>
<!-- 使用JdbcDaoSupport -->
<bean id="ClientDaoTwo" class="cn.labelnet.two.ClientDaoTwo">
<property name="jdbcTemplate" ref="jdbcTemplete"></property>
</bean>
</beans>
(4)測試
private ApplicationContext applicationContext;
@Before
public void setUp() throws Exception {
applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void testJdbcDaoSupport() throws Exception {
ClientDao dao=(ClientDao) applicationContext.getBean("ClientDaoTwo");
FClient clientByid = dao.findClientByid(15);
System.out.println(clientByid);
}
3.Spring宣告式事務處理
(1)Service 實現
在這裡我們繼續使用上面的JdbcTemplete方式的dao層,這裡實現Service層,來進行Spring進行事務管理;
Spring宣告式事務處理
宣告:針對開發汪,開發汪告訴spring容器,那些方法需要事務和那些不需要事務;
事務:事務處理(開啟,提交,回滾事務)
目的:讓spring管理事務,開發者不再關注事務;
Service介面實現:
public interface ClientServiceTwo {
String insertClient(FClient c) throws Exception;
}
Service介面實現 :
1.在這裡我們使用自定義異常來捕獲Service層異常資訊(相當與切面);
2.我們使用Spring來進行事務處理,而非我們自定義的事務處理;
public class ClientServiceTwoImpl implements ClientServiceTwo{
private ClientDao clientdao;
public void setClientdao(ClientDao clientdao) {
this.clientdao = clientdao;
}
@Override
public String insertClient(FClient c) throws Exception {
return clientdao.insertClient(c)>0?"成功":"失敗";
}
}
(2)配置實現
注意:
1) 配置dao , 配置 service , 配置 Exception 切面 ;
2) 配置transactionManager ,使用org.springframework.jdbc.datasource.DataSourceTransactionManager ;
3) 配置AOP , 包括切入點
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${oracle.driver}"></property>
<property name="url" value="${oracle.url}"></property>
<property name="username" value="${oracle.name}"></property>
<property name="password" value="${oracle.pass}"></property>
</bean>
<!-- 使用dao測試資料載入 -->
<bean id="ClientDao" class="cn.labelnet.dao.impl.ClientDaoImpl">
<property name="dataSource" ref="datasource"></property>
</bean>
<!-- 下面測試spring事務處理 -->
<bean id="clientTwoDao" class="cn.labelnet.two.ClientDaoTwo">
<property name="jdbcTemplate" ref="jdbcTemplete"></property>
</bean>
<bean id="clientTwoService" class="cn.labelnet.two.service.ClientServiceTwoImpl">
<property name="clientdao" ref="clientTwoDao"></property>
</bean>
<!-- 切面:異常 -->
<bean id="MyException" class="cn.labelnet.exception.MyException"></bean>
<!-- 事務 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"></property>
</bean>
<tx:advice id="tx" transaction-manager="transactionManager">
<tx:attributes>
<!--
name規定方法 isolation 預設值為DEFAULT propagation 傳播機制 REQUIRED
-->
<tx:method name="insertClient*" read-only="false" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* cn.labelnet.two.service.*.*(..))" id="perform"/>
<!-- 配置事務提交 -->
<aop:advisor advice-ref="tx" pointcut-ref="perform"/>
<aop:aspect ref="MyException">
<aop:after-throwing method="printException" throwing="msg" pointcut-ref="perform"/>
</aop:aspect>
</aop:config>
</beans>
(3)測試
@Test
public void testJdbcService() throws Exception {
ClientServiceTwo service=(ClientServiceTwo) applicationContext.getBean("clientTwoService");
FClient fc = new FClient();
fc.setId(205);
fc.setUsername("測試使用者名稱");
String result = service.insertClient(fc);
System.out.println(result);
}
(4)總結
採用什麼樣的方法處理事務,目標方法採用什麼樣的事務處理策略;
1)搭建環境
2)在spring的配置檔案中,匯入dataSource
3)測試datasource
4)進行aop的配置:引入事務管理器
5)測試service層的類是否是代理物件