Spring

Spring,第1张

官网:https://spring.io/

自学文档:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html
maven依赖

<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-webmvcartifactId>
    <version>5.3.19version>
dependency>

组成 七大模块

IOC
  • 理论推导
  1. UserDao接口
  2. UserDaoImpl实现
  3. UserService业务接口
  4. UserService业务实现
private UserDao userDao;

// 利用set进行动态实现值的注入!
public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
}
IOC创建对象方式

官方模板

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="..." class="...">  
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->

</beans>

<bean id="student" class="com.spring.pojo.Student">
	<property name="name" value="小杰student"/>
	<property name="teacher" ref="teacher"/>
bean>
<bean id="teacher" class="com.spring.pojo.Teacher">
	<property name="name" value="小杰teacher"/>
bean>

<bean id="student" class="com.spring.pojo.Student">
    <constructor-arg index="0" value="小杰student" />
    <constructor-arg index="1" ref="teacher"/>
bean>
<bean id="teacher" class="com.spring.pojo.Teacher">
    <property name="name" value="小杰teacher"/>
bean>

<bean id="student" class="com.spring.pojo.Student">
    <constructor-arg type="java.lang.String" value="小杰student"/>
    <constructor-arg type="com.spring.pojo.Teacher" ref="teacher"/>
bean>
<bean id="teacher" class="com.spring.pojo.Teacher">
    <property name="name" value="小杰teacher"/>
bean>

<bean id="student" class="com.spring.pojo.Student">
    <constructor-arg name="name" value="小杰student"/>
    <constructor-arg ref="teacher" name="teacher"/>
bean>
<bean id="teacher" class="com.spring.pojo.Teacher">
    <property name="name" value="小杰teacher"/>
bean>

IOC 小结好处:

  • bean单个存在,单例模式,不用担心内存泄漏问题。
  • 对象由Spring创建,管理,装配。
实例化一个容器
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = context.getBean("student", Student.class);
System.out.println(student);
DI 依赖注入
<bean id="address" class="com.spring.pojo.Address">
    <property name="address" value="中国"/>
bean>

<bean id="student" class="com.spring.pojo.Student">
    <property name="name" value="spring"/>
    <property name="address" ref="address"/>
    <property name="books">
        <array>
            <value>红楼梦value>
            <value>西游记value>
            <value>水浒传value>
            <value>三国演义value>
        array>
    property>
    <property name="hobbys">
        <list>
            <value>听歌value>
            <value>看电影value>
            <value>敲代码value>
        list>
    property>
    <property name="card">
        <map>
            <entry key="身份z" value="43092119998888888"/>
            <entry key="yhk" value="68544847855885555"/>
        map>
    property>
    <property name="games">
        <set>
            <value>LOLvalue>
            <value>COCvalue>
            <value>BOBvalue>
        set>
    property>
    <property name="wife">
        <null/>
    property>
    <property name="info">
        <props>
            <prop key="driver">com.mysql.cj.jdbc.Driverprop>
            <prop key="url">jdbc:mysql:///mydbprop>
            <prop key="username">rootprop>
            <prop key="password">rootprop>
        props>
    property>
bean>
拓展
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"


<bean id="user" class="com.spring.pojo.User" p:name="小蔡" p:age="99"/>

<bean id="user2" class="com.spring.pojo.User" c:name="小蔡2" c:age="992"/>
Bean别名

<alias name="fromName" alias="toName"/>

<bean id="user" class="com.spring.pojo.User" name="user2,user3"/>
import元素

<import resource="services.xml"/>
<import resource="resources/messageSource.xml"/>
<import resource="/resources/themeSource.xml"/>
自动装配Bean
<bean id="cat" class="com.spring.pojo.Cat"/>
<bean id="dog" class="com.spring.pojo.Dog"/>


<bean id="people" class="com.spring.pojo.People" autowire="byName">

    <property name="name" value="小杰"/>


bean>

小结:

  • byName,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法一致。
  • byType,需要保证所有的bean的class唯一,并且这个bean和自动注入的类型一致。
Bean 作用域
范围描述
singleton(默认)将单个 bean 定义限定为每个 Spring IoC 容器的单个对象实例。
prototype将单个 bean 定义限定为任意数量的对象实例。
request将单个 bean 定义限定为单个 HTTP 请求的生命周期。也就是说,每个 HTTP 请求都有自己的 bean 实例,该实例是在单个 bean 定义的后面创建的。仅在 Web 感知 Spring 的上下文中有效ApplicationContext。
session将单个 bean 定义限定为 HTTP 的生命周期Session。仅在 Web 感知 Spring 的上下文中有效ApplicationContext。
application将单个 bean 定义限定为ServletContext. 仅在 Web 感知 Spring 的上下文中有效ApplicationContext。
websocket将单个 bean 定义限定为WebSocket. 仅在 Web 感知 Spring 的上下文中有效ApplicationContext。
使用注解实现自动装配
  1. 导入约束 并配置注解的支持
xmlns:context="http://www.springframework.org/schema/context"

http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
  1. @Autowired
  • 一般直接在属性使用,底层通过类型反射注入
  • 使用@Autowired可以不用Set方法,前提属性在IOC容器
  • @Autowired默认根据Bean名装配 Bean名是JavaType首字母小写,如果容器找不到对应的Bean名,且JavaType没有重复,会使用类型注入,否则报错。
  • 报错
    • 找不到Bean
    • 有多个Bean同类型,只能选择一个
  1. 当给定注入点没有匹配的候选 bean 时,自动装配会失败。在声明的数组、集合或映射的情况下,至少需要一个匹配元素,也可以在参数前加@Nullable
@Autowired(required = false)
public void setMovieFinder(MovieFinder movieFinder) {
    this.movieFinder = movieFinder;
}

@Autowired
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
    this.movieFinder = movieFinder;
}
  1. 使用@Autowired 容器中多个类型相同时,可以指定Bean名自动装配
@Autowired
@Qualifier("cat1")
private Cat cat;
<bean id="cat" class="com.spring.pojo.Cat"/>
<bean id="cat1" class="com.spring.pojo.Cat"/>
<bean id="cat2" class="com.spring.pojo.Cat"/>

或者用@Resource (在框架中开发中,由jdk提供,一般不用)

@Resource(name = "cat1")
private Cat cat;
private String name;
使用注解开发
  1. @Conponent 这几个注解作用一样,当前类交给spring容器管理
  • controller【@Controller】
  • service【@Service】
  • dao【@Repository】
  1. @Value 给属性赋值
  2. @Scope("singleton ") 单例, prototype多例

小结

  • xml与注解:
    • xml更加万能,适用于任何场合,维护简单方便
    • 注解不是自己类使用不了,维护相对复杂
  • xml与注解最佳实践
    • xml用来管理bean
    • 注解只负责完成属性注入
    • 使用注解需开启注解支持

<context:annotation-config/>

<context:component-scan base-package="com.spring.pojo"/>
  1. @Configuration 表示这是一个配置类,相当于xml

  2. @ComponentScan(“”) 包扫描

  3. @Bean 相当于bean标签,方法名相当于id元素,方法的返回值相当于class元素

通过配置类 实例化一个容器

ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
User getUser = context.getBean("getUser", User.class);
System.out.println(getUser);
  1. @Import() 相当于xml配置文件的import元素 ,参数是JavaType的class对象
静态代理

好处:

  • 可以使真实角色的 *** 作更加纯粹,不用去关注一些公共的业务
  • 公共也就交给代理角色,实现了业务分工
  • 公共业务发生扩展的时候,方便集中管理、

缺点:

  • 一个真实角色就会产生一个代理角色;代码量会翻倍,开发效率会变低

接口

public interface UserService {
    void add();
    void delete();
    void update();
    void query();
}

实现

public class UserServiceImpl implements UserService{
    @Override
    public void add() {
        System.out.println("增加了一个用户");
    }

    @Override
    public void delete() {
        System.out.println("删除了一个用户");
    }

    @Override
    public void update() {
        System.out.println("更改了一个用户");
    }

    @Override
    public void query() {
        System.out.println("查询了一个用户");
    }
}

代理

public class UserServiceProxy implements UserService {

    private UserServiceImpl userService;

    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }

    @Override
    public void add() {
        log("add");
        userService.add();
    }

    @Override
    public void delete() {
        log("delete");
        userService.delete();
    }

    @Override
    public void update() {
        log("update");
        userService.update();
    }

    @Override
    public void query() {
        log("query");
        userService.query();
    }

    //日志方法
    public void log(String msg) {
        System.out.println("【Debug】"+msg+"方法");
    }
}

测试

public class Client {
    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();

        UserServiceProxy proxy = new UserServiceProxy();
        proxy.setUserService(userService);
        proxy.add();
        proxy.delete();
        proxy.update();
        proxy.query();
    }
}
动态代理
  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的,不是我们直接写好的
  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
    • 基于接口: jdk代理 【这里使用】
    • 基于类的:cglib
    • java字节码实现:JAVAssist

需要了解两个类:Proxy,InvocationHandler

接口

public interface UserService {
    void add();
    void delete();
    void update();
    void query();
}

实现

public class UserServiceImpl implements UserService {
    @Override
    public void add() {
        System.out.println("增加了一个用户");
    }

    @Override
    public void delete() {
        System.out.println("删除了一个用户");
    }

    @Override
    public void update() {
        System.out.println("更改了一个用户");
    }

    @Override
    public void query() {
        System.out.println("查询了一个用户");
    }
}

代理

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyInvocationHandler implements InvocationHandler {

    // 被代理的接口
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    // 生成得到代理类
    public Object getProxy() {
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                target.getClass().getInterfaces(), this);
    }

    @Override
    //处理代理实例 并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
        // 动态代理的本质 就是反射机制实现
        log(method.getName());
        Object result = method.invoke(target, args);
        return result;
    }

    public void log(String msg) {
        System.out.println("执行了" + msg + "方法");
    }
}

测试

public class Client {
    public static void main(String[] args) {
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        pih.setTarget(new UserServiceImpl());
        UserService proxy = (UserService) pih.getProxy();
        proxy.add();
    }
}

动态代理的好处:

  • 一个动态代理类 代理的是一个接口,一般就是对应的一类业务

  • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可

AOP

Maven依赖

<dependency>
    <groupId>org.aspectjgroupId>
    <artifactId>aspectjweaverartifactId>
    <version>1.9.4version>
dependency>
Aop在Spring中的作用

提供声明式事务,允许用户自定义切面

  • 横切关注点:跨越应用程序多个模块的方法或功能.既是,与我们业务逻辑无关,但是我们需要关注的部分,就是横切关注点.如日志,安全,缓存,事务等等…
  • 切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
  • 通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
  • 目标(Target):被通知对象。
  • 代理(Proxy):向目标对象应用通知之后创建的对象。
  • 切入点(PointCut):切面通知 执行的 “地点”的定义。
  • 连接点(JointPoint):与切入点匹配的执行点。

SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:

  • org.springframework.aop.MethodBeforeAdvice (前置通知:在方法前)
  • org.springframework.aop.AfterReturningAdvice (后置通知:在方法后)
  • org.aopalliance.intercept.MethodInterceptor (环绕通知:方法前后)
  • org.springframework.aop.ThrowsAdvice (异常抛出通知:方法抛出异常)
  • org.springframework.aop.IntroductionInterceptor (引介通知: 类中增加新的方法属性)
方式一:使用Spring的API接口

接口

public interface UserService {
    void add();

    void delete();

    void update();

    void select();
}

实现

public class UserServiceImpl implements UserService {
    public UserServiceImpl() {
    }

    public void add() {
        System.out.println("增加了一个用户");
    }

    public void delete() {
        System.out.println("删除了一个用户");
    }

    public void update() {
        System.out.println("修改了一个用户");
    }

    public void select() {
        System.out.println("查询了一个用户");
    }
}

前置通知

import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;

public class Log implements MethodBeforeAdvice {
    // method 要执行的目标对象的方法
    // args 参数
    // target 目标对象
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");
    }
}

后置通知

import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;

public class AfterLog implements AfterReturningAdvice {
    // returnValue 返回值
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("执行了"+method.getName()+"方法,返回结果为"+returnValue);
    }
}

配置文件applicationContext.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="userService" class="com.spring.service.UserServiceImpl"/>
    <bean id="afterLog" class="com.spring.log.AfterLog"/>
    <bean id="log" class="com.spring.log.Log"/>

    
    
    <aop:config>
        
        <aop:pointcut id="pointcut" expression="execution(* com.spring.service.UserServiceImpl.*(..))"/>
        
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    aop:config>

beans>

测试

public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    // 动态代理 代理的是接口
    UserService userService = (UserService) context.getBean("userService");
    userService.add();
}
方式二:自定义类来实现AOP

自定义类

public class DiyPointCut {

    public void before666() {
        System.out.println("方法执行前");
    }

    public void after888() {
        System.out.println("方法执行后");
    }
}

配置文件


<bean id="userService" class="com.spring.service.UserServiceImpl"/>
<bean id="diyPointCut" class="com.spring.diy.DiyPointCut"/>
<aop:config>
    
    <aop:aspect ref="diyPointCut">
        
        <aop:pointcut id="point" expression="execution(* com.spring.service.UserServiceImpl.*(..))"/>
        
        <aop:before method="before666" pointcut-ref="point"/>
        <aop:after method="after888" pointcut-ref="point"/>
    aop:aspect>
aop:config>
方式三:使用注解方式实现AOP

注解类

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class AnnotationPointCut {

    @Before("execution(* com.spring.service.UserServiceImpl.*(..))")
    public void before() {
        System.out.println("方法执行前");
    }

    @After("execution(* com.spring.service.UserServiceImpl.*(..))")
    public void after() {
        System.out.println("方法执行后");
    }

    // 在环绕增强中,我们可以给定一个参数,代表我们要处理切入点
    @Around("execution(* com.spring.service.UserServiceImpl.*(..))")
    public void around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("环绕前");
        jp.proceed(); // 执行方法
        System.out.println("环绕后");
    }
}

配置文件

<bean id="userService" class="com.spring.service.UserServiceImpl"/>

<bean id="annotationPointCut" class="com.spring.diy.AnnotationPointCut"/>

<aop:aspectj-autoproxy/>
Spring整合Mybatis

mybatis-spring自学文档:http://mybatis.org/spring/zh/factorybean.html

需要以下版本

MyBatis-SpringMyBatisSpring FrameworkSpring BatchJava
2.03.5+5.0+4.0+Java 8+
1.33.4+3.2.2+2.1+Java 6+

MyBatis-Spring 2.0 Maven依赖

    <dependencies>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>5.3.19version>
        dependency>
        
        <dependency>
            <groupId>org.aspectjgroupId>
            <artifactId>aspectjweaverartifactId>
            <version>1.9.4version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
            <version>5.3.19version>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>8.0.28version>
        dependency>
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
            <version>3.5.9version>
        dependency>
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatis-springartifactId>
            <version>2.0.7version>
        dependency>
        
    dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/javadirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
                <filtering>falsefiltering>
            resource>
            <resource>
                <directory>src/main/resourcesdirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
                <filtering>falsefiltering>
            resource>
        resources>
    build>
方式一

实体

package com.sm.pojo;

public class User {
    private int id;
    private String name;
    private String pwd;

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}

接口

package com.sm.mapper;

import com.sm.pojo.User;
import java.util.List;

public interface UserMapper {
    List<User> getUserList();
}

映射


DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sm.mapper.UserMapper">
    <select id="getUserList" resultType="com.sm.pojo.User">
        select * from user
    select>
mapper>
  1. spring整合Mybatis 新建配置文件spring-dao.xml

<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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/sm/mapper/UserMapper.xml"/>
    bean>

    
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    bean>

beans>
  1. mybatis-config.xml 都被Spring整合了 ,这里可以注释掉了,【别名,设置】建议留着

DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <package name="com.sm.pojo"/>
    typeAliases>

















configuration>
  1. 新建主配置文件applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <import resource="spring-dao.xml"/>
    
    <bean id="userMapper" class="com.sm.mapper.UserMapperImpl">
        <property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>
    bean>

beans>
  1. 整合后SqlSession工具类没有了,新增了 UserMapperImpl 实现类,set注入sqlSessionTemplate
import com.sm.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;

public class UserMapperImpl implements UserMapper{

    private SqlSessionTemplate sqlSessionTemplate;

    public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSessionTemplate = sqlSessionTemplate;
    }

    @Override
    public List<User> getUserList() {
        UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
        return mapper.getUserList();
    }
}
  1. 测试
import com.sm.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserMapperTest {
    @Test
    public void getUserList() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
        for (User user : userMapper.getUserList()) {
            System.out.println(user);
        }
    }
}
方式二

实现

public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
    @Override
    public List<User> getUserList() {
        return getSqlSession().getMapper(UserMapper.class).getUserList();
    }
}

实例

<bean id="userMapper2" class="com.sm.mapper.UserMapperImpl2">
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
bean>

测试

import com.sm.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserMapperTest {
    @Test
    public void getUserList() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapper = context.getBean("userMapper2", UserMapper.class);
        for (User user : userMapper.getUserList()) {
            System.out.println(user);
        }
    }
}
Spring事务
  • 声明式事务:AOP 【这里用】
  • 编程式事务:需要在代码中,进行事务的管理【一般不这么用】

事务ACID原则

  • 原子性
  • 一致性
  • 隔离性
    • 多个业务 *** 作同个资源,防止数据损坏
  • 持久性
    • 事务一旦提交,无论系统发生什么问题,结果都不会被影响,被持久化的写到存储器中

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
bean>


<tx:advice id="txAdvice" transaction-manager="transactionManager">
    
    
    <tx:attributes>
        <tx:method name="add" propagation="REQUIRED"/>
        <tx:method name="delete" propagation="REQUIRED"/>
        <tx:method name="update" propagation="REQUIRED"/>
        <tx:method name="getUserList" propagation="REQUIRED"/>
        
        <tx:method name="query" read-only="true"/>
        <tx:method name="*" propagation="REQUIRED"/>
    tx:attributes>
tx:advice>

<aop:config>
    <aop:pointcut id="txPointCut" expression="execution(* com.sm.mapper.*.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
aop:config>

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/721890.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存