Spring学习个人之路(一)(IOC)

1 篇文章 0 订阅
1 篇文章 0 订阅


致谢:
感谢【狂神说Java】的辛苦付出

【狂神说Java】Spring5最新完整教程IDEA版通俗易懂:https://www.bilibili.com/video/BV1WE411d7Dv

搭建环境

软件版本

  1. maven:apache-maven-3.6.3
  2. jdk:jdk1.8.0_60_x64

常用注解

  • @Autowired :自动装配类型、名字若都找不到,则报错,可以使用@Quailifire来适配名字

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

  • @Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!【常用】

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

    • dao【@Repository】
    • service【@Service】
    • controller【@Controller】

    这四个注解每个都是一样的,都是代表将某个类注册到Spring中,装配Bean

  • @Scope 作用域{ singleton,prototype,request、session }

  • @Value("") 注解注入属性

常用配置文件

配置pom.xml

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.syk</groupId>
    <artifactId>spring-study-02</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>demo-01-javaconfig</module>
    </modules>

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

            </dependency>
            <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.12</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13</version>
            </dependency>
        </dependencies>
</project>

配置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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="UserServiceImpl" class="com.syk.service.UserServiceImpl">
        <property name="userDao" ref="UserDaoMySqlImpl"></property>
    </bean>

    <bean id="UserDaoImpl" class="com.syk.dao.UserDaoImpl"></bean>
    <bean id="UserDaoMySqlImpl" class="com.syk.dao.UserDaoMySqlImpl"></bean>
    <bean id="UserDaoOracleImpl" class="com.syk.dao.UserDaoOracleImpl"></bean>

    <!--<bean id="student" class="com.syk.pojo.Student">
        <constructor-arg index="0" value="张三"></constructor-arg>
    </bean>-->
   <!-- <bean id="student" class="com.syk.pojo.Student">
        <constructor-arg type="java.lang.String" value="李四"></constructor-arg>
    </bean>-->
    <bean id="student" class="com.syk.pojo.Student">
        <constructor-arg name="name" value="王五"/>
        <property name="address" value="注入插入地址address"/>
    </bean>

    <alias name="student" alias="student2"/>
</beans>

使用注解 配置ApplicationContext.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
          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/>
    <bean id="cat" class="com.syk.pojo.Cat"/>
    <bean id="dog" class="com.syk.pojo.Dog"/>
    <bean id="people" class="com.syk.pojo.People"/>

</beans>

注:

  1. (The implicitly registered post-processors include AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, and the aforementioned RequiredAnnotationBeanPostProcessor.)
    有道翻译:
    (隐式注册的后处理器包括 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorPersistenceAnnotationBeanPostProcessor,以及前面提到的 RequiredAnnotationBeanPostProcessor 。)
  2. <context:annotation-config/>only looks for annotations on beans in the same application context in which it is defined. This means that, if you put <context:annotation-config/> in a WebApplicationContext for a DispatcherServlet, it only checks for @Autowired beans in your controllers, and not your services. See The DispatcherServlet for more information.
    有道翻译:
    只在定义bean的应用程序上下文中查找bean上的注释。这意味着,如果你把放在DispatcherServlet的WebApplicationContext中,它只会检查控制器中的@Autowired bean,而不会检查你的服务。有关更多信息,请参见DispatcherServlet。

获取context:

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

使用JavaConfig完成自动装配

使用@ComponentScan(value={""}) 扫描bean
package com.syk.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(value={"com.syk.pojo"})
public class MyConfig {
    // 显示的声明对象
    @Bean
    public Child getChild(){
        Child c= new Child();
        c.setName("小明同学");
        return c;
    }

    @Bean
    public Parent getParent(Child child) {
        Parent p= new Parent();
        p.setMychild(child);
        return p;
    }


    @Bean
    public BigMaster getBigMaster(Cat cat){
        BigMaster b=new BigMaster();
        b.setCat(cat);
        return b;
    }
}

pojo

@Component
public class Cat {
    @Autowired
    @Value("小花猫")
    private String name;
    public void bark(){
        System.out.println("我的名字是"+name+",我会喵喵叫");
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                '}';
    }
}
@Component
public class Master {
    @Autowired
    private Cat cat;

    public Cat getCat() {
        return cat;
    }

    @Override
    public String toString() {
        return "Master{" +
                "cat=" + cat.toString() +
                '}';
    }
}

//  不使用扫描
public class Child {
    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Child{" +
                "name='" + name + '\'' +
                '}';
    }
}
public class Parent {
    private Child mychild;

    public Child getMychild() {
        return mychild;
    }

    public void setMychild(Child mychild) {
        this.mychild = mychild;
    }

    @Override
    public String toString() {
        return "Parent{" +
                "mychild=" + mychild.toString() +
                '}';
    }
}
public class BigMaster {

    private Cat cat;

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    @Override
    public String toString() {
        return "Master{" +
                "cat=" + cat.toString() +
                '}';
    }
}

测试类

 	@Test
    public void stest01(){// 测试 Mater(使用 #Component) 和 Cat(使用 #Component)
        ApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class);
        Master master = context.getBean("master", Master.class);
        System.out.println(master);
        Cat cat=context.getBean("cat", Cat.class);
        System.out.println(cat);
        System.out.println("============");
        System.out.println(cat==master.getCat());
        /*
        Master{cat=Cat{name='小花猫'}}
        Cat{name='小花猫'}
        ============
        true
         */
    }

    @Test
    public void stest02(){// 测试 Parent(使用 @Bean ) 和 Child(使用 @Bean ) // 测试配置类中 使用 @Bean 配置的类
        ApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class);
        Child getChild = context.getBean("getChild", Child.class);
        Child getChild2 = context.getBean("getChild", Child.class);
        System.out.println(getChild);
        System.out.println(getChild==getChild2);
        System.out.println("---------------------------------");
        Parent getParent = context.getBean("getParent", Parent.class);
        System.out.println(getParent);
        System.out.println(getParent.getMychild()==getChild);
        /*
        Child{name='小明同学'}
        true
        ---------------------------------
        Parent{mychild=Child{name='小明同学'}}
        true
        */
    }

    @Test
    public void stest03(){// 测试 BigMaster (使用 @Bean ) 和 Cat (使用 #Component)
        ApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class);
        BigMaster getBigMaster = context.getBean("getBigMaster", BigMaster.class);
        Cat cat=context.getBean("cat", Cat.class);
        System.out.println(cat);
        System.out.println("============");
        System.out.println(cat==getBigMaster.getCat());
        /*
        Cat{name='小花猫'}
        ============
        true
         */
    }

小结:

  1. 使用配置类完成自动装配不需要 配置 @Autowired,只需在传入方法调用即可
  2. 使用@Bean和@Component完成注入的Bean是可以互相调用的。
  3. 在配置类中配置 @Bean必须给要注入的属性添加 Setter 方法、或者是有参的constructor;而使用注解的方式的则不用,因为底层是使用反射来完成的。
  4. 正确的使用@Bean完成注入的
// 错误示范
 	@Bean
    public BigMaster getBigMaster2(){
        BigMaster b=new BigMaster();
        b.setCat(new Cat());
        return b;
    }

// 测试

 	@Test
    public void stest04(){// 测试 BigMaster (使用 @Bean ) 和 Cat (使用 #Component)
        ApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class);
        BigMaster getBigMaster = context.getBean("getBigMaster2", BigMaster.class);
        Cat cat=context.getBean("cat", Cat.class);
   
        System.out.println("============");
        System.out.println(cat==getBigMaster.getCat());
        System.out.println("--------------------");

        BigMaster getBigMaster2 = context.getBean("getBigMaster2", BigMaster.class);
        System.out.println(getBigMaster2==getBigMaster);
        /*
        Cat{name='小花猫'}
        ============
        false
         */
    }

后果:就是其引用的 Cat 属于显示的new的对象,导致了 Spring容器中 getBigMaster2中的 cat 与 自动装配的 cat 不一致 。

10、代理模式

10.1、静态代理模式

代理模式的好处:

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

缺点:

  • 使用静态代理。一个真实的角色就会产生一个代理角色;代码量会翻倍,可以使用动态代理来解决
10.2、加深理解

代理:对应AOP
纵向编程、横向编程
在这里插入图片描述

10.3、动态代理

弹幕大佬:黑马刘意 动态代理

  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的,不是我们直接写好的
  • 动态代理分为两大类:基于接口的动态代理,及鱼类的动态代理
    • 基于接口 JDK 动态代理【我们在这里使用】
    • 基于类 :cglib
    • java字节码实现:javasisit

需要了解两个类:Proxy、invocationHandler:调用处理程序
在这里插入图片描述
在这里插入图片描述
JDK提供的代理只能对接口使用。对对象进行代理的话要使用更强大的cglib。

动态代理的好处:

  • 一个动态代理类代理的是一个接口,一般就是对应的一类业务
  • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可。
    在这里插入图片描述

11、AOP

11.1 什么是AOP

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

11.2 AOP在Spring中的作用

提供声明式事物:允许用户自定义切面
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

11.3、使用Srping实现AOP

【重点】使用AOP植入,需要导入一个依赖包。

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>
方式一:使用Spring的API接口【主要SpringAPI接口实现】在这里插入图片描述

在这里插入图片描述
代码:

pojo

public class User {
    private int id;
    private String name;
    private String gender;
}

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
        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="logAfter" class="com.syk.log.LogAfter"/>
    <bean id="logBefore" class="com.syk.log.LogBefore"/>
    <bean id="userServiceImpl" class="com.syk.service.UserServiceImpl"/>

<aop:config>
    <aop:pointcut id="pointcut" expression="execution(* com.syk.service.UserService.*(..))"/>
    <aop:advisor advice-ref="logAfter" pointcut-ref="pointcut"/>
    <aop:advisor advice-ref="logBefore" pointcut-ref="pointcut"/>
</aop:config>

</beans>

Service

public interface UserService {
    boolean add(User user);
    boolean delete(int id);
    boolean update(User user);
    List<User> getUserList();
}

public class UserServiceImpl implements UserService {
    public boolean add(User user) {
        System.out.println("成功添加了一条记录");
        return false;
    }

    public boolean delete(int id) {
        System.out.println("成功删除了一条记录");
        return false;
    }

    public boolean update(User user) {
        System.out.println("成功更新了一条记录");
        return false;
    }

    public List<User> getUserList() {
        System.out.println("成功查询了一条记录");
        return null;
    }
}

log

public class LogAfter implements AfterReturningAdvice {
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("[debug][end]"+method.getName()+"方法执行后,返回结果为:"+returnValue);
    }
}
public class LogBefore implements MethodBeforeAdvice {
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("[debug]进入了"+method.getName()+"方法");
    }
}

Test

public class MyTest {
    @Test
    public void test01() {
        ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        UserService userService = context.getBean("userServiceImpl", UserService.class);
        userService.add(null);
    }
}
方式二:使用自定义类来实现AOP【主要是切面】

在这里插入图片描述

实现代码

xml

<aop:config>
    <aop:aspect ref="log">
        <aop:pointcut id="pointcut" expression="execution(* com.syk.service.UserService.*(..))"/>
        <aop:before method="before" pointcut-ref="pointcut"/>
        <aop:after method="after" pointcut-ref="pointcut"/>
    </aop:aspect>
</aop:config>

Log类

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

    public void after(){
        System.out.println("===============after============");
    }
}

Test

@Test
public void test01() {
    ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
    UserService userService = context.getBean("userServiceImpl", UserService.class);
    userService.add(null);
}
/*
===============before============
成功添加了一条记录
===============after============
*/

使用切面:即一个类;切入点:即类中的一个方法;

不过没有第一种方式强大。

方式三:使用注解实现!

要开启自动代理
在这里插入图片描述
在这里插入图片描述
xml

<bean id="log" class="com.syk.log.Log"/>
<bean id="userServiceImpl" class="com.syk.service.UserServiceImpl"/>

<aop:aspectj-autoproxy/>
<bean id="logAnnotation" class="com.syk.diy.LogAnnotation"/>

java

package com.syk.diy;

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

@Aspect
public class LogAnnotation {
    @Before("execution(* com.syk.service.UserService.*(..))")
    public void before(){
        System.out.println("方法执行前");
    }
    @After("execution(* com.syk.service.UserService.*(..))")
    public void after(){
        System.out.println("方法执行后");
    }
}

test

@Test
public void test01() {
    ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
    UserService userService = context.getBean("userServiceImpl", UserService.class);
    userService.add(null);
}
/*
方法执行前
成功添加了一条记录
方法执行后
*/

12、整合MyBatis

官网:http://mybatis.org/spring/zh/factorybean.html

在这里插入图片描述
步骤:

  1. 导入相关jia包
    • junit
    • mybatis
    • mysql数据库
    • spring相关的
    • aop织入
    • mybatis-spring【new】

12.2、mybatis-spring

spring-dao.xml

在这里插入图片描述

  1. 编写数据源配置
  2. sqlSesionFactory
  3. sqlSessionTemplate
  4. 给接口加实现类
  5. 将自己写的实现类,注入到Spring中,
  6. 测试使用即可。

第二种方式实现整合:

使用官方提供的 SqlSessionDaoSupport 类来整合,在bean中注入的时候 参数需要传入SqlsessionFactory即可。

13、声明式事务

1、回顾事务

  • 把一组业务当成一个业务来做;要么都成功,要么都失败
  • 事务在项目开发中,十分的重要,涉及到数据的一致性问题,不能马虎!
  • 确保完整性和一致性;

事务ADID原则:

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

2、spring中的事务管理

  • 声明式事务:AOP
  • 编程式事务:需要在代码中,进行事务的管理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
思考:

为什么需要事务?

  • 如果不配置事务,可能存在数据提交不一致的情况下;
  • 如果我们不在Spring中去配置声明式事务,我们就需要在代码中手动配置事务!
  • 事务在项目的开发中十分重要,涉及到数据的一致性和完整性,不容马虎

实现代码:

12.2、mybatis-spring 全部实现代码

第一种实现方式

  1. 项目结构图

在这里插入图片描述

  1. 配置

    • pom.xml
<?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-02</artifactId>
    <groupId>com.syk</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>spring-03-mybatis-02</artifactId>


<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.20</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.4</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.4</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.6.RELEASE</version>
    </dependency>
</dependencies>
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
                <include>**/*.properties</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
                <include>**/*.tld</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>

</build>
</project>

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

    <import resource="spring-dao.xml"/>
    <bean id="userMapper" class="com.syk.mapper.UserMapperImpl">
        <property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>
    </bean>
</beans>
  • 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
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="url" value="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&amp;useSSL=true&amp;charset=utf-8"/>
            <property name="username" value="root"/>
            <property name="password" value="123456"/>
        </bean>
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="configLocation" value="mybatis-config.xml"/>
    <!--        <property name="mapperLocations" value="classpath:com/syk/mapper/*.java"/>-->
        </bean>
        <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
    		<constructor-arg name="sqlSessionFactory" index="0" ref="sqlSessionFactory"/>
        </bean>
    </beans>
    

    mybatis-config.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.syk.pojo"/>
        </typeAliases>
        <mappers>
            <mapper class="com.syk.mapper.UserMapper"/>
        </mappers>
    </configuration>
    
  1. 代码

    User

    package com.syk.pojo;
    
    import lombok.Data;
    import lombok.ToString;
    
    import java.util.Date;
    
    @Data
    @ToString
    public class User {
        private int id;
        private String name;
        private String password;
        private Date birthday;
        private String email;
    }
    

    UserMapper

    package com.syk.mapper;
    
    import com.syk.pojo.User;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    
    import java.util.List;
    
    
    public interface UserMapper {
        @Select(" select * from users ")
        List<User> getUserList();
    
        @Select(" select * from users where id=#{id} ")
        User getUserById(@Param("id") int id);
    }
    

    UserMapperImpl

    package com.syk.mapper;
    
    import com.syk.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> getUserList() {
            UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
            return mapper.getUserList();
        }
    
        public User getUserById(int id) {
            UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
            return mapper.getUserById(id);
        }
    }
    
  2. 测试

    MyTest

    import com.syk.mapper.UserMapperImpl;
    import com.syk.pojo.User;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.util.List;
    
    public class MyTest {
        @Test
        public void test01(){
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserMapperImpl userMapper = context.getBean("userMapper", UserMapperImpl.class);
            List<User> userList = userMapper.getUserList();
            for (User user : userList) {
                System.out.println(user);
            }
    
            /*
            User(id=1, name=张三, password=123456, birthday=Sun May 02 00:00:00 CST 1993, email=zs@qq.com)
            User(id=2, name=李四, password=123123, birthday=Sat Jul 11 00:00:00 CST 1998, email=ls@qq.com)
            User(id=3, name=王五, password=111111, birthday=Sun Apr 21 00:00:00 CDT 1991, email=ww@qq.com)
            User(id=5, name=狂神说Java, password=12345678, birthday=Sat May 09 00:00:00 CST 2020, email=kss@126.com)
             */
        }
    
        @Test
        public void test02(){
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserMapperImpl userMapper = context.getBean("userMapper", UserMapperImpl.class);
            User user = userMapper.getUserById(1);
            System.out.println(user);
    
            /*
            User(id=1, name=张三, password=123456, birthday=Sun May 02 00:00:00 CST 1993, email=zs@qq.com)
             */
        }
    }
    
  3. 总结

    • 编写数据源配置
    • sqlSesionFactory
    • sqlSessionTemplate
    • 给接口加实现类
    • 将自己写的实现类,注入到Spring中,
    • 测试使用即可。

    区别:

    • <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
          <property name="url" value="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&amp;useSSL=true&amp;charset=utf-8"/>
          <property name="username" value="root"/>
          <property name="password" value="123456"/>
      </bean>
      <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
          <property name="dataSource" ref="dataSource"/>
          <property name="configLocation" value="mybatis-config.xml"/>
      <!--        <property name="mapperLocations" value="classpath:com/syk/mapper/*.java"/>-->
      </bean>
      <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
          <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
      </bean>
      <!-- 
      1、使用 DriverManagerDataSource 来替代 
      InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
      
      2、使用 SqlSessionFactoryBean 这个bean来替代
      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
      
      3、SqlSessionTemplate 来替代
      SqlSession sqlSession = sqlSessionFactory.openSession();
      
      -->  
          
      
    • 为了使用 spring 来管理管理mapper,添加一个 接口实现类,将原本写在外面的获取mapper代码并操作的代码,整合统一放入 Impl 实现类 中。

      public class UserMapperImpl implements UserMapper {
          private SqlSessionTemplate sqlSessionTemplate;
          public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
              this.sqlSessionTemplate = sqlSessionTemplate;
          }
          public User getUserById(int id) {
              UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
              return mapper.getUserById(id);
          }
      }
      

      使用 Spring 托管对象

      <bean id="userMapper" class="com.syk.mapper.UserMapperImpl">
          <property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>
      </bean>
      

      调用

      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
      UserMapperImpl userMapper = context.getBean("userMapper", UserMapperImpl.class);
      User user = userMapper.getUserById(1);
      System.out.println(user);
      

    第二种实现方式

    UserMapperImpl2

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

    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
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="userMapper2" class="com.syk.mapper.UserMapperImpl2">
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>
    </beans>
    

    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
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="url" value="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&amp;useSSL=true&amp;charset=utf-8"/>
            <property name="username" value="root"/>
            <property name="password" value="123456"/>
        </bean>
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="configLocation" value="mybatis-config.xml"/>
        </bean>
    </beans>
    

    Test

    @Test
    public void test02(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapperImpl2 userMapper = context.getBean("userMapper2", UserMapperImpl2.class);
        User user = userMapper.getUserById(1);
        System.out.println(user);
    
        /*
        User(id=1, name=张三, password=123456, birthday=Sun May 02 00:00:00 CST 1993, email=zs@qq.com)
         */
    }
    

    13、事务的配置

    <!--结合aop实现事务的织入-->
    <!--配置事务通知-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <constructor-arg ref="dataSource"/>
    </bean>
    <xs:advice id="txAdvice" transaction-manager="transactionManager">
        <!--给哪些方法配置事务-->
        <xs:attributes>
            <xs:method name="add" propagation="REQUIRED"/>
            <xs:method name="*" propagation="REQUIRED"/>
        </xs:attributes>
    </xs:advice>
    <aop:config proxy-target-class="true">
        <aop:pointcut id="txPoint" expression="execution(* com.syk.mapper.*.*(..))"/>
        <!--配置事务切入-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
    </aop:config>
    

    UserMapperImpl3

    package com.syk.mapper;
    
    import com.syk.pojo.User;
    import org.mybatis.spring.support.SqlSessionDaoSupport;
    
    import java.util.Date;
    import java.util.List;
    
    public class UserMapperImpl3 extends SqlSessionDaoSupport implements UserMapper2 {
        public List<User> getUserList() {
            // 先插入、后删除
            User user = new User(8,"张三3222","1233456",new Date(),"111@123.com");
            UserMapper2 mapper2 = this.getSqlSession().getMapper(UserMapper2.class);
            mapper2.addUser(user);
            mapper2.delete(8);
            return mapper2.getUserList();
        }
    
        public User getUserById(int id) {
            return null;
        }
    
        public int addUser(User user) {
            return 0;
        }
    
        public int delete(int id) {
            return 0;
        }
    }
    

    UserMapper2

    package com.syk.mapper;
    
    import com.syk.pojo.User;
    import org.apache.ibatis.annotations.Delete;
    import org.apache.ibatis.annotations.Insert;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    
    import java.util.List;
    
    public interface UserMapper2 {
        @Select(" select * from users ")
        List<User> getUserList();
    
        @Select(" select * from users where id=#{id} ")
        User getUserById(@Param("id") int id);
    
        @Insert(" insert into users (`id`,`name`,`password`,`birthday`,`email`) values (#{id},#{name},#{password},#{birthday},#{email}) ")
        int addUser(User user);
    
        @Delete(" delete from users where id=#{id} ")
        int delete(int id);
    }
    

    test

    public class Mytest {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserMapper2 userMapper3 = context.getBean("userMapper3", UserMapperImpl3.class);
            List<User> userList = userMapper3.getUserList();
            for (User user : userList) {
                System.out.println(user);
            }
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值