菜鸟升级 ----spring学习第三天--------AOP注解开发-------spring的JDBC模板-------spring的事务管理

AOP注解开发方式:

1,创建目标类。

创建接入点,即可以拦截到的方法

2,配置XML

配置注解AOP开发
aop:aspectj-autoproxy/>
beans>
引入约束
配置目标类:
    bean id="userDao" class="">
    /bean>

/beans>

3,创建切面类

创建通知
在xml内配置切面类
bean id="myAspect" class="">
/bean>
在切面类前配置AOP注解:@Aspect
根据选择的通知类型在切点方法前配置AOP注解:
    前置通知:@Before(value="execution(*demo.userDemo.save(..))")
    后置通知:@AfterReturning(value="execution(*demo.userDemo.save(..))")
    异常通知:@AfterThrowing(value="execution(*demo.userDemo.save(..))",theowing="e"可以在方法内打印e.getMessage()输出异常类型)
    最终通知:@After(value="execution(*demo.userDemo.save(..))")
    最终通知:@Before(value="execution(*demo.userDemo.save(..))")
切入点ID配置:因为用注解方式配置切入点,没有ID这一项所以我们修改起来可能会很麻烦,
所以我们可以配置一个标准的切入点让其他的切入点调用:@Pointcut(value=execution(*demo.userDemo.save(..))") 然后再后面储创建一个方法。
然后在切入点配置注解的时候就可以:前置通知:@Before(value="切入点类.配置好的标准切入点的方法名字")

4,创建测试类

配置AOP整合JUnit的标准配置
在类前添加:@RunWith(SpringJUint4ClassRunner.class)
       @ContextConfiguration("classpath:applicationContext.xml")
创建测试方法
创建目标对象
在目标对象前添加AOP注解:@Resource(name="userDao")
在测试方法中用目标对象直接调用接入点

没有实现接口的目标,Aspextj会自动用Cglib来实现AOP
实现接口的目标,Aspextj会自动用JDK来实现AOP

Spring的JDBC模板

传统的JDBC模板调用需要

先创建连接池:DriverManagerDataSource dataSource=new DriverMangagerDataSource();
然后再设置驱动类:dataSource.setDriverClassName(“com.mysql.jdbc.Driver”);
接着设置URl:dataSource.setUrl(“jdbc:mysql:///数据库名”);
还要设置用户名和密码:dataSource.setUsername(“”); dataSource.setPassword(“”) ;
接着创建JDBC模板JdbcTemplate jdbcTemplate =new JdbcTemplate();
将连接池接入JDBC模板jdbcTemplate.setDataSource(“dateSource”)
最后调用调用sql:jdbcTemplate.update(“sql语句”,值,值,值。。)

经过spring整合后,将连接池的创建和jdbc模板的创建都交给IOC,在使用sql时就只用jdbcTemplate.update(“sql语句”,值,值,值。。)

在applicationContext.xml内配置

这个时固定的:bean id=”dateSource” class=”org.springframework.jdbc.datasource.DriverManagerDataSource”>
属性的配置:
property name=”driverClassName” value=”com.mysql.jdbc.Driver”/>
property name=”url” value=”jdbc:mysql:///数据库名”/>
property name=”username” value=”“/>
property name=”password” value=”“/>
/bean>

然后配置jdbc模板:

bean id="jdbcTemplate" class="org.springframework.jdbc.core.jdbcTemplate">
    peroperty name="dataSource" ref="dataSource"/>
/bean>

/beans>

在spring的xml中配置DBCP

在applicationContext.xml内配置

这个时固定的:bean id=”dateSource” class=”org.apache.commons.dbcp.BasicDataSource”>
属性的配置:
property name=”driverClassName” value=”com.mysql.jdbc.Driver”/>
property name=”url” value=”jdbc:mysql:///数据库名”/>
property name=”username” value=”“/>
property name=”password” value=”“/>
/bean>

然后配置jdbc模板:

bean id="jdbcTemplate" class="org.springframework.jdbc.core.jdbcTemplate">
    peroperty name="dataSource" ref="dataSource"/>
/bean>

/beans>

在spring的xml中配置C3P0

在applicationContext.xml内配置

这个时固定的:bean id=”dateSource” class=”com.machange.v2.c3p0.ComboPooledDataSource”>
属性的配置:
property name=”driverClassName” value=”com.mysql.jdbc.Driver”/>
property name=”jdbcUrl” value=”jdbc:mysql:///数据库名”/>
property name=”username” value=”“/>
property name=”password” value=”“/>
/bean>

然后配置jdbc模板:

bean id="jdbcTemplate" class="org.springframework.jdbc.core.jdbcTemplate">
    peroperty name="dataSource" ref="dataSource"/>
/bean>

/beans>

在一般工作中我们会使用properties属性文件来配置jdbc,这样修改起来不会太繁琐

配置jdbc.propweties文件:
driverClassName=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql:///数据库名
username=root
password=root
然后在xml中配置:context:property-placeholder location=”classpath:jdbc.properties”/>
bean id=”dateSource” class=”com.machange.v2.c3p0.ComboPooledDataSource”>
属性的配置:
property name=”driverClassName” value=” d r i v e r C l a s s N a m e / > p r o p e r t y n a m e = j d b c U r l v a l u e = {jdbcurl}”/>
property name=”username” value=” U s e r n a m e / > p r o p e r t y n a m e = p a s s w o r d v a l u e = {password}”/>

jdbc模板使用sql语句的规则

jdbc模板的增删改都是用jdbcTemplate.update(“sql语句”,值,值,值。。)
查询某个属性:String name=jdbcTemplate.queryForObject(“select name from student where id=?”,这个空是返回类型String.class,5)
统计个数:Long count=jdbcTemplate.queryForObject(“select count(*) from student”,这个空是返回类型Long.class);然后输出打印count
查询某个完整信息:
先创建一个类MyRowMapper实现接口RowMapper,然后创建一个方法返回值类型是Acount
class MyRowMapperImplements RowMapper{
public Account mapRow(ResultSet rs ,int RowNum) throws SQLException{
Account account=new Account();
account.setId(rs.getInt(“id”));
account.setname(rs.getString(“name”));
account.setsex(rs.getString(“sex”));
return account;
}}
}
}

Account account=jdbcTemplate.queryForObject(“select * from student where id=?”,这个空是返回类型new MyuRowMapper(),5);然后输出打印count

事务:

什么是事务

逻辑上的一组操作,组成这组操作的各个单元,全成功,获胜者全失败。

事务的特性:

原子性:事务不可分割
一致性:事务执行前后数据完整性保持一致
隔离性:一个事务的执行不应该受到其他事务的干扰
持久性:一旦事务结束,数据就将持久化到数据库。

如果不考虑隔离性引发安全问题

读问题

脏读:一个事务读到另一个事务未提交的数据
不可重复读:一个事务督导另一个事务已经提交的Upadta的数据,导致一个事务多次查询结果不一致
虚读:一个事务督导另一个事务已经提交的Insert的数据,导致一个事务多次查询结果不一致

写问题

丢失更新

解决读问题

设置事务的隔离级别
Read uncommitted:未提交读,任何问题都解决不了
Read commited :(常用)已提交读,解决脏读,但是不可重复读和虚读可能发生。
Repeatable rade :(常用)重复读,解决脏读和不重复度,但是虚读可能发生。
Seralizable :解决所有问题

事务管理的API

接口:Platform TransactionManager:平台事务管理器
实现类:DataSourceTransactionManager:底层是JDBC
实现类:HibernateTransactionManager:底层是Hibernate

TransactionDefiniton:事务定义信息

用于定义事务的相关信息,隔离级别,超时信息,传播行为,是否只读
TransactionStatus:事务状态
用于记录事务管理过程中,事务的状态的对象

事务管理的APi的关系

spring进行事务管理的时候,首先平台事务管理器根据事务定义信息进行事务的管理,在事务管理过程中产生各种状态,将这些状态信息记录到事务状态的对象中。

spring的事务的传播行为

通过TransactionDefinition定义传播行为

spring传播行为的用途:主要解决业特别复杂的逻辑行为问题

事务传播的三种类型

保证在同一个事务内:PROPAGATION_REQUIRED :默认值,如果A中有事务,使用A中的事务,否则就在A中创建一个事务,将所有操作包含进来,以保证多个操作都是在同一事务中
保证不在同一个事务内:PROPAGATION_REQUIRES :创建一个新的事务,只包含自身操作,如果A中有事务,就将他挂起(暂停)
嵌套式事务:PROPAGITION_NESTED :镶嵌事务,如果A中有事务,就先执行A,完毕后设置一个保存点,再执行B,最后结果没有异常就执行通过,有一场可以选择回滚到起点,或者到保存点。

在正真开发的时候dao层实现jdbc模板不需要setJdbcTemplate直接继承spring中的JdbcDaoSupport就可以省略在xml中配置jdbc模板,只配置bean id=”” class=”“>property name=”dataSource” ref=”dataSource”/>/bean>和链接池就可以了,在dao层的方法调用可以用this.jdbcTemplate().update();

编码式事务管理

1,在xml中配置平台事务管理器;bean id=”transactionManager” class=”org.springframwork.jdbc.datasource.DataSourceTransactionManager”>
property name=”transactionManager” ref=”ttransactionManager”/>
/bean>
2,在xml中配置事务管理器的模板:bean id=”transactionTemplate” class=”org.springframework.transactoin.support.TransactionTemplate”/>
property name=”transactionManager” ref=”transactionManager”/>
/bean>
3,在服务层创建private TransactionTemplate transactionManager;和transactionManager的set方法
4,在xml中配置该服务层类的bean中添加一个配置property name=”transactionTemplate” ref=”transactionTemplate”/>
5,在服务层的方法中调用事务管理的模板transactionTemplate.execute(new TransacttionCallbackWithoutResult(){
protected void doInTransactionWithOutReasult(TransactionStatus transactionStatus){
将事务管理的代码放在这里就可以了
}
}
6,需要注意的是服务层要用事务管理的方法传入的参数需要时用final修饰的

spring的声明式事务管理(重点常用的)

1,在xml中配置平台事务管理器;bean id=”transactionManager” class=”org.springframwork.jdbc.datasource.DataSourceTransactionManager”>
property name=”transactionManager” ref=”ttransactionManager”/>
/bean>
2,配置事务的增强:tx:advice transcation-maager=”transacationManager”>
tx:attributes>
tx:method name=”方法事务” propagation”=”REQUIRED” isolation=”DEFAULT”/>
/tx:attributes>
/tx:advice>
3,aop配置
aop:config>
aop:pointCut expression=”execution(...(..))” id=”aa”/>
aop:advisor advice-ref=”事务器的id” pointcut-ref=”aa”/>
/aop:config/>

猜你喜欢

转载自blog.csdn.net/qq_42799000/article/details/81348434