建立項目,導入jar包java
引入配置文件applicationContext.xmlmysql
<?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
package com.itzhouq.spring.demo1; public class OrderDao { public void save() { System.out.println("保存訂單。。。"); } public void update() { System.out.println("修改訂單。。。"); } public void find() { System.out.println("查找訂單。。。"); } public String delete() { System.out.println("刪除訂單。。。"); return "周杰倫"; } }
配置目標類,將目標類OrderDao交給Spring管理sql
<!-- 配置目標類 --> <bean id="orderDao" class="com.itzhouq.spring.demo1.OrderDao"></bean>
package com.itzhouq.spring.demo1; /* * 切面類:註解的切面類 */ public class MyAspectAnno { public void before() { System.out.println("前置加強==============="); } }
<!-- 配置切面類 --> <bean id="myAspect" class="com.itzhouq.spring.demo1.MyAspectAnno"></bean>
使用註解的AOP對目標類的方法進行加強數據庫
首先在配置文件中打開註解的AOP開發express
<!-- 在配置文件總開啓註解的AOP開發 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
/* * 切面類:註解的切面類 */ @Aspect //標記該類爲切面類 public class MyAspectAnno { @Before(value="execution(* com.itzhouq.spring.demo1.OrderDao.save(..))") public void before() {//這個註解用來標記目標類的哪一個方法使用何種加強 System.out.println("前置加強==============="); } }
package com.itzhouq.spring.demo1; 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; /* * Spring的AOP註解開發測試 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class SpringDemo1 { @Resource(name="orderDao") //注入OrderDao private OrderDao orderDao; @Test public void test1() { orderDao.save(); orderDao.update(); orderDao.find(); orderDao.delete(); // 前置加強=============== // 保存訂單。。。 // 修改訂單。。。 // 查找訂單。。。 // 刪除訂單。。。 } }
在切面類中添加如下方法apache
//後置通知 @AfterReturning("execution(* com.itzhouq.spring.demo1.OrderDao.delete(..))") public void afterReturning() { System.out.println("後置加強=================="); }
不用修改目標類直接測試就能實現效果編程
前置加強=============== 保存訂單。。。 修改訂單。。。 查找訂單。。。 刪除訂單。。。 後置加強==================
後置通知還能夠使用返回值安全
//後置通知 @AfterReturning(value="execution(* com.itzhouq.spring.demo1.OrderDao.delete(..))", returning="result") public void afterReturning(Object result) { System.out.println("後置加強=================="+result); }
前置加強=============== 保存訂單。。。 修改訂單。。。 查找訂單。。。 刪除訂單。。。 後置加強==================周杰倫
在切面類中添加如下方法:app
//環繞通知 @Around(value="execution(* com.itzhouq.spring.demo1.OrderDao.update(..))") public Object around(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println("環繞前加強==========="); Object obj = joinPoint.proceed(); System.out.println("環繞前加強==========="); return obj; }
測試
前置加強=============== 保存訂單。。。 環繞前加強=========== 修改訂單。。。 環繞前加強=========== 查找訂單。。。 刪除訂單。。。 後置加強==================周杰倫
在切面類中添加方法
//異常拋出通知 @AfterThrowing(value="execution(* com.itzhouq.spring.demo1.OrderDao.find(..))",throwing="e") public void afterThrowing(Throwable e) { System.out.println("異常拋出通知============"+e); }
在find方法中模擬異常
public void find() { System.out.println("查找訂單。。。"); int i = 1 / 0; }
測試
前置加強=============== 保存訂單。。。 環繞前加強=========== 修改訂單。。。 環繞前加強=========== 查找訂單。。。 異常拋出通知============java.lang.ArithmeticException: / by zero
在切面類中添加方法
//最終通知 @After(value="execution(* com.itzhouq.spring.demo1.OrderDao.find(..))") public void after() { System.out.println("最終加強============"); }
測試
前置加強=============== 保存訂單。。。 環繞前加強=========== 修改訂單。。。 環繞前加強=========== 查找訂單。。。 最終加強============ 異常拋出通知============java.lang.ArithmeticException: / by zero
package com.itzhouq.spring.demo1; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; /* * 切面類:註解的切面類 */ @Aspect //標記該類爲切面類 public class MyAspectAnno { @Before(value="MyAspectAnno.pointcut2()") public void before() {//這個註解用來標記目標類的哪一個方法使用何種加強 System.out.println("前置加強==============="); } //後置通知 @AfterReturning(value="execution(* com.itzhouq.spring.demo1.OrderDao.delete(..))", returning="result") public void afterReturning(Object result) { System.out.println("後置加強=================="+result); } //環繞通知 @Around(value="MyAspectAnno.pointcut3()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println("環繞前加強==========="); Object obj = joinPoint.proceed(); System.out.println("環繞前加強==========="); return obj; } //異常拋出通知 @AfterThrowing(value="MyAspectAnno.pointcut4()",throwing="e") public void afterThrowing(Throwable e) { System.out.println("異常拋出通知============"+e); } //最終通知 @After(value="MyAspectAnno.pointcut1()") public void after() { System.out.println("最終加強============"); } //切入點註解 @Pointcut(value="execution(* com.itzhouq.spring.demo1.OrderDao.find(..))") private void pointcut1() {} @Pointcut(value="execution(* com.itzhouq.spring.demo1.OrderDao.save(..))") private void pointcut2() {} @Pointcut(value="execution(* com.itzhouq.spring.demo1.OrderDao.update(..))") private void pointcut3() {} @Pointcut(value="execution(* com.itzhouq.spring.demo1.OrderDao.delete(..))") private void pointcut4() {} }
建立項目,引入jar包
建立數據庫和表
create database spring4_day03; use spring4_day03; create table account( id int primary key auto_increment, name varchar(20), money double )
package com.itzhouq.spring.jdbc.demo1; import org.junit.Test; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; /* * JDBC的模板使用 */ public class JdbcDemo1 { @Test //JDBC的模板的使用相似於Dbutils public void test1() { //建立鏈接池 這裏使用Spring默認的鏈接池 DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql:///spring4_day03"); dataSource.setUsername("root"); dataSource.setPassword("2626"); //建立jdbc模板 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate.update("insert into account values (null, ?,?)", "周杰倫",10000d); } }
將日誌記錄的配置文件jdbc.properties拷貝到src下
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/spring4_day03 jdbc.username=root jdbc.password=2626
引入Spring的配置文件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: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的內置鏈接池,將鏈接池交給Spring管理
<!-- 配置Spring的內置鏈接池 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!-- 屬性注入 ===============--> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql:///spring4_day03"></property> <property name="username" value="root"></property> <property name="password" value="2626"></property> </bean>
配置Spring的jdbc模板,將模板交給Spring管理
<!-- 配置Spring的JDBC模板 =================--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
使用JDBC的模板
package com.itzhouq.spring.jdbc.demo1; 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; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(value="classpath:applicationContext.xml") public class JdbcDemo2 { @Resource(name="jdbcTemplate") private JdbcTemplate jdbcTemplate; @Test public void test1() { jdbcTemplate.update("insert into account values (null, ?,?)", "趙雷",10000d); } }
導入jar包
路徑
配置C3P0鏈接池
<!-- 配置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:///spring4_day03"></property> <property name="user" value="root"></property> <property name="password" value="2626"></property> </bean> <!-- 配置Spring的JDBC模板 =================--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
引入jar包
路徑
配置DBCP的鏈接池
<!-- 配置DBCP鏈接池 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 屬性注入 =============== <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql:///spring4_day03"></property> <property name="username" value="root"></property> <property name="password" value="2626"></property> </bean> <!-- 配置Spring的JDBC模板 =================--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
org.apache.commons.dbcp.BasicDataSource
。在src下新建配置文件jdbc.properties
jdbc.driverClass=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/spring4_day03 jdbc.username=root jdbc.password=2626
在Spring的配置文件中引入屬性文件
<!-- 引入鏈接數據的屬性文件 --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置C3P0鏈接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 屬性注入 =============== --> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean>
package com.itzhouq.spring.jdbc.demo1; 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; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(value="classpath:applicationContext.xml") public class JdbcDemo2 { @Resource(name="jdbcTemplate") private JdbcTemplate jdbcTemplate; @Test public void test1() { jdbcTemplate.update("insert into account values (null, ?,?)", "YYY",10000d); } }
@Test public void test3() {//刪除 jdbcTemplate.update("delete from account where id = ?", 5); }
@Test public void test2() {//修改 jdbcTemplate.update("update account set name = ?, money = ? where id = ?", "何巨濤",10000d, 6); }
查詢某個屬性
@Test public void test4() {//查詢某個屬性 String name = jdbcTemplate.queryForObject("select name from account where id = ?", String.class, 6); System.out.println(name); }
查詢個數
@Test public void test5() {//查詢個數 Long count = jdbcTemplate.queryForObject("select count(*) from account", Long.class); System.out.println(count); }
返回的是對象
首先要建立一個實體Account
@Test public void test6() {//封裝到一個對象中 Account account = jdbcTemplate.queryForObject("select * from account where id = ?", new MyRowMapper(), 4); System.out.println(account); } class MyRowMapper implements RowMapper<Account>{ @Override public Account mapRow(ResultSet rs, int rowNum) throws SQLException { Account account = new Account(); account.setId(rs.getInt("id")); account.setName(rs.getString("name")); account.setMoney(rs.getDouble("money")); return account; } }
查詢多條記錄
@Test public void test7() { List<Account> listAccount = jdbcTemplate.query("select * from account", new MyRowMapper()); for (Account account : listAccount) { System.out.println(account); } } class MyRowMapper implements RowMapper<Account>{ @Override public Account mapRow(ResultSet rs, int rowNum) throws SQLException { Account account = new Account(); account.setId(rs.getInt("id")); account.setName(rs.getString("name")); account.setMoney(rs.getDouble("money")); return account; } }
讀問題
寫問題
設置事務的隔離級別
平臺事務管理器:接口,是Spring用於管理事務的真正的對象。
package com.itzhouq.spring.tx.demo1; /* * 轉帳的業務層的接口 */ public interface AccountService { public void transfer(String from, String to, Double money); }
package com.itzhouq.spring.tx.demo1; /* * 轉帳的業務層的實現類 */ public class AccountServiceImpl implements AccountService { //注入DAO private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } /** * from:轉出帳戶 * to:轉入帳戶 * money:轉帳金額 */ @Override public void transfer(String from, String to, Double money) { accountDao.outMoney(from, money); int i = 1 / 0; accountDao.inMoney(to, money); } }
package com.itzhouq.spring.tx.demo1; /* * 轉帳的DAO的接口 */ public interface AccountDao { public void outMoney(String from, Double money); public void inMoney(String to, Double money); }
建立AccountDao實現類AccountDaoImpl
package com.itzhouq.spring.tx.demo1; import org.springframework.jdbc.core.support.JdbcDaoSupport; public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { @Override public void outMoney(String from, Double money) { this.getJdbcTemplate().update("update account set money=money-? where name=?", money,from); } @Override public void inMoney(String to, Double money) { this.getJdbcTemplate().update("update account set money=money+? where name=?", money,to); } }
配置Service和Dao:交給Spring管理
複製applicationContext.xml文件,新建配置文件tx.xml
<!-- 配置Service --> <bean id="accountService" class="com.itzhouq.spring.tx.demo1.AccountServiceImpl"> <property name="accountDao" ref="accountDao"></property> </bean> <!-- 配置Dao --> <bean id="accountDao" class="com.itzhouq.spring.tx.demo1.AccountDaoImpl"> </bean>
在Dao中編寫扣錢和加錢
配置鏈接池和JDBC的模板
<!-- 引入鏈接數據的屬性文件 --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置C3P0鏈接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 屬性注入 =============== --> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 配置Spring的JDBC模板 =================--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
在Dao中注入jdbc的模板
方法一:在Dao中直接注入
package com.itzhouq.spring.tx.demo1; import org.springframework.jdbc.core.JdbcTemplate; public class AccountDaoImpl implements AccountDao { private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public void outMoney(String from, Double money) { } @Override public void inMoney(String to, Double money) { } }
方法二:AccountDaoImpl繼承JdbcDaoSupport
JdbcDaoSupport類中提供了模板,也提供了set方法
package com.itzhouq.spring.tx.demo1; import org.springframework.jdbc.core.support.JdbcDaoSupport; public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao { @Override public void outMoney(String from, Double money) { } @Override public void inMoney(String to, Double money) { } }
因此直接在xml文件中的dao注入模板
<!-- 配置Dao --> <bean id="accountDao" class="com.itzhouq.spring.tx.demo1.AccountDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean>
方法三:繼承JdbcDaoSupport類以後直接注入鏈接池,這樣鏈接池能夠自動建立模板
不用配置模板,直接dao中注入鏈接池
<!--能夠省略的配置--> <!-- 配置Spring的JDBC模板 =================--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
<!-- 配置Dao --> <bean id="accountDao" class="com.itzhouq.spring.tx.demo1.AccountDaoImpl"> <property name="dataSource" ref="dataSource"/> </bean>
配置文件
<?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"> <!-- 配置Service --> <bean id="accountService" class="com.itzhouq.spring.tx.demo1.AccountServiceImpl"> <property name="accountDao" ref="accountDao"></property> </bean> <!-- 配置Dao --> <bean id="accountDao" class="com.itzhouq.spring.tx.demo1.AccountDaoImpl"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 引入鏈接數據的屬性文件 --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置C3P0鏈接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 屬性注入 =============== --> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 配置Spring的JDBC模板 =================--> <!-- <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> --> </beans>
package com.itzhouq.spring.tx.demo1; 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; /* * 測試轉帳 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:tx.xml") public class SpringDemo1 { @Resource(name="accountService") private AccountService accountService; @Test public void test1() { accountService.transfer("周杰倫", "鄧超", 1000d); } }
XML方式的聲明式的事務管理
引入jar包
配置事務管理器
<!-- 配置事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
配置加強
<!-- 配置事務的加強=============================== --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 事務管理的規則 --> <!-- <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="find*" read-only="true"/> --> <tx:method name="*" propagation="REQUIRED" read-only="false"/> </tx:attributes> </tx:advice>
AOP的配置
<!-- aop的配置 --> <aop:config> <aop:pointcut expression="execution(* com.itzhouq.spring.tx.demo1.AccountServiceImpl.*(..))" id="pointcut1"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/> </aop:config>
註解方式聲明事務
配置事務管理
<!-- 配置事務管理器=============================== --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
開啓註解事務
<!-- 開啓註解事務================================ --> <tx:annotation-driven transaction-manager="transactionManager"/>
在業務層添加註解
@Transactional public class AccountServiceImpl implements AccountService {