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=”
{jdbcurl}”/>
property name=”username” value=”
{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/>