4.2-Spring

1.Spring

1.1

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.9</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.3.9</version>
</dependency>

1.2 优点

  • 开源,免费的框架(容器)
  • 轻量级,非入侵式的框架
  • 控制反转(IOC),面向切面编程(AOP)
  • 支持事务处理,对框架整合的支持

1.3 组成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o2STjfPc-1629202612442)(C:\Users\ma\MyWorkplace\code\LongWayOfJava\5.1-Spring.assets\tmp.jpg)]

1.4

  • spring boot
    • 一个快速开发的脚手架
    • 基于spring boot 可以快速开发单个微服务
    • 约定大于配置
  • spring cloud
    • 基于 spring boot 实现

学习spring boot 前提 : spring, springMVC

2.IOC理论

IOC是Inversion of Control的缩写 ,控制反转

传统业务开发:

  1. dao 接口类
  2. daoImpl 实现类
  3. service 接口类
  4. serviceImpl 实现类

user --> service --> dao

程序主动创建对象,控制权在开发人员手中

//serviceImpl 传统

class ServiceImpl {
   private Dao dao = new DaoImpl();
}
//dao实现类写死了

使用set注入,程序不在具有主动性,而是变成被动接受对象

//set注入 变革
class ServiceImpl{
    private Dao dao;
     
    public void setDao(Dao dao){
        this.dao = dao;
    }
}
//用户可以传入不同的DaoImpl

3.hellospring

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--使用 Spring 来创建对象 在Spring中称为 Bean

        id: 变量名
        class: new的对象
        property: 给对象属性设置值
    -->
    <bean id="hello" class="cqu.ma.pojo.Hello">
        <property name="str" value="Spring"></property>
    </bean>
</beans>
import cqu.ma.pojo.Hello;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    @Test
    public void test(){
        //获取spring 上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Hello hello = (Hello) context.getBean("hello");
        System.out.println(hello.toString());
    }
}

4.IOC创建对象的方式

  • 无参构造(set方法赋值)
  • 有参构造
    • 下标
    • 类型(不建议使用)
    • 参数名
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--使用 Spring 来创建对象 在Spring中称为 Bean

        id: 变量名
        class: new的对象
        property: 给对象属性设置值
    -->
    <bean id="user" class="cqu.ma.pojo.User">
        <!--无参构造-->
        <!--<property name="name" value="模糊"></property>-->

        <!--有参构造 下标赋值-->
        <!--<constructor-arg index="0" value="马"></constructor-arg>-->

        <!--有参构造 通过类型 (不建议使用)-->
        <!--<constructor-arg type="java.lang.String" value="漫画"></constructor-arg>-->

        <!--有参构造 通过参数名-->
        <constructor-arg name="name" value="冒号"></constructor-arg>
    </bean>
</beans>

5.spring配置文件

5.1 别名

<alias name="user" alias="user2"></alias>

5.2 Bean配置

<!--bean标签的name属性为bean设置别名,可以通过各种分隔符设置多个-->
<bean id="user" class="cqu.ma.pojo.User" name="user2,u2,u3">
	<property name="name" value="user01"></property>
</bean>

5.3 import

一般用于团队开发,可以将多个配置文件,导入合并为一个

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

    <import resource="beans.xml"></import>
    <import resource="beans2.xml"></import>
</beans>

id相同的bean会被之后的覆盖(别名合并)

6.依赖注入 DI

6.1 构造器注入

6.2 set注入

  • 依赖注入
    • 依赖:bean对象的创建依赖于容器
    • 注入: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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="address" class="cqu.ma.pojo.Address">
        <property name="address" value="wwww.w"></property>
    </bean>
    <bean id="student" class="cqu.ma.pojo.Student">
        <!--1.普通值注入-->
        <property name="name" value=""></property>
        <!--2.bean注入 ref-->
        <property name="address" ref="address"></property>
        <!--数组注入-->
        <property name="books">
            <array>
                <value>红楼梦</value>
                <value>西游记</value>
                <value>三国</value>
            </array>
        </property>
        <!--list-->
        <property name="hobbies">
            <list>
                <value>听歌</value>
                <value>movie</value>
                <value>coding</value>
            </list>
        </property>
        <!--map-->
        <property name="card">
            <map>
                <entry key="id" value="11112233"></entry>
                <entry key="bank" value="4455"></entry>
            </map>
        </property>
        <!--set-->
        <property name="games">
            <set>
                <value>LOL</value>
                <value>COC</value>
            </set>
        </property>
        <!--null-->
        <property name="wife">
            <null></null>
        </property>
        <!--properties-->
        <property name="info">
            <props>
                <prop key="学号">2290</prop>
                <prop key="性别"></prop>
            </props>
        </property>
    </bean>
</beans>

6.3 其他方式

使用 p命名空间 或 c命名空间注入

xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"

<?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:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--p命名空间注入,可以直接注入属性值-->
    <bean id="user" class="cqu.ma.pojo.User" p:name="" p:age="18"></bean>

    <!--c命名空间注入,通过构造器注入 construct-args-->
    <bean id="user2" class="cqu.ma.pojo.User" c:name="艾2" c:age="19"></bean>
</beans>

6.4 bean作用域 (scope)

  • singleton 单例 (默认)
  • prototype 原型 (每次从容器get都产生一个新的对象)
  • request
  • session
  • application
  • websocket
<bean id="user2" class="cqu.ma.pojo.User" c:name="艾2" c:age="19" scope="prototype"></bean>

7.bean的自动装配

  • 自动装配是Spring满足bean依赖一种方式
  • Spring会在上下文中自动寻找并自动给bean装配属性

三种装配方式

  1. 在xml中显示配置
  2. 在java中显示配置
  3. 隐式的自动装配

autowire

byName

    <bean id="cat" class="cqu.ma.Cat"></bean>
    <bean id="dog" class="cqu.ma.Dog"></bean>
    <bean id="people" class="cqu.ma.People" autowire="byName">
        <property name="name" value=""></property>
<!--        <property name="cat" ref="cat"></property>-->
<!--        <property name="dog" ref="dog"></property>-->
    </bean>

byType

    <bean id="cat" class="cqu.ma.Cat"></bean>
    <bean id="dog" class="cqu.ma.Dog"></bean>
    <bean id="people" class="cqu.ma.People" autowire="byType">
        <property name="name" value=""></property>
<!--        <property name="cat" ref="cat"></property>-->
<!--        <property name="dog" ref="dog"></property>-->
    </bean>

注解自动装配

  1. 导入约束
    context

    <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
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">
    
  2. 配置注解的支持
    <context:annotation-config></context:annotation-config>

    <?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"
           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:annotation-config></context:annotation-config>
    
        <bean id="cat" class="cqu.ma.Cat"></bean>
        <bean id="dog" class="cqu.ma.Dog"></bean>
        <bean id="people" class="cqu.ma.People">
            <!--<property name="name" value="艾"></property>
            <property name="cat" ref="cat"></property>
            <property name="dog" ref="dog"></property>-->
        </bean>
    </beans>
    
  3. 代码中用注解
    @Autowired

    	@Autowired
        private Dog dog;
        @Autowired
        private Cat cat;
    

    直接在属性上使用,也可以在set方法上使用

    使用@Authowired可以不用编写set方法,前提是自动装配的属性在 IOC (Spring)

    容器中存在在使用@Autowired时,首先在容器中查询对应类型的bean

    如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据

    如果查询的结果不止一个,那么@Autowired会根据名称来查找。

    如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false

    @Qualifier 可以指定名字

     	@Autowired
        @Qualifier("cat")
        private Cat cat;
    

    @Resource

    	@Resource(name="cat")
    	private Cat cat
    

8.使用注解开发

spring4之后使用注解开发需要导入aop

//会依赖导入
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.9</version>
</dependency>

需要导入context约束,增加注解的支持

<?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"
       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:component-scan base-package="cqu.ma.pojo"></context:component-scan>
    <context:annotation-config></context:annotation-config>

</beans>
  1. bean
    @Component

    // @Component 类似 <bean id="user" class="cqu.ma.pojo.User"></bean>
    @Component
    public class User {
    
  2. 属性注入
    @Value

     	@Value("模糊") //设置属性值
        private String name;
    
  3. 衍生的注解
    @Component 衍生的注解 (功能一样),在web开发中,按照mvc三层架构:

    • dao @Repository
    • service @Service
    • controller @Controller
  4. 自动装配
    @Autowired
    @Qualifier(value=)
    @Nullable
    @Resource(name=)

  5. 作用域
    @Scope() singleton , prototype

xml 与 注解

  • xml更万能,使用任何场景,维护简单方便
  • 注解维护复杂

9.使用Java的方式配置Spring

配置类

@Configuration //标志该类是spring配置类
@ComponentScan("cqu.ma") //扫描
@Import(MyConfig2.class) //合并其他配置
public class MyConfig {

    @Bean // <bean id="getUser" class=cqu.ma.pojo.User/>
    public User getUser(){
        return new User();
    }
}

实体类

package cqu.ma.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class User {
    @Value("模糊")
    private String name;

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

    public String getName() {
        return name;
    }

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

测试

import cqu.ma.config.MyConfig;
import cqu.ma.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MyTest {
    @Test
    public void test(){
        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);

        User user =  context.getBean("getUser",User.class);

        System.out.println(user);
    }
}

10.代理模式

Spring AOP底层

  • 静态代理
  • 动态代理

静态代理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hz2NZCSy-1629202612443)(C:\Users\ma\MyWorkplace\code\LongWayOfJava\5.1-Spring.assets\proxy_static.PNG)]

  • 代理类与目标类实现同一接口
  • 代理类组合目标类

动态代理

  • 基于接口:JDK动态代理
  • 基于类:cglib
  • java字节码实现:javassist

需要了解两个类 Proxy InvocationHandler

package cqu.ma.demo1;

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

public class ProxyHandler implements InvocationHandler {

    private Object target;

    public ProxyHandler(Object target){
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before");
        Object o = method.invoke(target,args);
        System.out.println("after");

        return o;
    }
}
    @org.junit.Test
    public void test2(){
        //目标对象
        Image reader = new ImageReader("b");

        //handler
        InvocationHandler handler = new ProxyHandler(reader);

        //获取代理
        Image proxy = (Image) Proxy.newProxyInstance(Image.class.getClassLoader(),ImageReader.class.getInterfaces(),handler);

        proxy.show();
    }

    @org.junit.Test
    public void test2(){
        //目标对象
        Image reader = new ImageReader("b");

        //handler
        InvocationHandler handler = new ProxyHandler(reader);

        //获取代理
        Image proxy = (Image) Proxy.newProxyInstance(Image.class.getClassLoader(),ImageReader.class.getInterfaces(),handler);

        //proxy.show();

        //把proxy当作目标对象,代理
        Image proxyProxy = (Image) Proxy.newProxyInstance(Image.class.getClassLoader(), proxy.getClass().getInterfaces(), new InvocationHandler() {
            private Object target = proxy;
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("[debug]日志开始");
                Object obj = method.invoke(target,args);
                System.out.println("[debug]日志结束");
                return obj;
            }
        });

        proxyProxy.show();
    }

/**
    输出:
		load image:b
        [debug]日志开始
        before
        show image:b
        after
        [debug]日志结束
*/

11.AOP (面向切面编程)

11.1 什么是AOP

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

11.2 AOP在Spring中

  • 横切关注点:跨越应用程序多个模块的方法或功能.既是,与我们业务逻辑无关,但是我们需要关注的部分,就是横切关注点.如日志,安全,缓存,事务等…
  • 切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
  • 通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
  • 目标(Target):被通知对象。
  • 代理(Proxy):向目标对象应用通知之后创建的对象。
  • 切入点(PointCut):切面通知 执行的 “地点”的定义。
  • 连接点(JointPoint):与切入点匹配的执行点
通知类型连接点实现接口
前置通知方法前org.springframework.aop.MethodBeforeAdvice
后置通知方法后org.springframework.aop.AfterReturningAdvice
环绕通知方法前后org.aopalliance.intercept.MethodInterceptor
异常抛出通知方法抛出异常org.springframework.aop.ThrowsAdvice
引介通知类中增加新的方法属性org.springframework.aop.IntroductionInterceptor

11.3 使用

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.7</version>
</dependency>

方式一

目标对象/接口 实现类

package cqu.ma.service;

public interface UserService {
    public void insert();
    public void delete();
    public void update();
    public void select();
}

public class UserServiceImpl implements UserService{
    @Override
    public void insert() {
        System.out.println("insert");
    }

    @Override
    public void delete() {
        System.out.println("delete");
    }

    @Override
    public void update() {
        System.out.println("update");
    }

    @Override
    public void select() {
        System.out.println("select");
    }
}

Log类 实现前置通知和后置通知

package cqu.ma.log;

import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class Log implements MethodBeforeAdvice, AfterReturningAdvice {

    /**
     *
     * @param method 目标对象的方法
     * @param objects 方法参数
     * @param o 目标对象
     * @throws Throwable
     */
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("[LOG]-exe "+o.getClass().getName()+":"+method.getName());
    }

    /**
     *
     * @param o 返回结果
     * @param method
     * @param objects
     * @param o1 目标对象
     * @throws Throwable
     */
    @Override
    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
        System.out.println("[LOG]-exe "+method.getName()+" -return "+o);
    }
}

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: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/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="userService" class="cqu.ma.service.UserServiceImpl"></bean>
    <bean id="log" class="cqu.ma.log.Log"></bean>

    <!--方式一:使用原生Spring API接口-->
    <!--配置aop-->
    <aop:config>
        <!--切入点: expression:表达式, execution(要执行的位置)-->
        <aop:pointcut id="pointcut" expression="execution(* cqu.ma.service.UserServiceImpl.*(..))"/>
        <!--执行环绕增强-->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"></aop:advisor>
    </aop:config>
</beans>

test

    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserService service = context.getBean("userService",UserService.class);

        service.delete();
    }

/**
输出:
	[LOG]-exe cqu.ma.service.UserServiceImpl:delete
    delete
    [LOG]-exe delete -return null
*/
方式二
package cqu.ma.pointcut;

public class MyPointcut {
    public void before(){
        System.out.println("before");
    }

    public void after(){
        System.out.println("after");
    }
}
    <!--方式二: 自定义类-->
    <bean id="myPointcut" class="cqu.ma.pointcut.MyPointcut"></bean>
    <aop:config>
        <!--自定义切面, ref 要引用的类-->
        <aop:aspect ref="myPointcut">
            <!--切入点-->
            <aop:pointcut id="point" expression="execution(* cqu.ma.service.UserService.*(..))"/>
            <!--通知-->
            <aop:before method="before" pointcut-ref="point"></aop:before>
            <aop:after method="after" pointcut-ref="point"></aop:after>
        </aop:aspect>
    </aop:config>
方式三 (使用注解实现)
package cqu.ma.pointcut;

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(* cqu.ma.service.UserServiceImpl.*(..))")
    public void before(){
        System.out.println("-before-");
    }

    @After("execution(* cqu.ma.service.UserServiceImpl.*(..))")
    public void after(){
        System.out.println("-after-");
    }

    //在环绕增强中,可以给定一个参数,代表要获取处理切入的点
    @Around("execution(* cqu.ma.service.UserServiceImpl.*(..))")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕前");

        //执行方法
        Object proceed = joinPoint.proceed();

        System.out.println("环绕后");
    }
}
	<!--方式三: 注解-->
    <bean id="annotationPointcut" class="cqu.ma.pointcut.AnnotationPointcut"></bean>
    <!--开启注解支持-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

总结

  • 方式一:使用Spring API
    • 实现通知接口
    • xml配置
      • 切入点
      • 通知
  • 方式二:自定义类
    • 自定义通知类
    • xml配置
      • 自定义切面 引用类
        • 切入点
        • 通知
  • 方式三:注解
    • 注解标注类
    • xml配置
      • 开启注解支持

12.整合 Mybatis

  1. 导入依赖

    • junit

    • mybaits

    • mysql

    • spring相关

    • aop织入

    • mybatis-spring

        <dependencies>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.3.9</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/junit/junit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.9.7</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.21</version>
            </dependency>
    
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.6</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>5.3.9</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>2.0.6</version>
            </dependency>
    
    
        </dependencies>
    
  2. 配置

  3. 测试

12.1 mybatis

  1. 编写实体类
  2. 编写核心配置文件
  3. 编写接口
  4. 编写Mapper.xml
  5. 测试

12.2 Mybatis-Spring

  1. 编写数据源配置

  2. sqlSessionFactory

  3. sqlSessionTemplate
    spring-dao.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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!--DataSource:使用Spring数据源替换mybatis的配置 c3p0 dbcp druid
            使用Spring提供的JDBC
        -->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
            <property name="url" value="jdbc:mysql://localhost:3306/mybatis
                                        ?useSSL=true
                                        &amp;useUnicode=true
                                        &amp;characterEncoding=UTF-8
                                        &amp;serverTimezone=Asia/Shanghai"></property>
            <property name="username" value="root"></property>
            <property name="password" value="root"></property>
        </bean>
        
        <!--sqlSessionFactory-->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"></property>
            <!--绑定mybatis配置文件-->
            <property name="configLocation" value="classpath:mybatis-config.xml"></property>
            <property name="mapperLocations" value="classpath:cqu/ma/mapper/*.xml"></property>
        </bean>
        
        <!--SqlSessionTemplate就是我们使用的SqlSession-->
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
            <constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg>
        </bean>
    </beans>
    
  4. 给接口加实现类

    package cqu.ma.mapper;
    
    import cqu.ma.pojo.User;
    import org.mybatis.spring.SqlSessionTemplate;
    
    import java.util.List;
    
    public class UserMapperImpl implements UserMapper{
    
        private SqlSessionTemplate sqlSessionTemplate;
    
        public SqlSessionTemplate getSqlSessionTemplate() {
            return sqlSessionTemplate;
        }
    
        public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
            this.sqlSessionTemplate = sqlSessionTemplate;
        }
    
        @Override
        public List<User> getUsers() {
            UserMapper userMapper = sqlSessionTemplate.getMapper(UserMapper.class);
            return userMapper.getUsers();
        }
    }
    
  5. 注入实现类
    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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <import resource="spring-dao.xml"></import>
    
        <bean id="userMapper" class="cqu.ma.mapper.UserMapperImpl">
            <property name="sqlSessionTemplate" ref="sqlSession"></property>
        </bean>
    </beans>
    
  6. 测试
    UserMapper.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!--namespace 绑定一个对应的DAO/Mapper接口-->
    <mapper namespace="cqu.ma.mapper.UserMapper">
        <select id="getUsers" resultType="User">
            select * from user
        </select>
    </mapper>
    

    test

        @Test
        public void test2(){
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserMapper mapper = context.getBean("userMapper",UserMapper.class);
    
            List<User> users = mapper.getUsers();
    
            for (User user : users) {
                System.out.println(user);
            }
        }
    

13.事务

ACID

  • atomicity 原子性

    一个事务要么全部提交成功,要么全部失败回滚,不能只执行其 中的一部分操作

  • consistency 一致性

    事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处于一致性状态

  • isolation 隔离性

    事务的隔离性是指在并发环境中,并发的事务时相互隔离的,一个事务的执行不能不被其他事务干扰。不同的事务并发操作相同的数据时,每个事务都有各自完成的数据空间,即一个事务内部的操作及使用的数据对其他并发事务时隔离的,并发执行的各个事务之间不能相互干扰。

  • durability 持久性

    一旦事务提交,那么它对数据库中的对应数据的状态的变更就会永久保存到数据库中。–即使发生系统崩溃或机器宕机等故障,只要数据库能够重新启动,那么一定能够将其恢复到事务成功结束的状态

Spring中事务管理

  • 声明式事务:AOP

    spring-dao.xml

        <!--配置声明式事务-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
    
        <!--结合AOP,实现事务的织入-->
        <!--配置事务通知-->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <!--给方法配置事务-->
            <!--配置事务传播特性:new propagation-->
            <tx:attributes>
                <tx:method name="add" propagation="REQUIRED"/>
                <tx:method name="delete" propagation="REQUIRED"/>
                <tx:method name="update" 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(* cqu.ma.mapper.*.*(..))"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"></aop:advisor>
        </aop:config>
    
  • 编程式事务:需要在代码中,进行事务管理

保存到数据库中。–即使发生系统崩溃或机器宕机等故障,只要数据库能够重新启动,那么一定能够将其恢复到事务成功结束的状态

Spring中事务管理

  • 声明式事务:AOP

    spring-dao.xml

        <!--配置声明式事务-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
    
        <!--结合AOP,实现事务的织入-->
        <!--配置事务通知-->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <!--给方法配置事务-->
            <!--配置事务传播特性:new propagation-->
            <tx:attributes>
                <tx:method name="add" propagation="REQUIRED"/>
                <tx:method name="delete" propagation="REQUIRED"/>
                <tx:method name="update" 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(* cqu.ma.mapper.*.*(..))"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"></aop:advisor>
        </aop:config>
    
  • 编程式事务:需要在代码中,进行事务管理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值