Spring(三)

Spring(三)

十四、Spring + MyBatis【重点】


14.1 配置数据源

将数据源配置到项目中

       <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>
14.1.1 引入jdbc.properties配置文件
#jdbc.properties
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncpding=UTF-8
username=root
password=123456
14.1.2 整合Spring配置文件和properties配置文件
<!--spring-context.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       ">

    <!--配置文件参数化(参数占位符)-->
	<context:property-placeholder location="classpath:jdbc.properties" />
    
    <!--与PooledDataSource集成(二选一)-->
    <bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
        <property name="driver" value="${driverClass}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
    </bean>

    <!--与DruidDataSource集成(二选一)-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!--基本配置-->
        <property name="driverClassName" value="${driverClass}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
    </bean>
</bean>
14.1.3 Druid连接池可选参数
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    <!--基本配置-->
    <property name="driverClassName" value="${driverClass}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>

    <!-- 配置初始化大小、最小、最大 -->
    <property name="initialSize" value="${init}"/>
    <property name="minIdle" value="${minIdle}"/>
    <property name="maxActive" value="${maxActive}"/>

    <!-- 配置获取连接等待超时的时间 -->
    <property name="maxWait" value="60000"/>

    <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
    <property name="timeBetweenEvictionRunsMillis" value="60000"/>

    <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
    <property name="minEvictableIdleTimeMillis" value="300000"/>
</bean>
14.1.4 Druid监控中心
<!--web.xml-->
<servlet>
    <servlet-name>DruidStatView</servlet-name>
    <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>DruidStatView</servlet-name>
    <url-pattern>/druid/*</url-pattern>
</servlet-mapping>
14.1.5 测试监控中心
配置tomcat,并访问protocol://ip:port/project/druid/index.html

14.2 整合MyBatis

将 SqlSessionFactory、DAO、Service 配置到项目中

14.2.1 导入依赖
<!-- spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.6.RELEASE</version>
</dependency>

<!-- spring+mybatis集成依赖 -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.1</version>
</dependency>
14.2.2 配置SqlSessionFactory
<!-- 工厂bean:生成SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 注入连接池 -->
    <property name="dataSource" ref="dataSource"></property>
    <!-- 注入dao-mapper文件信息 ,如果映射文件和dao接口 同包且同名,则此配置可省略-->
    <property name="mapperLocations">
        <list>
            <value>classpath:com/qf/spring/dao/*.xml</value>
        </list>
    </property>
    <!-- 为 dao-mapper文件中的实体 定义缺省包路径 
		如:<select id="queryAll" resultType="User"> 中 User类可以不定义包
    -->
    <property name="typeAliasesPackage" value="com.qf.entity"></property>
</bean>
14.2.3 配置MapperScannerConfigurer

管理DAO实现类的创建,并创建DAO对象,存入工厂管理

	  1.扫描所有DAO接口,去构建DAO实现

	  2.将DAO实现存入工厂管理 

     3.DAO实现对象在工厂中的id是:“首字母小写的-接口的类名”,   例如:UserDAO==>userDAO , OrderDAO==>orderDAO

<!-- mapperScannerConfigurer -->
<bean id="mapperScannerConfigurer9" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
   	<!-- dao接口所在的包  如果有多个包,可以用逗号或分号分隔 
  		<property name="basePackage" value="com.a.dao,com.b.dao"></property>
   	-->
    <property name="basePackage" value="com.qf.spring.dao"></property>
    <!-- 如果工厂中只有一个SqlSessionFactory的bean,此配置可省略 -->
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
14.2.4 配置Service
<bean id="userService" class="com.qf.spring.service.UserServiceImpl">
    <!-- 注意ref中的值是对应DAO接口的首字母小写的接口名 -->
	<property name="userDAO" ref="userDAO"></property>
</bean>

十五、事务【重点】


15.1 配置DataSourceTransactionManager

事务管理器,其中持有DataSource,可以控制事务功能(commit,rollback等)。

<!-- 1. 引入一个事务管理器,其中依赖DataSource,借以获得连接,进而控制事务逻辑 -->
<bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>

注意:DataSourceTransactionManager 和 SqlSessionFactoryBean 要注入同一个DataSource的Bean,否则事务控制失败!!!

15.2 配置事务通知

基于事务管理器,进一步定制,生成一个额外功能:Advice。

此Advice可以切入任何需要事务的方法,通过事务管理器为方法控制事务。

<tx:advice id="txManager" transaction-manager="tx">
	<tx:attributes>
        <!--<tx:method name="insertUser" rollback-for="Exception" isolation="DEFAULT"    
              	propagation="REQUIRED" read-only="false"/>-->
        <!-- 以User结尾的方法,切入此方法时,采用对应事务实行-->
        <tx:method name="*User" rollback-for="Exception"/>
        <!-- 以query开头的方法,切入此方法时,采用对应事务实行 -->
        <tx:method name="query*" propagation="SUPPORTS"/>
        <!-- 剩余所有方法 -->
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

15.3 事务属性

15.3.1 隔离级别

isolation 隔离级别

default            (默认值)(采用数据库的默认的设置) (建议)
read-uncommited    读未提交
read-commited      读提交 (Oracle数据库默认的隔离级别)
repeatable-read    可重复读	(MySQL数据库默认的隔离级别)
serialized-read    序列化读

隔离级别由低到高为:read-uncommited < read-commited < repeatable-read < serialized-read

安全性:级别越高,多事务并发时,越安全。因为共享的数据越来越少,事务间彼此干扰减少。

并发性:级别越高,多事务并发时,并发越差。因为共享的数据越来越少,事务间阻塞情况增多。

事务并发时的安全问题:

1). 脏读:一个事务读取到另一个事务还未提交的数据。
    大于等于 read-commited 可防止
2). 不可重复读:一个事务内多次读取一行数据的相同内容,其结果不一致。
    大于等于 repeatable-read 可防止
3). 幻影读:一个事务内多次读取一张表中的相同内容,其结果不一致。
    serialized-read 可防止
15.3.2 传播行为

propagation传播行为

当涉及到事务嵌套(Service调用Service)中,可能会存在问题。
1). SUPPORTS =	如果有事务在运行,当前的方法就在这个事务内运行,否则可以不运行在事务中

2). REQUIRED = 如果有事务在运行,当前的方法就在这个事务内运行,否则就开启一个新的事务,默认传播行为.
15.3.3 读写性

readonly 读写性

1). true:只读,可提高查询效率。(适合查询)

2). false:可读可写。 (默认值)(适合增删改)
15.3.4 事务超时

timeout事务超时时间

当前事务所需操作的数据被其他事务占用,则等待。
1). 100:自定义等待时间100(秒)。
2). -1:由数据库指定等待时间,默认值。(建议)
15.3.5 事务回滚

rollback-for 回滚属性

默认情况下,spring在遇到运行时异常和Error,Spring事务会进行回滚,而遇到非运行时异常Exception则不会回滚。可以通过rollbackFor指定需要回滚的受检查异常,指定异常之后,被指定的异常和该异常的子类都会得到回滚,并且运行时异常和Error异常仍然会得到回滚

1) 如果事务中抛出 RuntimeException,则自动回滚

2) 如果事务中抛出 CheckException(非运行时异常 Exception),不会自动回滚,而是默认提交事务

3) 处理方案 : 将CheckException转换成RuntimException上抛,或 设置 rollback-for="exception"

15.4 编织

将事务管理的Advice 切入需要事务的业务方法中

<aop:config>
	<aop:pointcut expression="execution(* com.qf.spring.service.UserServiceImpl.*(..))" id="pc"/>
    <!-- 组织切面 -->
    <aop:advisor advice-ref="txManager" pointcut-ref="pc"/>
</aop:config>

十六、注解开发

16.1 声明bean

用于替换自建类型组件的 <bean…>标签;可以更快速的声明bean

@Service 业务类专用

@Repository dao实现类专用

@Controller web层专用

@Component 通用

@Scope 用户控制bean的创建模式

// @Service说明 此类是一个业务类,需要将此类纳入工厂  等价替换掉 <bean class="xxx.UserServiceImpl">
// @Service默认beanId == 首字母小写的类名"userServiceImpl"
// @Service("userService") 自定义beanId为"userService"
@Service //声明bean,且id="userServiceImpl"
@Scope("singleton") //声明创建模式,默认为单例模式 ;@Scope("prototype")即可设置为多例模式
public class UserServiceImpl implements UserService {
 	...   
}

16.2 注入(DI)

用于完成bean中属性值的注入

@Autowired 基于类型自动注入

@Resource 基于名称自动注入

@Qualifier(“userDAO”) 限定要自动注入的bean的id,一般和@Autowired联用

@Value 注入简单类型数据 (jdk8种+String)

@Service
public class UserServiceImpl implements UserService {
    
    @Autowired //注入类型为UserDAO的bean
    @Qualifier("userDAO2") //如果有多个类型为UserDAO的bean,可以用此注解从中挑选一个
    private UserDAO userDAO;
}

@Service
public class UserServiceImpl implements UserService {
    
	@Resource("userDAO3") //注入id=“userDAO3”的bean
    private UserDAO userDAO;
    /*
    @Resource //注入id=“userDAO”的bean
    private UserDAO userDAO;
    */
}

public class XX{
    @Value("100") //注入数字
    private Integer id;
    @Value("shine") //注入String
	private String name;
}

16.3 事务控制

用于控制事务切入

@Transactional

工厂配置中的 <tx:advice… 和 <aop:config… 可以省略 !!

//类中的每个方法都切入事务(有自己的事务控制的方法除外)
@Transactional(isolation=Isolation.READ_COMMITTED,propagation=Propagation.REQUIRED,readOnly=false,rollbackFor=Exception.class,timeout = -1)
public class UserServiceImpl implements UserService {
	...
    //该方法自己的事务控制,仅对此方法有效
	@Transactional(propagation=Propagation.SUPPORTS)
	public List<User> queryAll() {
		return userDao.queryAll();
	}
	public void save(User user){
		userDao.save(user);
	}
}

16.4 注解所需配置

<!-- 告知spring,哪些包中 有被注解的类、方法、属性 -->
<!-- <context:component-scan base-package="com.qf.a,com.xx.b"></context:component-scan> -->
<context:component-scan base-package="com.qf"></context:component-scan>
	
<!-- 告知spring,@Transactional在定制事务时,基于txManager=DataSourceTransactionManager -->
<tx:annotation-driven transaction-manager="txManager"/>

16.5 AOP开发

16.5.1 注解使用
@Aspect // 声明此类是一个切面类:会包含切入点(pointcut)和通知(advice)
@Component //声明组件,进入工厂
public class MyAspect {
    // 定义切入点
    @Pointcut("execution(* com.qf.spring.service.UserServiceImpl.*(..))")
    public void pc(){}
    
    @Before("pc()") // 前置通知
    public void mybefore(JoinPoint a) {
        System.out.println("target:"+a.getTarget());
        System.out.println("args:"+a.getArgs());
        System.out.println("method's name:"+a.getSignature().getName());
        System.out.println("before~~~~");
    }

    @AfterReturning(value="pc()",returning="ret") // 后置通知
    public void myAfterReturning(JoinPoint a,Object ret){
        System.out.println("after~~~~:"+ret9);
    }
    
    @Around("pc()") // 环绕通知
    public Object myInterceptor(ProceedingJoinPoint p) throws Throwable {
        System.out.println("interceptor1~~~~");
        Object ret = p.proceed();
        System.out.println("interceptor2~~~~");
        return ret;
    }
    
    @AfterThrowing(value="pc()",throwing="ex") // 异常通知
    public void myThrows(JoinPoint jp,Exception ex){
        System.out.println("throws");
        System.out.println("===="+ex.getMessage());
    }
}
16.5.2 配置
<!-- 添加如下配置,启用aop注解 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

十七、集成JUnit

17.1 导入依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.3.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

17.2 编码

可以免去工厂的创建过程;

可以直接将要测试的组件注入到测试类。

@RunWith(SpringJUnit4ClassRunner.class) //由SpringJUnit4ClassRunner启动测试
@ContextConfiguration("classpath:applicationContext.xml") //spring的配置文件位置
public class SpringTest{//当前测试类也会被纳入工厂中,所以其中属性可以注入

    @Autowired // 注入要测试的组件
    @Qualifier("userDAO")
    private UserDAO userDAO;

    @Test
    public void test(){
        // 测试使用userDAO
        userDAO.queryUser();
        ....
    }
}

十八、Spring整合Web【重点】

1.在web.xlm中设置监听器

在这里插入图片描述

2.在WEb环境中获取SPring容器

  @Override
    public void init() throws ServletException {

        // 1.在Web环境下获取Spring容器
        WebApplicationContext ctx = WebApplicationContextUtils
                .getWebApplicationContext(getServletContext());

        // 2.从Spring容器里面根据类型获取userService
        userService = ctx.getBean(IUserService.class);
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值