1.Spring整合JDBC
spring提供了不少模板來整合daojava
2 . jdbc模板對象:jdbcTemplate
(1)spring中提供了一個能夠操做數據庫的模板對象:jdbcTemplate,它封裝了jdbc技術。與DBUtils中的QueryRunner很是類似。mysql
@Test public void fun1() throws Exception{ //0 準備c3p0鏈接池 ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass("com.mysql.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql:///hibernate_32"); dataSource.setUser("root"); dataSource.setPassword("1234"); //1 建立JDBC模板對象 JdbcTemplate jt = new JdbcTemplate(); jt.setDataSource(dataSource); //2 書寫sql,並執行 String sql = "insert into t_user values(null,'rose') "; jt.update(sql); }
(2)spring中jdbcTemplate演示:spring
(2.1)導包:4+2+2(spring-test.jar、spring-aop.jar)+c3p0鏈接池(com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar)和jdbc驅動(mysql-connector-java-5.0.4-bin.jar)+spring-jdbc.jar和spring-tx.jar(事務)sql
(2.2)書寫dao數據庫
package com.xing.jdbc; import java.util.List; import bean.User; public interface UserDao { public void save(User u); public void delete(Integer id); public void update(User u); public User getById(Integer id); public List<User> getAll(); public int getTotalCount(); }
書寫實現類(jdbcTemplate的得到方式2種、jdbcTemplate的訪問數據庫的API須要掌握)express
package com.xing.jdbc; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.support.JdbcDaoSupport; import bean.User; public class UserDaoImpl extends JdbcDaoSupport implements UserDao{ //使用JdbcTemplate增刪改查,獲取jdbcTemplate有兩種方式 //(1)獲取jdbcTemplate。(須要在xml中配置一個bean,並注入數據源dataSource) //public JdbcTemplate jt;//在xml中把jt屬性注入UserDao對象須要有set方法 /*public void setJt(JdbcTemplate jt) { this.jt = jt; }*/ //(2)更方便的獲取jdbcTemplate:使用繼承JdbcDaoSupport的方法來獲取jdbcTemplate:super.getJdbcTemplate()--(須要在xml中配置一個數據源dataSource) //不須要在xml中手動配置jdbc模板,使用父類方法便可得到 @Override public void save(User u) { String sql="insert into myuser values(null,?)"; super.getJdbcTemplate().update(sql, u.getUsername()); } @Override public void delete(Integer id) { String sql="delete from myuser where id=?"; super.getJdbcTemplate().update(sql, id); } @Override public void update(User u) { String sql="update myuser set name=? where id=?"; super.getJdbcTemplate().update(sql, u.getUsername(),u.getId()); } @Override public User getById(Integer id) { String sql="select * from myuser where id=?"; //API:super.getJdbcTemplate().queryForObject(sql, requiredType, args)查詢單個對象 User u = super.getJdbcTemplate().queryForObject(sql, new RowMapper<User>(){ @Override public User mapRow(ResultSet rs, int arg1) throws SQLException {//自動遍歷,arg1是遍歷次數 User u=new User(); u.setId(rs.getInt("id")); u.setUsername(rs.getString("name")); return u; } }, id); return u; } @Override public List<User> getAll() { String sql="select * from myuser"; //super.getJdbcTemplate().query(sql, rowMapper)查詢list集合類型 List<User> userList = super.getJdbcTemplate().query(sql, new RowMapper<User>(){ @Override public User mapRow(ResultSet rs, int arg1) throws SQLException { User u=new User(); u.setId(rs.getInt("id")); u.setUsername(rs.getString("name")); return u; } }); return userList; } @Override public int getTotalCount() { String sql="select count(*) from myuser"; //super.getJdbcTemplate().queryForObject(sql, requiredType)查詢值類型 Integer totalCount = super.getJdbcTemplate().queryForObject(sql, Integer.class); return totalCount; } }
(2.3)配置applicationContext.xmlapp
導入相關的約束ide
配置順序根據 依賴關係:UserDaoImpl依賴jdbcTemplate,jdbcTemplate依賴dataSource。測試
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" 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.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd "> <!-- 將鏈接池放入spring容器 --> <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql:///user"></property> <property name="user" value="root"></property> <property name="password" value="123"></property> </bean> <!-- 方式1獲取jdbcTemplate:將JDBCTemplate對象放入spring容器 --> <!-- <bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> --> <!-- 將UserDaoImpl放入spring容器 --> <bean name="userDao" class="com.xing.jdbc.UserDaoImpl"> <!-- 爲方式1注入JDBCTemplate(必須有set方法才能注入)--> <!--<property name="jt" ref="jdbcTemplate"></property>--> </bean> </beans>
改進:由於在UserDaoImpl中使用了JdbcDaoSupport類來得到jdbc模板(jdbcTemplate),因此配置文件不須要再配置jdbcTemplate對象。所以依賴關係也變了。UserDaoImpl依賴JDBCDaoSupport(須要鏈接池),只需配置鏈接池對象和UserDaoImpl對象ui
改進:使用properties配置文件讀取數據庫。
jdbc.driverClass=com.mysql.jdbc.Driver jdbc.jdbcUrl=jdbc:mysql:///user jdbc.user=root jdbc.password=123
改進的applicationcontext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" 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.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd "> <!-- 1.將鏈接池放入spring容器 --> <!-- <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql:///user"></property> <property name="user" value="root"></property> <property name="password" value="123"></property> </bean> --> <!-- 改進第一步:使用配置文件讀取 --> <context:property-placeholder location="com/xing/jdbc/db.properties"/> <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 2.將JDBCTemplate對象放入spring容器 (由於實現類使用JdbcDaoSupport獲取jdbc模板,此處不須要再配置)--> <!-- <bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> --> <!-- 3.將UserDaoImpl放入spring容器 --> <bean name="userDao" class="com.xing.jdbc.UserDaoImpl"> <!-- 使用JDBCDaoSupport來得到jdbcTemplate,此處不須要注入jt屬性了--> <!-- <property name="jt" ref="jdbcTemplate"></property> --> <!-- 由於UserDaoImpl使用JDBCDaoSupport來得到jdbcTemplate,JDBCDaoSupport須要鏈接池,此處須要注入--> <property name="dataSource" ref="dataSource"></property> </bean> </beans>
(2.4)測試
package com.xing.jdbc; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.mchange.v2.c3p0.ComboPooledDataSource; import bean.User; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:com/xing/jdbc/applicationContext.xml") public class JdbcTemplateTest { @Resource(name="userDao") UserDao userDao; @Test public void test2() { User u=new User(); u.setUsername("aliyun"); userDao.save(u); System.out.println(userDao.getAll()); System.out.println(userDao.getTotalCount()); System.out.println(userDao.getById(1)); userDao.update(u); userDao.delete(2); } }
3.spring管理事務的方式(AOP思想)
spring封裝了事務管理代碼,由於在不一樣平臺,操做事務的代碼各不相同.spring提供了一個接口:PlatformTransactionManager 接口,裏面有幾個方法分別用於不一樣平臺:DataSourceTransactionManager,HibernateTransitionmanager......注意:在spring中玩事務管理.最爲核心的對象就是TransactionManager對象
spring管理事務的方式:
(1)編碼式(瞭解)
(2)xml配置管理事務
(2.1)導包:4+2+(aop+aspect)+(aop聯盟+weaving織入包)
(2.2)導入新的約束tx(配置事務通知)
約束說明:beans最基本,context讀取properties配置,aop配置aop,tx配置事務通知
(2.3)書寫目標對象,配置通知,而且將通知織入目標
package com.xing.dao; import org.springframework.jdbc.core.support.JdbcDaoSupport; //dao層代碼,使用繼承JDBCDaoSupport來獲取jdbcTemplate。配置文件中只需注入dataSource便可 public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { @Override public void increaseMoney(Integer id, Double money) { super.getJdbcTemplate().update("update account set money=money+? where id=?", money,id); } @Override public void decreaseMoney(Integer id, Double money) { super.getJdbcTemplate().update("update account set money=money-? where id=?", money,id); } }
package com.xing.service; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import com.xing.dao.AccountDao; //目標對象(通知織入service層的方法) public class AccountServiceImpl implements AccountService { public AccountDao dao;//配置文件中注入dao便可 public void setDao(AccountDao dao) { this.dao = dao; } @Override public void transferMoney(Integer from, Integer to, Double money) { dao.decreaseMoney(from, money); int i=1/0; dao.increaseMoney(to, money); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" 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-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd "> <!-- 指定spring讀取db.properties配置 --> <context:property-placeholder location="classpath:db.properties" /> <!-- 配置鏈接池 --> <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" > <property name="jdbcUrl" value="${jdbc.jdbcUrl}" ></property> <property name="driverClass" value="${jdbc.driverClass}" ></property> <property name="user" value="${jdbc.user}" ></property> <property name="password" value="${jdbc.password}" ></property> </bean> <!-- 事務核心管理器,封裝了全部事務操做. 依賴於鏈接池 --> <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name="dataSource" ref="dataSource" ></property> </bean> <!-- 配置事務通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager" > <tx:attributes> <!-- 以方法爲單位,指定方法應用什麼事務屬性 isolation:隔離級別 propagation:傳播行爲 read-only:是否只讀 --> <tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /> <tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /> <tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /> <tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /> <tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /> <tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /> <tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" /> <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" /> <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /> </tx:attributes> </tx:advice> <!-- 將通知織入目標對象的方法 --> <aop:config > <!-- 配置切點表達式(注意:第一個星號後面加空格) --> <aop:pointcut expression="execution(* cn.itcast.service.*ServiceImpl.*(..))" id="txPc"/> <!-- 配置切面 : 通知+切點 advice-ref:通知的名稱 pointcut-ref:切點的名稱 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPc" /> </aop:config> <!-- Dao--> <bean name="accountDao" class="cn.itcast.dao.AccountDaoImpl" > <property name="dataSource" ref="dataSource" ></property> </bean> <!-- Service--> <bean name="accountService" class="cn.itcast.service.AccountServiceImpl" > <property name="dao" ref="accountDao" ></property> </bean> </beans>
package com.xing.test; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.xing.service.AccountService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class test { @Resource(name="accountService") public AccountService service; @Test public void test() { service.transferMoney(1, 2, 100d); } }
(3) 使用註解配置管理事務(代替xml配置)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd "> <context:property-placeholder location="classpath:db.properties"/> <!-- 事務核心管理器,封裝了全部事務操做. 依賴於鏈接池 --> <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name="dataSource" ref="mydataSource" ></property> </bean> <!-- 開啓使用註解管理aop事務 --> <tx:annotation-driven/> <!-- 1.配置dataSource --> <bean name="mydataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 2.配置dao --> <bean name="accountDao" class="com.xing.dao.AccountDaoImpl"> <property name="dataSource" ref="mydataSource"></property> </bean> <!-- 3.配置service --> <bean name="accountService" class="com.xing.service.AccountServiceImpl"> <property name="dao" ref="accountDao"></property> </bean> </beans>
package com.xing.service; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import com.xing.dao.AccountDao; public class AccountServiceImpl implements AccountService { public AccountDao dao; public void setDao(AccountDao dao) { this.dao = dao; } @Override //使用註解控制事務(isolation隔離級別,propagation傳播行爲,readOnly是否只讀) @Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false) public void transferMoney(Integer from, Integer to, Double money) { dao.decreaseMoney(from, money); int i=1/0;//出現異常,轉帳會失敗,數據不會改變 dao.increaseMoney(to, money); } }