1、Spring

1.1、简介

官网: https:/lspring.io/projects/spring-framework#overview

官方下载地址: http://repo.spring.io/release/orglspringframework/spring

GitHub: https:/lgithub.comlspring-projects/spring-framework

1 <!-- https : //mvnrepository.com/artifact/org.springframework/spring-webmvc -->2<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</ artifactId>
<version>5.2.O.RELEASE</version>
    </ dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->8<dependency>
<groupId>org.springframework</groupId>
<artifactid>spring-jdbc</artifactId>
<cversion>5.2.0.RELEASE</version>
    </ dependency>

1.2、优点

总结一句话: Spring就是一个轻量级的控制反转(IOC))和面向切面编程(AOP)的框架!

2、IOC理论推导

  1. UserDao 接口
  2. UserDaoImpl 接口实现类
  3. UserService 业务接口
  4. UserServiceImpl 业务实现类

在之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求去修改源代码,如果程序代码量十分大,修改一次的成本代价十分昂贵!

我们使用一个Set接口实现,已经发生了革命性的变化!

//利用set动态实现值的注入
public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
}

这种思想,从本质上解决了问题,我们程序员不用再去管理对象的创建!系统的耦合性大大降低,可以更加专注在业务的实现上!这是IOC的原型!

IOC本质

控制反转loC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现loC的一种方法,也有人认为DI只是loC的另一种说法。没有loC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是︰获得依赖对象的方式反转了。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是loC容器,其实现方法是依赖注入(Dependency Injection,Dl)。

控制:获取对象的控制权从程序转换到容器。

反转:程序由主动创建对象变成被动接收对象。

3、IOC创建对象的方式

1.使用无参构造创建对象,默认!

2.假设我们要使用有参构造创建对象

  1. 下标赋值

    <!--第一种:下标赋值-->
    <bean id="user" class="com.ws.pojo.User">
        <constructor-arg index="0" value="ws学Java"/>
    </bean>
    
  2. 通过类型创建

    <!--第一种:通过类型创建,不建议使用-->
    <bean id="user" class="com.ws.pojo.User">
        <constructor-arg type="java.lang.String" value="qidayang"/>
    </bean>
    

    3.参数名

    <!--第三种方式:直接通过参数名创建-->
        <bean id="user" class="com.ws.pojo.User">
            <constructor-arg name="name" value="其打样"/>
        </bean>
    

总结:在配置文件加载的时候,容器中管理的对象就已经初始化了!

4、Spring配置

4.1、别名

<!--如果添加了别名,我们也可以通过别名获取这个对象-->
<alias name="user" alias="userNew"/>

4.2、Bean的配置

<!--id:bean的唯一标识符,也就是我们学的对象名
class:bean所对应的全限定名:包名+类名
name:也是别名,而且name可以去多个别名-->
<bean id="userT" class="com.ws.pojo.UserT" name="userTNew,userTNew2 u3;u4">
    <constructor-arg name="name" value="xiahouxue"/>
</bean>
## 4.3import
这个import,一般用于团队开发使用,他可以将多个配置文件,导入合并为一个!
假设,现在项目中有多个人开发,这三个人复制不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的!
- 张三
- 李四
- 王五
- applicationContext.xml
  ```xml
  <import resource="beans.xml"/>
  <import resource="beans1.xml"/>

使用的时候,直接使用总的配置就可以了!

5、依赖注入(DI)

5.1、构造器注入

前面已经说过

5.2、Set方式注入 【重点】

【环境搭建】

​ 1.复杂类型

​ 2.真实测试对象

5.3、扩展方式注入

实体类

package com.ws.pojo;
public class Address {
    private String address;
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                '}';
    }
}
package com.ws.pojo;
import java.util.*;
public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbys;
    private Map<String, String> card;
    private Set<String> games;
    private String wife;
    private Properties info;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    public String[] getBooks() {
        return books;
    }
    public void setBooks(String[] books) {
        this.books = books;
    }
    public List<String> getHobbys() {
        return hobbys;
    }
    public void setHobbys(List<String> hobbys) {
        this.hobbys = hobbys;
    }
    public Map<String, String> getCard() {
        return card;
    }
    public void setCard(Map<String, String> card) {
        this.card = card;
    }
    public Set<String> getGames() {
        return games;
    }
    public void setGames(Set<String> games) {
        this.games = games;
    }
    public String getWife() {
        return wife;
    }
    public void setWife(String wife) {
        this.wife = wife;
    }
    public Properties getInfo() {
        return info;
    }
    public void setInfo(Properties info) {
        this.info = info;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", address=" + address.toString() +
                ", books=" + Arrays.toString(books) +
                ", hobbys=" + hobbys +
                ", card=" + card +
                ", games=" + games +
                ", wife='" + wife + '\'' +
                ", info=" + info +
                '}';
    }
}

测试类

import com.ws.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) applicationContext.getBean("student");
        System.out.println(student.toString());
    }
    /*Student{
     name='qdy',
     address=Address{address='厦门'}, books=[红楼梦, 西游记, 水浒传],
     hobbys=[听歌, 敲代码, 看电影], card={身份证=1234567890, 银行卡=1234345234, =},
     games=[lol, 王者, 吃鸡],
     wife='null',
     info={学号=31, 性别=男, 年龄=19}
     }*/
}

完善注入信息

<?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="address" class="com.ws.pojo.Address">
        <property name="address" value="厦门"/>
    </bean>
    <bean id="student" class="com.ws.pojo.Student">
        <!--第一种:普通值注入-->
        <property name="name" value="qdy"/>
        <!--第二种:bean注入-->
        <property name="address" ref="address"/>
        <!--第三种:数组注入:ref-->
        <property name="books" >
            <array>
                <value>红楼梦</value>
                <value>西游记</value>
                <value>水浒传</value>
            </array>
        </property>
        <!--List-->
        <property name="hobbys">
            <list>
                <value>听歌</value>
                <value>敲代码</value>
                <value>看电影</value>
            </list>
        </property>
        <!--Map-->
        <property name="card">
            <map>
                <entry key="身份证" value="1234567890"/>
                <entry key="银行卡" value="1234345234"/>
                <entry key="" value=""/>
            </map>
        </property>
        <!--Set-->
        <property name="games">
            <set>
                <value>lol</value>
                <value>王者</value>
                <value>吃鸡</value>
            </set>
        </property>
        <!--null-->
        <property name="wife" >
                <null/>
        </property>
        <!--Properties-->
        <property name="info">
            <props >
                <prop key="性别">男</prop>
                <prop key="学号">31</prop>
                <prop key="年龄">19</prop>
            </props>
        </property>
    </bean>
</beans>

5.4、bean的作用域

spring5随笔

1.单例模式(Spring默认机制)

1 <bean id="user2" class="com.ws.pojo.user" c:age="18" c:name="狂神"
scope="sing1eton" />

2.原型模式:每次从容器中get的时候,都会产生一个新对象!

1<bean id="accountservice" class="com.something.Defau1tAccountservice"
scope="prototype" />

3.其余的request、session、 application、这些个只能在web开发中使用到!

6、Bean的自动装配

在Spring中有三中装配方式

  1. 在xml中显示的配置
  2. 在Java中显示配置
  3. 隐式的自动装配bean 【重要】

6.1、测试

环境搭建:一个人有两个宠物!

6.2、ByName自动装配

   <!--ByName:会自动在上下文中查找,和自己对象set方法后面的值对应的beanid-->
    <bean id="people" class="com.ws.pojo.People" autowire="byName">
        <property name="name" value="xq"/>
    </bean>

6.3、ByType自动装配

    <bean id="dog" class="com.ws.pojo.Dog"/>
    <bean class="com.ws.pojo.Cat"/>
    <!--ByName:会自动在上下文中查找,和自己对象set方法后面的值对应的beanid-->
    <!--ByType:会自动在上下文中查找,和自己对象属性相同的bean, bean的id属性可以省略-->
    <bean id="people" class="com.ws.pojo.People" autowire="byType">
        <property name="name" value="xq"/>
    </bean>

小结:

6.4、使用注解自动装配

要使用注解须知:

  1. 导入约束,context约束
  2. == 配置注解的支持: 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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <context:annotation-config/>
</beans>

@Autowired

科普:

@Nullable 字段标记了这个注解,说明这个字段可以为null.

7、使用注解开发

在Spring 4 之后,要是用注解开发,必须要保证aop的包导入了!

spring5随笔

使用注解需要导入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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <context:annotation-config/>
</beans>
  1. bean
  2. 属性如何注解
//等价于 <bean id="user" class="com.ws.pojo.User"/>
@Component
public class User {
    public String name;
    @Value("asdfas")
    public void setName(String name) {
        this.name = name;
    }
  1. 衍生的注解

    ​ @Component 有几个衍生注解,我们在web开发中,会按照mvc三层架构分层!

    • dao 【@Repository】

    • service 【@Service】

    • controller 【@Controller】

      ​ 这四个注解功能都是一样的,都是将某个类注册到Spring中,装配Bean!

  2. 自动装配置

@Autowired : 自动装配通过类型。名字
	如果Autowired不能唯一自动装配上属性,则需要通过@Qualifier(value="xxx")- @Nullable字段标记了这个注解,说明这个字段可以为null;
@Resource:自动装配通过名字。类型。
  1. 作用域
//等价于 <bean id="user" class="com.ws.pojo.User"/>
@Component
@Scope("prototype")
public class User {
    public String name;
    @Value("asdfas")
    public void setName(String name) {
        this.name = name;
    }
  1. 小结

xml与注解:

xml与注解最佳实践:

<!--指定扫描包,这个包下的注解就会生效-->
    <context:component-scan base-package="com.ws"/>
    <context:annotation-config/>

8、使用Java的方式配置Spring

我们现在要完全不使用Spring的xml配置了,全权交给Java来做!

JavaConfig 是Spring的一个子项目,在Spring 4之后,它成为了一个核心功能!

实体类:

//这里这个注解的意思,就是说明这个类被Spring接管了,注册到了Spring容器中
@Component
public class User {
    public String name;
    public String getName() {
        return name;
    }
    @Value("其打样") //属性注入值
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }

配置文件:

@Configuration
//这个也会被Spring容器托管,注册到容器中,因为他本来就是一个@Component
//@Configuration 代表这是一个配置类,就和我们之前看的beans.xml是一样的
@ComponentScan("com.ws")
@Import(UserConfig2.class)
public class UserConfig {
    //注册一个bean,就相当于之前写的一个bean标签
    //这个方法的名字就相当于bean标签中的id属性
    //这个方法的返回值就相当于bean标签中的class属性
    @Bean
    public User getUser() {
        //就是返回要注入到bean中的对象!
        return new User();
    }

测试类:

public class MyTest {
    public static void main(String[] args) {
        //如果完全使用了配置类方式去做,我们就只能通过AnnotationConfig 上:下文来获取容器,通过配置类的cLass对象加载!
        ApplicationContext context = new AnnotationConfigApplicationContext(UserConfig.class);
        User user =(User) context.getBean("getUser");
        System.out.println(user.getName());
    }
}

这种纯Java的配置文件,在SpringBoot中随处可见!

9、代理模式

为什么要学习代理模式?因为就是SpringAOP的底层!【SpringAOP 和 SpringMVC】

代理模式:

spring5随笔

9.1、静态代理

角色分析:

代码步骤:

1.接口

/**
 * @author 平卉陌路
 */
public interface Rent {
    //出租房屋
    public void rent();
}

2.真实角色

/**
 * @author 平卉陌路
 */
public class Host implements Rent{
    @Override
    public void rent() {
        System.out.println("房东要出租房子!");
    }
}

3.代理角色

/**
 * @author 平卉陌路
 */
public class Proxy implements Rent{
    private Host host;
    public Proxy() {
    }
    public Proxy(Host host) {
        this.host = host;
    }
    @Override
    public void rent() {
        host.rent();
        seeHouse();
        signAgreement();
        free();
    }
    //看房
    public void seeHouse(){
        System.out.println("中介带你看房!");
    }
    //签合同
    public void signAgreement(){
        System.out.println("签租赁合同");
    }
    //收中介费
    public void free(){
        System.out.println("收中介费");
    }
}

4.客户端访问代理角色

/**
 * @author 平卉陌路
 */
public class Client {
    public static void main(String[] args) {
        //房东要出租房子
        Host host = new Host();
        /*host.rent();*/
        //代理,中介帮房东出租房子,但中介会有一些附属操作
        Proxy proxy = new Proxy(host);
        //你不用面对房东,找中介租房即可!
        proxy.rent();
    }
}

代理模式的好处:

缺点:

9.2、加深理解

聊聊横向AOP开发:

spring5随笔9.3、动态代理

需要了解两个类: Proxy:代理,InvocationHandler:调用处理程序

动态代理的好处:

10、AOP

10.1、什么是AOP

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

spring5随笔

10.2 、Aop在Spring中的作用

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

spring5随笔

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

即Aop在不改变原有代码的情况下,去增加新的功能.

10.3、使用Spring实现Aop【重点】

使用AOP织入,需要导入一个依赖包!

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

注册bean:

 <!--注册bean-->
    <bean id="userService" class="com.ws.service.UserServiceImpl"/>
    <bean id="log" class="com.ws.log.Log"/>
    <bean id="afterLog" class="com.ws.log.AfterLog"/>

方式一 :使用Spring的接口 【主要是SpringAPI接口实现】

<!--方式一:使用原生Spring API接口-->
<!--配置aop:需要导入aop的约束-->
 <aop:config>
         <!--切入点 expression :表达式 execution:要执行的位置-->
         <aop:pointcut id="pointcut" expression="execution(* com.ws.service.UserServiceImpl.*(..))"/>
         <!--执行环绕增加-->
         <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
         <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
     </aop:config>

方式二 :自定义类实现AOP (XML)【主要是切面定义】

    <!--方式二:基于xml的声明式AspectJ-->
      <bean id="diy" class="com.ws.diy.DiyPointCut"/>
        <aop:config>
            <!-- 自定义切面 ref:要引用的类-->
            <aop:aspect ref="diy">
                <!--切入点-->
                <aop:pointcut id="pointcut" expression="execution(* com.ws.service.UserServiceImpl.*(..))"/>
                <!--配置通知-->
                <!--前置通知-->
                <aop:before method="before" pointcut-ref="pointcut"/>
                <!--后置通知-->
                <aop:after method="after" pointcut-ref="pointcut"/>
                <!--环绕通知-->
                <aop:around method="around" pointcut-ref="pointcut"/>
                <!--异常通知-->
                <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="throwable"/>
                <!--最终通知-->
                <aop:after-returning method="afterReturning" pointcut-ref="pointcut"/>
            </aop:aspect>
        </aop:config>

方式三 :使用注解实现

<!--方式三:基于注解的声明式AspectJ-->
    <bean id="annotationPointCut" class="com.ws.diy.AnnotationPointCut"/>
    <!--开启注解支持 jdk(默认proxy-target-class="false")  cglib(proxy-target-class="true")-->
    <aop:aspectj-autoproxy proxy-target-class="true"/>

11. 整合mybatis

文档: https://mybatis.org/spring/zh/

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-study</artifactId>
        <groupId>com.hou</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>spring-10-mybatis</artifactId>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
</project>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <package name="com.ws.pojo"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://111.230.212.103:3306/mybatis?userSSL=true&amp;
                userUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="ws"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper class="com.mapper.UserMapper"/>
    </mappers>
</configuration>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mapper.UserMapper">
    <select id="selectUser" resultType="user">
        select * from mybatis.user;
    </select>
</mapper>
public interface UserMapper {
    List<User> selectUser();
}

整合

方法一:

1586177510119

UserMapperImpl

package com.ws.mapper;
import com.ws.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;
    }
    public List<User> selectUser() {
        UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
        return mapper.selectUser();
    }
}

mybatis.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <package name="com.ws.pojo"/>
    </typeAliases>
</configuration>

spring.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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--data source-->
    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8;
                userUnicode=true&amp;characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
    <!--sqlsession-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasource" />
        <!--bound mybatis-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/ws/mapper/UserMapper.xml"/>
    </bean>
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>
    <bean id="userMapper" class="com.ws.mapper.UserMapperImpl">
        <property name="sqlSessionTemplate" ref="sqlSession"></property>
    </bean>
</beans>

test

import com.ws.mapper.UserMapper;
import com.ws.pojo.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class Mytest {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");
        UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
        for (User user : userMapper.selectUser()) {
            System.out.println(user);
        }
    }
}

方法二:

<?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">
    <!--data source-->
    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8;/>
        <property name="username" value="root"/>
        <property name="password" value="hdk123"/>
    </bean>
    <!--sqlsession-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasource" />
        <!--bound mybatis-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/mapper/UserMapper.xml"/>
    </bean>
    <!--<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">-->
        <!--<constructor-arg index="0" ref="sqlSessionFactory"/>-->
    <!--</bean>-->
    <!--<bean id="userMapper" class="com.ws.mapper.UserMapperImpl">-->
        <!--<property name="sqlSessionTemplate" ref="sqlSession"></property>-->
    <!--</bean>-->
    <bean id="userMapper2" class="com.ws.mapper.UserMapperIml2">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
    </bean>
</beans>
package com.ws.mapper;
import com.ws.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class UserMapperIml2 extends SqlSessionDaoSupport implements UserMapper {
    public List<User> selectUser() {
        SqlSession sqlSession = getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.selectUser();
    }
}

12. 声明式事务

事务的acid原则:

Spring中的事务管理

声明式事务

<?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:tx="http://www.springframework.org/schema/tx"
       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/tx
        https://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-tx.aop">
    <!--data source-->
    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://111.230.212.103:3306/mybatis?userSSL=true&amp;
                userUnicode=true&amp;characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="hdk123"/>
    </bean>
    <!--sqlsession-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasource" />
        <!--bound mybatis-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/mapper/*.xml"/>
    </bean>
    <!--声明式事务-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <constructor-arg ref="datasource" />
    </bean>
    <!--结合aop实现事务置入-->
    <!--配置事务的类-->
    <tx:advice id="tx1" 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="*" propagation="REQUIRED"/>
            <tx:method name="query" read-only="true"/>
        </tx:attributes>
    </tx:advice>
    <!--配置事务切入-->
    <aop:config>
        <aop:pointcut id="txpointxut" expression="execution(* com.mapper.*.*(..))"/>
        <aop:advisor advice-ref="tx1" pointcut-ref="txpointxut"/>
    </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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <import resource="spring-dao.xml"/>
    <bean id="userMapper2" class="com.mapper.UserMapperIml2">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
    </bean>
</beans>

Mapper

package com.ws.mapper;
import com.ws.pojo.User;
import java.util.List;
public interface UserMapper {
    List<User> selectUser();
    int addUser(User user);
    int delete(int id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mapper.UserMapper">
    <select id="selectUser" resultType="user">
        select * from mybatis.user;
    </select>
    <insert id="addUser" parameterType="user">
        insert into mybatis.user (id, name, pwd) values
        (#{id}, #{name}, #{pwd})
    </insert>
    <delete id="delete" parameterType="int">
        delete from mybatis.user where id=#{id}
    </delete>
</mapper>
package com.mapper;
import com.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class UserMapperIml2 extends SqlSessionDaoSupport implements UserMapper {
    public List<User> selectUser() {
        User user = new User(6, "long", "zhi");
        SqlSession sqlSession = getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.addUser(user);
        mapper.delete(6);
        return mapper.selectUser();
    }
    public int addUser(User user) {
        return getSqlSession().getMapper(UserMapper.class).addUser(user);
    }
    public int delete(int id) {
        return getSqlSession().getMapper(UserMapper.class).delete(id);
    }
}

发表回复