1、IOC 容器
1、概念
- IOC为Inversion of control,控制反转,意思是现在需要对象,自己不创建,交给外部的容器创建
- IOC容器= bean.xml配置 + ApplicationContext容器类
2、简单使用
-
引入jar
commons-logging-1.1.3.jar 【单独下载】 spring-beans-3.2.5.RELEASE.jar 【spring源码, bean节点管理】 spring-context-3.2.5.RELEASE.jar 【spring上下文类】 spring-core-3.2.5.RELEASE.jar 【IOC容器】 spring-expression-3.2.5.RELEASE.jar 【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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" 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"> </beans>
-
配置
<bean id="userAction " class="xxxx.UserAction "> </bean>
-
获取
// 容器对象(加载applicationContext.xml配置文件) ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); // 获取对象 UserAction userAction = (UserAction) ac.getBean("userAction"); userAction.execute();
3、配置细节
-
细节1
id 不能以数字开头,不能含有特殊符号, 不能有空格、逗号等, id 不能重复 name 可以以数字开头,可以有特殊符合,如果name值重复,编译没有问题但运行报错 <bean id="user" name="user2,user3 user4" class="xxxx.User"></bean> <bean name="user5" class="xxxx.User"></bean> <bean id="user6" class="xxxx.User"></bean> <bean id="user6" class="xxxx.User"></bean>
-
细节2
<!-- scope="singleton" 默认表示单例! prototype 多例 init-method="" 在创建完对象之后执行初始化方法 destroy-method="" 在调用容器类的destroy()方法时候,对单例的对象有效! lazy-init="true" 延迟初始化 / 这个属性的设置只对单例有影响,对多例没有任何影响! 单例的对象默认是在创建容器的时候就创建所有单例的对象,如果希望在第一次访问的时候创建单例的对象,就设置延迟初始化 Bean生命周期: bean在xml中配置, singleton 单例 1) 创建对象 如果有配置延迟初始化, lazy-init=true 如果单例的对象有配置延迟初始化, 在创建容器之后,在第一次从容器获取对象的时候 创建单例的对象! 如果没有配置或延迟初始化为默认值, 单例的对象会在创建容器的时候创建对象 2) 执行初始化方法 , init-method配置的方法会执行 3) 调用容器destroy() 方法时候,容器在销毁单例对象的实例的时候,会调用destroy-method对应的方法 此时bean对象会被销毁! prototype 多例 1) 每次在从容器获取对象的时候,都会创建新的对象 2) 每次创建完对象后,就执行初始化方法 3) java回回收不用资源(jvm gc) --> <bean id="user" class="xxxx.User" init-method="init" destroy-method="destroy_" lazy-init="false" scope="prototype"></bean>
4、创建对象的几种方式
-
构造赋值
<!-- 创建user对象,且赋值 --> <!-- value 当直接给属性值的时候使用value赋值 ref 当引用的是IOC容器中的对象的时候,使用ref --> <bean id="user" class="xxxx.User"> <constructor-arg index="0" type="int" value="10000"></constructor-arg> <constructor-arg index="1" type="String" ref="str"></constructor-arg> </bean>
-
set赋值
<!--IOC容器, 给对象属性赋值 --> <bean id="user" class="xxxx.User"> <property name="id" value="1000"></property> <property name="name" value="Jacky"></property> <!-- list集合赋值 --> <property name="list"> <list> <value>cn</value> <value>usa</value> </list> </property> <!-- map 集合赋值 --> <property name="map"> <map> <entry key="cn" value="China"></entry> <entry key="usa" value="1234"></entry> </map> </property> <!-- Properties对象赋值 --> <property name="prop"> <props> <prop key="cn">China</prop> <prop key="usa">America</prop> </props> </property> </bean>
-
工厂创建对象
<!-- class 指定工厂的类型; factory-method: 工厂类的静态方法 --> <bean id="user1" class="xxxx.UserFactory" factory-method="getStaticInstance"></bean> <!-- * 非静态方法创建对象 --> <!-- 先创建工厂实例 --> <bean id="factory" class="xxxx.UserFactory"></bean> <bean id="user" factory-bean="factory" factory-method="getInstance"></bean>
-
p名称空间
<bean id="str" class="java.lang.String"> <constructor-arg value="Jacky"></constructor-arg> </bean> <bean id="user" class="xxxx.User" p:id="1000" p:name-ref="str"></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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" 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" default-autowire="byType"> <!-- 配置: 需要创建的对象、对象依赖关系处理 --> <!-- 方式4:自动装配 (了解) --> <!-- a. default-autowire="byType" 配置到全局 当前所有的bean都采用”根据类型自动装配“ b. 配置到bean节点 autowire="byName" 根据名称自动装配, 会去容器找指定名称的对象,注入到set方法的参数中! autowire="byType" 根据类型自动装配, 要确保改类型对应的对象在IOC容器中唯一,否则报错! 总结: 简化配置,但是维护麻烦! --> <bean id="userDao" class="xxx.UserDao"></bean> <bean id="userService" class="xxx.UserService"></bean> <bean id="userAction" class="xxx.UserAction"></bean> </beans>
-
注解
<!-- 1. 开启注解扫描 --> <context:component-scan base-package="xxxx"></context:component-scan> // 把userDao对象加入IOC容器 //@Component("userdao") // <bean id=userDao class="..."> //@Repository("userdao") // <bean id=userDao class="..."> @Repository // 默认名称是类名,且第一个字母小写 public class UserDao implements IUserDao { // 模拟:保存对象 public void save() { System.out.println("UserDao.save()"); } } //@Component("userService") // 把当前类加入IOC容器 //@Service("userService") // 把当前类加入IOC容器 @Service public class UserService implements IUserService { //@Resource(name = "userDao") // 根据”userDao“去ioc容器找对象,找到后注入到当前方法参数 @Resource // 默认会根据private IUserDao userDao 这里的名称去容器找; 如果没有找到,再根据类型找,再没有找到就报错! private IUserDao userDao; public void save() { userDao.save(); } } //@Component("userAction") // 加入IOC容器 //@Controller("userAction") // 加入IOC容器 @Scope("prototype") // 指定加入ioc容器的对象为多例 @Controller public class UserAction { // @Resource(name = "userService") // ioc容器找名称是userService的对象并注入 @Resource private IUserService userService; public String execute(){ userService.save(); return "success"; } }
2、Spring与Struts2整合
1、关键
- 把action的创建,交给spring的ioc容器
2、引入jar
- struts2-spring-plugin-2.3.4.1.jar 【struts源码】
- spring-web-3.2.5.RELEASE.jar 【spring源码】
3、配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- struts2配置 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/bean*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
3、Aop编程
1、概念
- Aop编程:关注点代码与业务代码分离(jdk/cglib代理)
- 关注点:重复执行的代码, 也叫关注点代码
- 切面:关注点代码形成的类,就叫做切面
2、步骤
-
引入jar
aopalliance.jar 【spring-framework-2.5.6\lib\aopalliance】 aspectjrt.jar 【spring-framework-2.5.6\lib\aspectj】 aspectjweaver.jar 【spring-framework-2.5.6\lib\aspectj】 spring-aop-3.2.5.RELEASE.jar 【Spring3.2源码】
-
引入aop名称空间和开启aop注解
<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" 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"> <!-- 开启注解扫描 --> <context:component-scan base-package="xxxx"></context:component-scan> <!-- 开启aop注解 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
-
使用Aop相关注解
// 重复代码 @Component("aop") @Aspect // 指定一个类为切面类 public class TransactionAop { // 定义一个切入点表达式变量 (后面使用这个切入点表达式的时候,直接引用方法名即可) @Pointcut("execution(* xxxx.UserDao.*(..))") public void pointcut_(){ } //【前置通知】 // 在执行业务方法,之前执行 @Before("pointcut_()") public void beginTransaction() { System.out.println("[前置通知] 开启事务.."); } //【后置通知】 // 在执行业务方法,之后执行 @After("pointcut_()") public void commit() { System.out.println("[后置通知] 提交事务.."); } // 【返回后通知】 在执行目标方法结束后执行, 出现异常不会执行 @AfterReturning("pointcut_()") public void afterReturing(){ System.out.println("[返回后通知]"); } // 【异常通知】 在执行目标方法的时候出现异常执行 @AfterThrowing("pointcut_()") public void afterThrowing(){ System.out.println("[异常通知]"); } // 【环绕通知】 会环绕目标方法执行 @Around("pointcut_()") public void arroud(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("[环绕前:]"); pjp.proceed(); // 执行目标方法 System.out.println("[环绕后:]"); } }
-
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" 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"> <!-- dao实例加入容器 --> <bean id="userDao" class="xxxxx.UserDao"></bean> <!-- 实例化切面类 --> <bean id="aop" class="xxxx.TransactionAop"></bean> <!-- Aop相关配置 --> <aop:config> <!-- 切入点表达式定义 --> <aop:pointcut expression="execution(* xxxx.UserDao.*(..))" id="pt"/> <!-- 切面配置 --> <aop:aspect ref="aop"> <!-- 【环绕通知】 --> <aop:around method="arroud" pointcut-ref="pt"/> <!-- 【前置通知】 在目标方法之前执行 --> <aop:before method="beginTransaction" pointcut-ref="pt" /> <!-- 【后置通知】 --> <aop:after method="commit" pointcut-ref="pt"/> <!-- 【返回后通知】 --> <aop:after-returning method="afterReturing" pointcut-ref="pt"/> <!-- 异常通知 --> <aop:after-throwing method="afterThrowing" pointcut-ref="pt"/> </aop:aspect> </aop:config> </beans>
3、切入点表达式语法详解
-
切入点表达式:拦截指定的类,生成代理对象
-
表达式
execution( modifiers-pattern? 拦截的方法的访问修饰符 ret-type-pattern 方法返回类型,必须指定 declaring-type-pattern? 拦截的方法所在的类 name-pattern(param-pattern) 拦截的方法(以及方法的参数列表) throws-pattern?) 方法声明的异常 <!-- 切入点表达式定义 --> <!-- 1. 拦截指定的方法(通用) --> <!--<aop:pointcut expression="execution(* xxxx.UserDao.save(..))" id="pt"/>--> <!-- 2. 拦截指定的类下所有的方法 --> <!--<aop:pointcut expression="execution(* xxxx.UserDao.*(..))" id="pt"/>--> <!-- 3. 拦截指定包下所有的类的所有方法 --> <!--<aop:pointcut expression="execution(* xxxx.*.*(..))" id="pt"/>--> <!-- 3. 拦截指定包,以及其子包下所有类的所有方法 --> <!--<aop:pointcut expression="execution(* cn..*.*(..))" id="pt"/>--> <!-- 5. 拦截所有的public方法 --> <!--<aop:pointcut expression="execution(public * *(..))" id="pt"/>--> <!-- 6. 拦截所有的包含save方法 --> <!--<aop:pointcut expression="execution(* *save*(..))" id="pt"/>--> <!-- 7. 拦截UserDao.save()方法与OrderDao.save() --> <!--<aop:pointcut expression="execution(* cn..UserDao.save(..)) || execution(* cn..OrderDao.save(..))" id="pt"/>--> <!--<aop:pointcut expression="execution(* cn..UserDao.save(..)) or execution(* cn..OrderDao.save(..))" id="pt"/>--> <!-- 8. 不拦截UserDao.save()方法 --> <!--<aop:pointcut expression="!execution(* cn..UserDao.save(..))" id="pt"/>--> <!--<aop:pointcut expression=" not execution(* cn..UserDao.save(..))" id="pt"/>--> <!-- 9. 拦截UserDao.save()同时拦截OrderDao.save() --> <!-- 注意: 这种很少用,一般都是或者的关系即: || 、 or --> <!--<aop:pointcut expression="execution(* cn..UserDao.save(..)) and execution(* cn..OrderDao.save(..))" id="pt"/>--> <aop:pointcut expression="execution(* cn..UserDao.save(..)) && execution(* cn..OrderDao.save(..))" id="pt"/>
4、Spring对jdbc模块的支持
1、配置
-
db.properties
driverClass=com.mysql.jdbc.Driver jdbcUrl=jdbc:mysql:///hib_demo user=root password=root initialPoolSize=3 maxPoolSize=6 acquireIncrement=2
-
applicationContext
<?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" 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"> <!-- 加载Proerties配置文件 --> <context:property-placeholder location="classpath:xxxx/db.properties"/> <!-- 1. 实例化连接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${driverClass}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <property name="initialPoolSize" value="${initialPoolSize}"></property> <property name="maxPoolSize" value="${maxPoolSize}"></property> <property name="acquireIncrement" value="${acquireIncrement}"></property> </bean> <!-- 2. 创建JdbcTemplate对象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 实例化dao --> <bean id="deptDao" class="xxxx.DeptDao"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> </beans>
-
JdbcTemplate Api
public class DeptDao implements IDeptDao { // 接收容器注入的JdbcTemplate对象 private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } // 1. 原始jdbc代码 public void save(Dept dept) { jdbcTemplate.update("insert into t_dept(deptName) values(?)", dept.getName()); } @Override public void delete(Serializable id) { jdbcTemplate.update("delete from t_dept where id=?", id); } @Override public void update(Dept dept) { jdbcTemplate.update("update t_dept set deptName=? where id=?", dept.getName(),dept.getId()); } @Override public Dept findById(Serializable id) { // queryForList 把每一行都封装为map对象,再添加到list中 // List<Map<String, Object>> list = jdbcTemplate.queryForList("select * from t_dept"); // 传入类型参数,表示查询的列的类型; 这里只能查询一列 // List<String> list = jdbcTemplate.queryForList("select deptName from t_dept", String.class); List<Dept> list = jdbcTemplate.query("select * from t_dept where id=?", new MyRowMapper(), id); return (list!=null&&list.size()>0)?list.get(0):null; } @Override public List<Dept> getAll() { List<Dept> list = jdbcTemplate.query("select * from t_dept", new MyRowMapper()); return list; } // 封装Springjdbc查询的结果集 class MyRowMapper implements RowMapper<Dept>{ // 如何解析一行 @Override public Dept mapRow(ResultSet rs, int rowNum) throws SQLException { Dept dept = new Dept(); dept.setId(rs.getInt("id")); dept.setName(rs.getString("deptName")); return dept; } } }
5、Spring声明式事务管理
1、Jdbc(DataSourceTransactionManager)
-
引入jar
Spring 核心
Spring Aop 切面编程
Spring-jdbc / Spring-tx / 驱动包、连接池 -
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: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"> <!-- 1. 数据源配置 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql:///hib_demo"></property> <property name="user" value="root"></property> <property name="password" value="root"></property> <property name="initialPoolSize" value="3"></property> <property name="maxPoolSize" value="6"></property> </bean> <!-- 2. JdbcTemplate配置 , 注入数据源--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 3. dao实例,注入jdbcTemplate --> <bean id="deptDao" class="xxxx.DeptDao"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <!-- 4. Service实例,注入dao实例 --> <bean id="deptService" class="xxxx.DeptService"> <property name="deptDao" ref="deptDao"></property> </bean> <!-- 5. Spring声明式事务管理配置 --> <!-- 5.1 配置事务管理器类 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 5.2 事务通知配置, 拦截到指定的方法后如何管理事务 --> <!-- find* find开头的方法,是只读的事务 --> <!-- * 上面所有的方法都不满足时候,采用的事务控制规则 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="find*" read-only="true"/> <tx:method name="get*" read-only="true"/> <tx:method name="*" read-only="false"/> </tx:attributes> </tx:advice> <!-- 5.3 事务Aop配置 = 切入点表达式 + 应用上面的事务通知 --> <aop:config> <aop:pointcut expression="execution(* cn..*Service.*(..))" id="pt"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/> </aop:config> </beans>
-
注解方式
<?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: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"> <!-- 1. 数据源配置 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql:///hib_demo"></property> <property name="user" value="root"></property> <property name="password" value="root"></property> <property name="initialPoolSize" value="3"></property> <property name="maxPoolSize" value="6"></property> </bean> <!-- 2. JdbcTemplate配置 , 注入数据源--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 事务管理器类 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 开启注解扫描 --> <context:component-scan base-package="xxxx"></context:component-scan> <!-- spring声明式事务管理,注解开启 --> <tx:annotation-driven transaction-manager="txManager"/> </beans> @Repository // 当期类加入ioc容器 public class DeptDao implements IDeptDao { // 注入JdbcTemplate对象 @Resource private JdbcTemplate jdbcTemplate; public void save() { jdbcTemplate.update("insert into t_dept(deptName)values('test..')"); } } @Service public class LogService { @Resource private JdbcTemplate jdbcTemplate; // 事务控制 //@Transactional,写到方法上, 表示当前方法应用事务控制 写到类上, 表示当前类的所有方法都会应用事务 写到父类上, 当执行父类的这个方法时候才应用事务 @Transactional(propagation=Propagation.REQUIRES_NEW) public void insertLog() { jdbcTemplate.update("insert into t_log values('在插入部门....')"); } } @Service public class DeptService implements IDeptService { @Resource private IDeptDao deptDao; @Resource private LogService logService; // 当前方法应用事务 @Transactional( readOnly=false, // 读写的事务,当修改数据时候用;如果查询就设置为true isolation=Isolation.DEFAULT, // 事务隔离级别 timeout=-1, // 事务执行的超时时间, -1 表示不超时 //noRollbackFor=ArithmeticException.class, // 遇到指定的异常不回滚 propagation=Propagation.REQUIRED // 事务传播行为 //REQUIRES_NEW 当前执行方法必须在事务环境下运行,且当前执行方法始终开启一个新的事务 //REQUIRED 当前执行方法必须在事务环境下运行, 如果调用当前方式时候已经有一个事务环境,当前执行方法会加入当前事务环境,就不开启新的事务, 如果调用当前方法时候没有事务环境,就开启一个新的事务! //SUPPORTS 支持事务环境! 如果当前方法没有事务,也可以运行! //Never 当前方法不能再事务环境下运行! ) public void save() { // 插入日志 logService.insertLog(); int i = 1/0; // 插入部门 deptDao.save(); } }
2、 Hibernate(HibenateTransactionManager)
-
引入jar
hibernate jar
spring – core
spring – aop
spring – orm 对orm支持
spring-jdbc-3.2.5.RELEASE.jar
spring-orm-3.2.5.RELEASE.jar
spring-tx-3.2.5.RELEASE.jar -
Spring创建SessionFactory几种方式
<?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: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"> <!-- 连接池, 通过spring管理 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="jdbcUrl" value="jdbc:mysql:///hib_demo"></property> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="user" value="root"></property> <property name="password" value="root"></property> <property name="initialPoolSize" value="3"></property> <property name="maxPoolSize" value="6"></property> </bean> <!-- Spring 与 Hibenate整合 (Spring创建SessionFactory) --> <!-- 方式1: 直接加载hibernate.cfg.xml的方式,创建sessionFactory对象 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml"></property> </bean> --> <!-- 方式2: 连接池交给spring管理,其他配置还是写到hibernate.cfg.xml中 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:hibernate.cfg.xml"></property> </bean> --> <!-- 方式3:(推荐) 所有的配置都在spring中完成--> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!-- a. 注入连接池 --> <property name="dataSource" ref="dataSource"></property> <!-- b. hibernate常用配置: 方言、自动建表、显示sql --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> <!-- c. 加载所有的映射(根据路径加载) <property name="mappingLocations"> <list> <value>classpath:xxx/entity/*.hbm.xml</value> </list> </property> --> <!-- c. 根据目录加载所有的映射 --> <property name="mappingDirectoryLocations"> <list> <value>classpath:xxx/entity</value> </list> </property> </bean> <!-- 创建dao实例 --> <bean id="deptDao" class="xxx.DeptDao"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 创建service实例 --> <bean id="deptService" class="xxxx.service.DeptService"> <property name="deptDao" ref="deptDao"></property> </bean> <!-- Spring声明式事务管理配置 --> <!-- a. 事务管理器 --> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- b. 事务通知 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="*" read-only="false"/> </tx:attributes> </tx:advice> <!-- c. Aop配置 = 切入点表达式 + 应用通知规则 --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* cn..*Service.*(..))"/> </aop:config> </beans>
-
Spring对dao操作的支持
1、直接在dao中使用sessionFactory对象操作数据库
2、使用Spring提供的 HibernateTemplate 工具类操作数据库,优点: 对session的常用操作进行封装! 比较方便!
3、(推荐)HibernateDaoSupport工具类 ,Dao类直接继承HibernateDaoSupport工具类即可,HibernateDaoSupport对hibernateTemlate类进行了封装
网友评论