以下代码省略dao,service,action类的具体创建,主要是文件的相关配置
db.properties文件
driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:xe
name=hr
password=hr
没有加注解的.xml文件配置及解析见代码
<?xml version="1.0" encoding="UTF-8"?>
<!-- xmlns:context 配置信息参数化 -->
<beans 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"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
">
<!-- 一、加载db.properties配置文件,获得数据源 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- spring与mybatis整合,即spring要将Mybatis的相关组件纳入工厂中
1、DateSource:负责数据库的连接
2、SqlSessionFactory :核心组件,负责生产SqlSession的,但它依赖于DateSource
3、MapperScannerConfigurer:负责创建dao的实现类的对象,依赖于SqlSession
-->
<!-- 二、创建连接池,有三个:dbcp,c3p0,druid,三个选用其中一个就可以 -->
<!--第一个:dbcp-->
<bean id="dbcp_pool" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!-- 基本参数 -->
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${name}"></property>
<property name="password" value="${password}"></property>
<!-- 详细的其他参数 -->
<property name="maxActive" value="3"></property>
<property name="minIdle" value="1"></property>
<property name="initialSize" value="1"></property>
<property name="maxWait" value="3000"></property>
</bean>
<!--第二个:druid-->
<!-- 连接池:druid -->
<bean id="druid_pool" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本参数 -->
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"></property>
<property name="username" value="hr"></property>
<property name="password" value="hr"></property>
<!-- 详细参数 -->
<!-- 连接池的最大连接对象 数量 -->
<property name="maxActive" value="3"></property>
<!-- 最少要空闲 1 个连接对象 -->
<property name="minIdle" value="1"></property>
<!-- 初始化连接池 要创建1个连接对象 -->
<property name="initialSize" value="1"></property>
<!-- 当向连接池索要连接时,如果没有空闲连接,最大等待的时长:毫秒 -->
<property name="maxWait" value="3000"></property>
<!-- 驱逐线程运行间隔 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"></property>
<!-- 连接空闲超过100000ms 则成为一个可以被驱逐的对象 -->
<property name="minEvictableIdleTimeMillis" value="100000"></property>
<!-- 用于检测连接有效的 sql语句 (心跳) -->
<property name="validationQuery" value="select 1 from dual"></property>
<!-- 检测的时机 -->
<property name="testWhileIdle" value="true"></property>
<property name="testOnReturn" value="false"></property>
<property name="testOnBorrow" value="false"></property>
</bean>
<!-- 三、准备好连接池,创建一个工厂bean去创建一个复杂对象:准备sqlsessionfactorybean -->
<bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 在工厂里最重要的两件事就是 1数据源 、 2注册的mapper文件 -->
<property name="dataSource" ref="dbcp_pool"></property>
<property name="mapperLocations">
<!-- 注册多个mapper文件
classpath:类路径,生成的类信息放在src文件同级目录下的lib的文件夹中,所以相当于src文件夹的位置开始后的路径
-->
<list>
<value>classpath:com/qyy/dao/*Mapper.xml</value>
</list>
</property>
<!-- 为mapper文件中的实体定义缺省包路径 -->
<property name="typeAliasesPackage" value="com.qyy.entity"></property>
</bean>
<!-- 四、mapperScannerConfigurer:生产dao的实现类的对象,并纳入工厂管理
行为:
1.扫描所有的dao接口
2.根据提供的daoMapper文件信息和Sqlsession,构建dao的实现类
3.将对象纳入工厂处理,且id默认为:首字母小写的接口类名
-->
<bean id="mapperScannerConfigurer1" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 得到所有的接口,即其所在的包路径 ,多个包之间可以用逗号或分好分割-->
<property name="basePackage" value="com.qyy.dao"></property>
<!-- 获得sqlsessionfactory,即获得sqlsession和注册的mapper文件
但是当当前工厂中只有一个sqlSessionFactory,则可以省略不写
-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory1"></property>
</bean>
<!-- 创建service,并为sevice注入相应的dao -->
<bean id="userService" class="com.qyy.service.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
<bean id="auctionService" class="com.qyy.service.AuctionServiceImpl">
<property name="auctionDao" ref="auctionDao"></property>
</bean>
<bean id="recordService" class="com.qyy.service.RecordServiceImpl">
<property name="recordDao" ref="recordDao"></property>
</bean>
<!-- 利用spring进行sevice层的事务管理
在mybatis中dao层的事务提交默认auto_commit修改为false,在service层进行事务控制
在spring中,dao层的事务提交没有做修改,还是true,所以这点方便我们在dao层的测试
在service层进行事务管理
-->
<!-- 1、引入一个管理实务的半成品,虽然不是额外功能,但是持有连接,控制了事务管理的行为 -->
<bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 获得连接池,知道对那个数据库进行管理事务 -->
<property name="dataSource" ref="dbcp_pool"></property>
</bean>
<!-- 2、基于半成品,进一步对具体的service层具体的方法进行定制,生成最终的事务管理 器:Advice-->
<tx:advice id="txManager" transaction-manager="tx">
<tx:attributes>
<!-- 如果事务要切入此方法,可以单独为此方法定制事务属性(*代表剩余其他的方法)
有关查询的添加属性propagation="SUPPORTS" :
事务的传播性, 如果已经有事务,则融入这个事务;如果没事务,以非事务环境运行
有关增删改的操作增加属性rollback-for="Exception"
事务只要出现异常就进行回滚
-->
<tx:method name="find*" propagation="SUPPORTS"/>
<tx:method name="*" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<!-- 编织 -->
<aop:config>
<aop:pointcut expression="execution(* com.qyy.service.UserServiceImpl.*(..))" id="pc"/>
<!-- 组装切面 -->
<aop:advisor advice-ref="txManager" pointcut-ref="pc"/>
</aop:config>
<!-- 创建一个action对象 -->
<bean id="userAction" class="com.qyy.action.UserAction" scope="prototype">
<property name="userService" ref="userService"></property>
</bean>
</beans>
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">
<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>
<!-- struts和spring整合
1、矛盾点:spring工厂和StrutsPrepareAndExecuteFilter都会创建action实例对象
2、整合:action的创建应该由spring来完成,因为带有一系列的依赖关系
3、解决方法:监听项目的启动,当项目启动时触发行为:spring创建action的实例对象
启动工厂时,需要spring配置文件会到项目中查找一个名为contextConfigLocation的context-param
进而读取解析配置文件applicationContext.xml
-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
</web-app>
补充:事务控制的参数解析
1. isolation=隔离级别
default (默认值==采用数据的默认的设置)
read-uncommited 读未提交 (脏读,不可重复读)
read-commited 读提交 (不可重复读)
repeatable-read 可重复读 (幻影读)
serialized-read 序列化读
隔离级别由近到远,则并发性降低,安全性提高
oracle只支持了 读提交(默认) 和 序列化读
mysql都支持了 可重复读(默认)
*事务并发时的安全问题:
1>脏读:一个事务中 读到了其他事务中 未提交的数据
2>不可重复读:一个事务中 多次读取相同的数据行,但是,结果不一致
3>幻影读:一个事务中 多次读取同一张表,但是,数据行数不一致;
查询时没有某数据,但是操作时,却提示存在此数据。
2.propagation=传播性
support = 如果已经有事务,则融入这个事务;如果没事务,以非事务环境运行
required = 如果已经有事务,则融入这个事务;如果没事务,开启自己的事务 (默认值)
3.read-only:读写性
true:只读事务,事务中只出现查询行为
false:读写事务,事务中可以出现curd行为 (默认值)
4.rollback-for:回滚时刻
1>如果事务中抛出 运行时异常(RuntimeException),则自动回滚
2>如果事务中抛出 已检查异常(非运行时异常 Exception),不会自动回滚,而是默认提交事务
rollback-for="SQLException"
rollback-for="Exception"