Crazy God Spring-5 full version basic knowledge comprehensively explains Spring-Mybatis framework integration

1、spring

1.1. Introduction

  • Spring:---->Bring spring to the software industry

  • In 2002, the prototype of the spring framework was first launched: the interfaace21 framework

  • The Spring framework is based on the interface21 framework. After redesign and continuous enrichment of its connotation, the official version 1.0 was released on March 24, 2004.

  • Rod Johnson, founder of Spring Framework and famous author. It’s hard to imagine that Rod Johnson’s academic qualifications really surprise many people. He has a PhD from the University of Sydney, but his major is not computer science, but musicology.

  • Spring concept: Make existing technologies easier to use. It is a hodgepodge in itself, integrating existing technology frameworks!

    • SSH:Struct2 + Spring + Hibernate!

    • SSM:SpringMVC + Spring + Mybatis!

Official website: https://spring.io/projects/spring-framework#overview
Official download address: https://repo.spring.io/release/org/springframework/spring/
GitHub: https://github.com/spring -projects/spring-framework

maven dependency

spring

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

jdbc

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

1.2. Advantages

  • Spring is an open source free framework (container)
  • Spring is a lightweight, non-intrusive framework! (Importing spring will not cause the project to fail to run)
  • Inversion of Control (IOC) and Aspect-Oriented Programming (AOP)
  • Support transaction processing, support for framework integration!

Spring is a lightweight Inversion of Control (IOC) and Aspect-Oriented Programming (AOP) framework

1.3. Spring composition

[External link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-BIZu4Y7A-1677035935112)(https://cdn.mianshigee.com/upload/note/210313/1246590.jpg ?2017102711233)]

Spring's seven modules: https://blog.csdn.net/weixin_39885962/article/details/125743470

1.4. Expansion

Modern Java development is spring-based development

Insert image description here

  • spring boot
    • A scaffolding for rapid development!
    • Based on springboot, a single microservice can be quickly developed
    • Agreement is greater than configuration
  • spring cloud
    • springcloud is implemented based on springboot

Nowadays, most companies are using springboot for rapid development. The prerequisite for learning springboot is to fully master spring and springMVC! The role of connecting the previous and the following

Disadvantages: After developing for too long, it violates the original concept and the configuration is very cumbersome.

2. IOC theoretical derivation

  1. UserDao interface

    public interface UserDao {
          
          
        public void getUser();
    }
    
  2. UserDaoImpl implementation class

    public class UserDaoImpl implements UserDao{
          
          
        @Override
        public void getUser() {
          
          
            System.out.println("获取数据");
        }
    }
    
    public class UserDaoMysqlImpl implements UserDao{
          
          
        @Override
        public void getUser() {
          
          
            System.out.println("mysql获取用户数据");
        }
    }
    
    public class UserDaoOracleImpl implements UserDao{
        @Override
        public void getUser() {
            System.out.println("Oracle获取数据");
        }
    }
    
  3. UserService business interface

    public interface UserService{
          
          
        public void getUser();
    }
    
  4. UserServiceImpl business implementation

    public class UserServiceImpl implements UserService{
          
          
        private UserDao userDao;
        //利用set进行动态值的注入
        public  void setUserDao(UserDao userDao){
          
          
            this.userDao = userDao;
        }
        @Override
        public void getUser() {
          
          
            userDao.getUser();
        }
    }
    
  5. test

    public class MyTest {
          
          
        public static void main(String[] args) {
          
          
    
            UserServiceImpl userService = new UserServiceImpl();
    
            userService.setUserDao(new UserDaoOracleImpl());
            userService.getUser();
        }
    }
    

In the previous business, user needs may affect our original code, and the source code needs to be modified according to user needs. If the amount of program code is very large, the cost of modifying it once will be very expensive.

We use a set interface to implement

public class UserServiceImpl implements UserService{
    
    
    private UserDao userDao;
    //利用set进行动态值的注入
    public  void setUserDao(UserDao userDao){
    
    
        this.userDao = userDao;
    }
    @Override
    public void getUser() {
    
    
        userDao.getUser();
    }
}
  • Previously, programs were actively created and control rested with the programmer.
  • After using set injection, the program no longer has the initiative, but becomes a passive receiving object.

Insert image description here

This idea essentially solves the problem, and programmers no longer have to manage the creation of objects. System coupling is greatly reduced, and more focus is placed on business online! This is the prototype of IOC

The essence of IOC:

  • Inversion of control IOC is a design idea, and DI dependency injection is a method to implement IOC.
  • Some people think that DI is just another way of saying IOC. In programs without IOC, we use object-oriented programming. The creation of objects and the dependencies between objects are completely hard-coded in the program. The creation of objects is controlled by the program itself. After inversion of control, the creation of the object is transferred to a third party, that is, the spring container. Personally, I think the so-called inversion of control means: the way of obtaining dependent objects is reversed.
  • When configuring beans using xml, the definition information of the bean is separated from the implementation, and the two can be merged into one using annotations. The definition information of the bean is directly defined in the implementation class in the form of annotations, thus achieving zero configuration. the goal of.
  • Inversion of control is a way to create or obtain specific objects through xml or annotations, and through a third party. What implements inversion of control in spring is the IOC container, and its implementation method is DI dependency injection.

3、HelloSpring

  1. Create a new maven project and write entity classes

    public class Hello {
          
          
        private String str;
        public String getStr() {
          
          
            return str;
        }
        public void setStr(String str) {
          
          
            this.str = str;
        }
        @Override
        public String toString() {
          
          
            return "Hello{" +
                    "str='" + str + '\'' +
                    '}';
        }
    }
    
  2. Write Spring xml configuration file

    <?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">
    <!--使用Spring来创建对象,在Spring这些都称为Bean
        类型 变量名 = new 类型();
        Hello hello = new Hello();
    
        id  = 变量名
        class = new 的对象
        property 就是给对象中的属性设置一个值
    
        bean = 对象
    -->
        <bean id="hello" class="com.hwt.pojo.Hello">
            <property name="str" value="Spring"/>
        </bean>
    
    </beans>
    
  3. test

    public class MyTest {
          
          
        public static void main(String[] args) {
          
          
            //获取Spring的上下文对象
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            Hello hello = (Hello) context.getBean("hello");
            System.out.println(hello.toString());
        }
    }
    

ClassPathXmlApplicationContext inheritance relationship
Insert image description here

Questions to think about:

  • Who created the Hello object?
    • Hello object is created by spring
  • How are the properties of the Hello object set?
    • The properties of the Hello object are set by the spring container

This process is called IOC inversion of control:

  • **Control:** Who controls the creation of objects? Objects in traditional applications are created by the program itself. After using spring, objects are created by spring.
  • **Inversion:** The program itself does not create objects, but becomes passive receiving objects.
  • **Dependency injection:** is injected using the set method

OC is a programming idea that changes from active programming to passive reception.

You can browse the source code through new ClassPathXMLApplicationContext.

OK, now, we don’t need to make changes in the program at all. To implement different operations, we only need to make changes in the xml configuration file.

The so-called IOC means: objects are created, managed, and assembled by Spring!

4. How IOC creates beans (objects)

4.1. Use no-parameter construction to create objects, which is the default.

  • Entity class

    public class User {
          
          
        private String name;
    
        public User() {
          
          
            System.out.println("User的无参构造");
        }
    
        public String getName() {
          
          
            return name;
        }
    
        public void setName(String name) {
          
          
            this.name = name;
        }
        public void show(){
          
          
            System.out.println("name="+name);
        }
    }
    
  • beans.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="user" class="com.hwt.pojo.User">
            <property name="name" value="高启强"/>
        </bean>
    
    </beans>
    
  • test

    public class MyTest {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            User user = (User) context.getBean("user");
            user.show();
        }
    }
    

4.2. Suppose we want to use parameterized construction to create objects. There are three ways

  1. subscript assignment

    <!--第一种、 下标赋值-->
    <bean id="user" class="com.hwt.pojo.User">
        <constructor-arg index="0" value="高启盛"/>
    </bean>
    
  2. Parameter type assignment

    <!--第二种, 参数类型赋值-->
    <bean id="user" class="com.hwt.pojo.User">
        <constructor-arg type="java.lang.String" value="泰叔"/>
    </bean>
    
  3. Parameter name assignment

    <bean id="user" class="com.hwt.pojo.User">
        <constructor-arg name="name" value="徐江"/>
    </bean>
    

When the configuration file is loaded, the objects managed in the container have been initialized!

5. Spring configuration

5.1. Alias:

If an alias is added, we can also use the alias to obtain the object, and the original name can also be used

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

5.2. Bean configuration

<!--
    id:bean唯一的标识符,也就相当于对象名
    class:bean 对象对应的限定名: 包名 + 类名
    name:也就是别名,可以取多个别名
-->
<bean id="userT" class="com.hwt.pojo.UserT" name="t"></bean>

5.3、import

Generally used for team development, multiple configuration files can be imported and merged into one.

Assume that there are many individual developers in the project. These people are responsible for the development of different classes. Different classes need to be registered in different beans. We can use import to merge everyone's bean.xml into a total ApplicationContext.xml.

  • Zhang San

  • John Doe

  • Wang Wu

  • ApplicationContext.xml (merged into this file)

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

Just use the general configuration when using it.

6. Dependency injection

6.1. Constructor injection

That’s 4. How IOC creates objects

6.2. Set method injection

  • Dependency injection: set injection
    • Dependency: The creation of the bean object depends on the container
    • Injection: All properties in the bean object are injected by the container

Environment setup

  1. complex type

    public class Address {
        private String address;
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    }
    
  2. real test subjects

    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;
            
            get  set
    }
    
  3. beans.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">
    <!--普通值注入,vlue-->
        <bean id="student" class="com.hwt.pojo.Student">
            <property name="name" value="高启强"/>
        </bean>
    
    </beans>
    
  4. test

    public class MyTest {
          
          
        public static void main(String[] args) {
          
          
          ApplicationContext Context = new ClassPathXmlApplicationContext("beans.xml");
            Student student = (Student) Context.getBean("student");
            System.out.println(student.getName());
        }
    }
    
  5. Other injection information

    <bean id="address" class="com.kuang.pojo.Address">
        <property name="address" value="西安"></property>
    </bean>
    
    <bean id="name" class="com.kuang.pojo.Student">
        <property name="name" value="秦疆"></property>
        <property name="address" ref="address"/>
        <property name="books" >
            <array>
            <value>西游记</value>
            <value>三国演义</value>
            <value>水浒传</value>
            </array>
        </property>
    
        <property name="hobbies">
            <list>
                <value>看书</value>
                <value>听歌</value>
                <value>看电影</value>
                <value>玩手机</value>
            </list>
        </property>
    
        <property name="card">
            <map>
                <entry key="身份证号" value="111111222222333333"></entry>
                <entry key="银行卡" value="512345156663322"></entry>
            </map>
        </property>
    
        <property name="games">
            <set>
                <value>LOL</value>
                <value>BOB</value>
                <value>COC</value>
            </set>
        </property>
    
        <property name="wife">
            <null/>
        </property>
    
        <property name="info">
            <props>
                <prop key="学号">123456</prop>
                <prop key="url">123456</prop>
                <prop key="root">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
    </bean>
    

6.3. Other methods

Injection using p namespace and c namespace

XML shortcut with P-namespace

P-Namespace allows you to use beanattributes of elements (rather than nested <property/>elements) to describe the property values ​​of your collaborating beans, or both.

Spring supports an extensible configuration format with namespaces , which is based on XML schema definitions. The configuration format discussed in this chapter beansis defined in an XML schema document. However, the P-namespace is not defined in the XSD file and only exists in Spring's core.

XML shortcut with C-Namespace

Similar to XML shortcuts with P-namespace , C-namespace introduced in Spring 3.1 allows inline properties to be used to configure constructor parameters instead of nested constructor-argelements.

(1.4 Dependencies)

  • use:

    <?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
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!--p命名空间注入,可以直接注入属性的值:property-->
        <bean id="user" class="com.hwt.pojo.User" p:name="高启强" p:age="20"/>
    
        <!--c命名空间注入,通过构造器注入:construct-args -->
        <bean id="user2" class="com.hwt.pojo.User" c:age="40" c:name="龚开疆"/>
    
    </beans>
    
  • test:

    public void test2(){
          
          
        ApplicationContext context = new ClassPathXmlApplicationContext("userbean.xml");
        User user = context.getBean("user2",User.class);
        System.out.println(user);
    }
    
  • Note: p naming and p naming cannot be imported directly, and xml constraints need to be imported.

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

The injection of p namespace is actually the injection method of set, but we introduce a constraint to make it simpler and more convenient for us to use.

The c namespace still uses the above entity class, but adds a parameterless constructor and a parameterized constructor, because we need to use the parameterized constructor to inject attribute values.

6.4. Bean scope

The following table describes the supported scopes:

Scope illustrate
singleton (Default) A single bean definition is applied to a single object instance per Spring IOC container.
prototype Beans apply a single definition to any number of object instances.
request Beans apply a single definition to the life cycle of a single HTTP request. That is, each HTTP request has its own instance of a Bean created behind a single Bean definition. Spring ApplicationContextonly works in a Web-aware context.
session Apply the scope of a bean definition to the HTTP Sessionlife cycle. Spring ApplicationContextonly works in a network-aware context.
application The life cycle to which the scope of a bean definition applies ServletContext. Spring ApplicationContextonly works in a network-aware context.
websocket The life cycle that a single bean definition acts on WebSocket. Spring ApplicationContextonly works in a network-aware context.
  1. Singleton mode (Spring default mechanism) concurrency will affect

    <bean id="user2" class="com.hwt.pojo.User" c:age="40" c:name="龚开疆" scope="singleton"/>
    
  2. Prototype pattern: Every time you get it from the container, an object will be generated.

    <bean id="user2" class="com.hwt.pojo.User" c:age="40" c:name="龚开疆" scope="prototype"/>
    
  3. The rest of request, session, and application can only be used on the web.

7. Bean automatic assembly

  • Autowiring is a way for spring to satisfy bean dependencies!
  • Spring will automatically find it in the context and automatically assemble the properties for the bean.

Three assembly methods in spring:

  • Configuration displayed in xml
  • Display configuration in Java;
  • Implicit automatic wiring of beans [Key points]

7.1. Testing

**Environment matching:**Create a project where one person has two pets.

<?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="cat" class="com.hwt.pojo.Cat"/>
    <bean id="dog" class="com.hwt.pojo.Dog"/>

    <bean id="people" class="com.hwt.pojo.People">
        <property name="name" value="高启强"/>
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    </bean>

</beans>

7.2. ByName automatic assembly

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

</bean>

7.3. ByType automatic assembly

<!--
   byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean!
-->
<bean id="people" class="com.hwt.pojo.People" autowire="byType">
    <property name="name" value="高启强"/>
</bean>

summary:

  • When ByName, it is necessary to ensure that the ID of all beans is unique, and the bean needs to be consistent with the value of the set method of the automatically injected attribute.
  • When ByType, you need to ensure that the class of all beans is unique, and the bean needs to be consistent with the type of automatically injected properties.

7.4. Use annotations to implement automatic assembly

Annotations supported by jdk1.5, spring2.5 supports annotations

Are annotations better than XML for configuring Spring?
The introduction of annotation-based configuration raises the question of whether this approach is "better" than XML. The short answer is "it depends." The long-term answer is that each approach has its advantages and disadvantages, and generally, it's up to the developer to decide which strategy works better for them. Because of the way they are defined, annotations provide a lot of context in their declarations, resulting in shorter and more concise configurations. However, XML is good at connecting components together without touching their source code or recompiling them. Some developers prefer to keep the connection close to the source code, while others believe that annotated classes are no longer POJOs and, moreover, configuration becomes diffuse and harder to control.

Notes on using annotations:

  • Import constraints: context constraints

  • Configuration annotation support

    <?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

    • You can use it directly on the attribute, or you can use it on the set method.
    • Using Autowired we don't need to write a set method, provided that your automatically assembled property exists in the IOC container and conforms to the type ByType!

Popular science:

The field is marked with this annotation, indicating that this field can be null;

public People(@Nullable String name) {
    
    
    this.name = name;
}

Test code:

@Autowired annotation:

public class People {
    
    
    //如果显式定义Autowired的required属性为false,说明这个对象可以为null,否则不能为空
    @Autowired(required = false)
    private Cat cat;
    @Autowired
    private Dog dog;

    private String name;
}

If the @Autowired automatic assembly environment is more complex and the automatic assembly cannot be completed through an annotation, we can use @Qualifier(value = “xxx”) to configure the use of @Autowired and specify a unique bean object for injection! **

@Autowired:
@Autowired is an annotation provided by the Spring framework. It can annotate class member variables, methods and constructors to complete automatic assembly. Eliminate set and get methods through the use of @Autowired.
@Qualifier:
@Qualifier is an annotation provided by the Spring framework. It can be used together with @Autowired to specify the id of the component that needs to be assembled. When different bean instances have the same type, @Qualifier is used to specify which bean instance to assemble.

public class People {
    
    
    //如果显式定义Autowired的required属性为false,说明这个对象可以为null,否则不能为空
    @Autowired
    private Cat cat;
    @Autowired
    @Qualifier(value = "dog1")
    private Dog dog;

    private String name;
}

@Resource annotation:

public class People {
    
    
    //如果显式定义Autowired的required属性为false,说明这个对象可以为null,否则不能为空
    @Resource(name = "cat1")
    private Cat cat;
    @Resource
    private Dog dog;

    private String name;
}

summary:

The difference between @Resource and @Autowired:

  • They are all used for automatic assembly and can be used on attribute fields.
  • @Autowired is implemented by ByType and must require that this object exists.
  • @Resource is implemented by ByName by default. If the name cannot be found, it is implemented by ByType. If both are not found, an error will be reported.
  • The execution order is different: @Autowired is implemented by byType.

8. Develop using annotations

After Spring 4, to use annotations for development, you must ensure that the aop package is imported.

Insert image description here

To use annotations, you need to import constraints and configure annotation support!

<?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. How to inject attributes

    //等价于 <bean id="user" class="com.hwt.pojo.User"/>
    //Component:组件
    @Component
    public class User {
          
          
        @Value("高启强")
        public String name;
    }
    
  3. Derived annotations

    3. Derived annotations
    @Component has several derived annotations. In web development, we will layer them according to the mvc three-tier architecture!

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

    The functions of these four annotations are the same. They all represent registering a class into Spring and assembling the Bean.

  4. automatic assembly

    • @Autowired: Automatically wired by type, name. If Autowired cannot uniquely autowire attributes, you need to configure them through @Qualifier(value = “xxx”).

    • The @Nullable field is marked with this annotation, indicating that this field can be null;

    • @Resource: Autowiring by name, type.

  5. Scope

    @Component
    @Scope("singleton")//prototype原型模式  singleton单例模式
    public class User {
          
          
        @Value("高启强")
        public String name;
    }
    
  6. summary

    xml and annotations:

    • xml is more versatile and suitable for any occasion! Maintenance is simple and convenient
    • Annotations cannot be used by your own class, and maintenance is complicated!

    Best practices for xml and annotations:

    • xml is used to manage beans;

    • Annotations are only responsible for completing the injection of attributes;

      • During use, you only need to pay attention: for annotations to take effect, you need to enable annotation support and scan packages.

    9. Configure spring using Java

    No need to use Spring's xml configuration at all, leave it all to Java!
    JavaConfig is a sub-project of Spring. After Spring 4, it has become a core function!

Insert image description here

  • Entity class

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    //@Component注解的意思就是这个类被spring接管了,注册到容器中
    @Component
    public class User {
          
          
        private String name;
    
        @Override
        public String toString() {
          
          
            return "User{" +
                    "name='" + name + '\'' +
                    '}';
        }
        public String getName() {
          
          
            return name;
        }
        @Value("高启强")
        public void setName(String name) {
          
          
            this.name = name;
        }
    }
    
  • Configuration file

    import com.hwt.pojo.User;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Import;
    import org.springframework.stereotype.Component;
    
    //@Configuration也会被spring容器接管,注册到容器中,他本来就是一个@Component
    //它代表的是一个配置类,和之前的beans.xml一样
    @Configuration
    @ComponentScan("com.hwt.pojo")
    @Import(Config2.class)//使用注解引入其他配置
    public class Config {
          
          
        /*
            注册一个bean,就相当于就相当于我们之前写的一个bean标签
            这个的方法的名字,相当于bean标签中的id属性
            这个方法的返回值相当于bean标签中的class属性
        */
        @Bean
        public User getUser(){
          
          
            return new User();//即使要返回注入到bean的对象
        }
    }
    
  • Test class

    public class MyTest {
          
          
        @Test
        public void test1(){
          
          
            //如果完全使用了配置类方式去做,就只能通过AnnotationConfigApplicationContext上下文来获取容器,
            //通过配置类的class对象加载
            ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
            User getUser = context.getBean("getUser", User.class);
            System.out.println(getUser.getName());
        }
    }
    

10. Agent mode

The proxy mode is the bottom layer of AOP! [spring aop and spring MVC]

Classification of proxy modes:

  • static proxy
  • dynamic proxy

bold style

10.1. Static proxy

Role analysis:

  • Abstract role: Generally, interfaces or abstract classes are used to solve the problem.
  • Real role: the role being represented
  • Acting role: Acting as a real character. After acting as a real character, we usually do some ancillary operations.
  • Client: The person who accesses the proxy object!

Code implementation steps:

  1. interface

    public interface Rent {
          
          
        public void rent();
    }
    
  2. real character

    //房东
    public class Host implements Rent {
          
          
        @Override
        public void rent() {
          
          
            System.out.println("房东要出租房子");
        }
    }
    
  3. agent role

    //中介
    public class Proxy implements Rent{
          
          
        private Host host;
    
        public Proxy() {
          
          
        }
    
        public Proxy(Host host) {
          
          
            this.host = host;
        }
        @Override
        public void rent() {
          
          
            host.rent();
            seeHost();
            hetong();
            fare();
        }
        //看房
        public void seeHost(){
          
          
            System.out.println("中介带的看房");
        }
        //签合同
        public void hetong(){
          
          
            System.out.println("签合同");
        }
        //收中介费
        public void fare(){
          
          
            System.out.println("收中介费");
        }
    }
    
  4. Client Access Broker role

    public class Cilent {
          
          
        public static void main(String[] args) {
          
          
            Host host  = new Host();
    //        host.rent();
            //代理中介帮房东租房子,代理一般会有其他操作
            Proxy proxy = new Proxy(host);
            proxy.rent();
        }
    }
    

Benefits of proxy mode:

  • It can make the operation of real characters more pure! No need to pay attention to some public business
  • Leave the public role to the agent role! Achieved division of labor
  • When public services expand, centralized management is facilitated

shortcoming:

  • A real role will generate an agent role, the amount of code will double, and development efficiency will become lower.

10.2. Deepen understanding

Code operation steps:

  1. interface:

    public interface UserService {
          
          
        public void add();
        public void delete();
        public void update();
        public void query();
    }
    
  2. Real character:

    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("查询了一个用户");
        }
    }
    
  3. Agent role:

    public class UserServiceProxy implements UserService{
          
          
        private UserServiceImpl userService;
    
        public UserServiceProxy() {
          
          
        }
        public UserServiceProxy(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("使用了"+msg+"方法");
        }
    }
    
  4. Customer Access Agent role:

    public class Cilent {
          
          
        public static void main(String[] args) {
          
          
            UserServiceImpl userService = new UserServiceImpl();
    //        userService.add();
            UserServiceProxy userServiceProxy = new UserServiceProxy(userService);
            userServiceProxy.add();;
        }
    }
    

The principle of AOP:
Insert image description here

10.3. Dynamic proxy

  • Dynamic proxy and static proxy roles are the same
  • The proxy class of dynamic proxy is dynamically generated and is not written directly by us.
  • Dynamic proxies are divided into two categories: interface-based dynamic proxies [jdk] and class-based dynamic proxies [cglib]
    • Based on interface: JDK dynamic proxy [we use it here]
    • Class-based: cglib
    • Java bytecode implementation: javassist

Javassist is an open source library for analyzing, editing and creating Java bytecode. It was created by Shigeru Chiba from the Department of Mathematics and Computer Science at Tokyo Institute of Technology. It has joined the open source project to implement a dynamic "AOP" framework for JBoss by using Javassist to operate on bytecode.

There are two classes you need to know:

  • Proxy: proxy;

  • InvocationHandler: call handler;

Code

  • interface

    //租房,抽象角色
    public interface Rent {
          
          
        public void rent();
    }
    
  • real character

    //房东,要出租房子
    public class Host implements Rent {
          
          
        public void rent() {
          
          
            System.out.println("我要出租房子了");
        }
    }
    
  • ProxyInvocationHandler class

    //自动生产代理类
    public class ProxyInvocationHandler implements InvocationHandler {
          
          
        //被代理的接口
        private Rent rent;
    
        public void setRent(Rent rent) {
          
          
            this.rent = rent;
        }
    
        //生成得到代理类
        public Object getProxy() {
          
          
                                                        //类装载器
            //Proxy.newProxyInstance(this.getClass().getClassLoader(), 被代理的接口,InvocationHandler)
            return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
    
        }
    
        //处理代理实例并返回结果  ,被代理的人
        public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
          
          
            seeHouse();;
            //动态代理的本质,就是使用反射机制
            Object invoke = method.invoke(rent, objects);
            fare();
            return invoke;
        }
    
        public void seeHouse(){
          
          
            System.out.println("带中介看房子");
        }
        public void fare(){
          
          
            System.out.println("收中介费");
        }
    }
    
  • test

    //真实角色
    public class Client {
          
          
        public static void main(String[] args) {
          
          
    
            //真实角色
            Host host = new Host();
            //代理角色,现在不存在,要自动生成
            ProxyInvocationHandler pih = new ProxyInvocationHandler();
    
            //通过调用程序处理角色来处理我们要调用的接口对象!
            pih.setRent(host);
            Rent proxy= (Rent) pih.getProxy();//proxy就是自动生成的代理类,不是我们写的
            proxy.rent();
        }
    }
    
  • The extracted ProxyInvocationHandler is used as a tool class

    //自动生产代理类
    public class ProxyInvocationHandler implements InvocationHandler {
          
          
        //被代理的接口
        private Object target;
    
        public void setRent(Object target) {
          
          
            this.target = target;
        }
    
        //生成得到代理类
        public Object getProxy() {
          
          
                                                        //类装载器
            //Proxy.newProxyInstance(this.getClass().getClassLoader(), 被代理的接口,InvocationHandler)
            return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    
        }
    
        //处理代理实例并返回结果  ,被代理的人
        public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
          
          
            log(method.getName());
            //动态代理的本质,就是使用反射机制
            Object invoke = method.invoke(target, objects);
            return invoke;
        }
    
        public void log(String msg) {
          
          
            System.out.println("执行了" + msg + "方法");
        }
    }
    

Benefits of dynamic proxy:

  • It can make the operation of real characters more pure! No need to pay attention to some public business
  • Leave the public role to the agent role! The division of labor has been realized!
  • When public services expand, centralized management is convenient!
  • A dynamic proxy class is an interface, which generally corresponds to a type of business.
  • A dynamic proxy class can proxy multiple classes as long as they implement the same interface.

11、AOP

11.2. What is AOP?

AOP : Aspect-oriented programming, a technology that achieves unified maintenance of program functions through pre-compilation and run-time dynamic agents. AOP is the continuation of OOP. It is a hot spot in software development and an important content in the spring framework. It is a derivative of functional programming. AOP can be used to isolate various parts of business logic, thereby making the business logic The coupling degree between various parts is reduced, which improves the reusability of the program and improves the efficiency of development.

Insert image description here

11.2. The role of AOP in spring

Provide declarative transactions: allow users to customize aspects

Cross-cutting concerns: methods or functions that span multiple modules of the application; that is, the parts that have nothing to do with our business logic, but that we need to pay attention to, are cross-cutting concerns. Such as logging, security, cache, transactions, etc...

Aspect: A special object that is modularized across concerns. That is, he is a class

Advice: The work that aspects must complete. That is, he is a method in the class

Target: the object to be notified

Proxy: An object created after applying notifications to the target object

Pointcut (PointCut): The definition of the "place" where the aspect notification is executed

JoinPoint: Execution point that matches the entry point

Insert image description here

In SpringAOP, cross-cutting logic is defined through Advice. Spring supports 5 types of Advice:

notification type Junction implement interface
Pre-notification method method before org.springframework.aop.MethodBeforeAdvice
post notification After method org.springframework.aop.AfterReturningAdvice
surround notification before and after method org.aopalliance.intercept.MethodInterceptor
Exception thrown notification Method throws exception org.springframework.aop.ThrowsAdvice
Introduction Notice Add new method attributes to the class org.springframework.aop.IntroductionInterceptor

11.3. Use spring to implement AOP

To use AOP weaving, you need to import a dependency package

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
 </dependency>
11.3.1. Method 1:

Using spring's API interface [springAPI interface implementation]

  1. Under the service package, define the UserService business interface and UserServiceImpl implementation class

    public interface UserService {
          
          
        public void add();
        public void delete();
        public void update();
        public 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("查询了一个用户");
        }
    }
    
  2. Under the log package, define our enhancement classes, a log pre-enhancement and an afterlog post-enhancement class

    public class Log implements MethodBeforeAdvice {
          
          
        //method:要执行目标表对象的方法
        //arg:参数
        //o:目标对象
        @Override
        public void before(Method method, Object[] objects, Object o) throws Throwable {
          
          
    
            System.out.println(o.getClass().getName()+"的"+method.getName()+"被执行了");
        }
        
    }
    
    public class AfterLog implements AfterReturningAdvice {
          
          
        //returnValue;返回值
        @Override
        public void afterReturning(Object returnValue, Method method, Object[] objects, Object o1) throws Throwable {
          
          
            System.out.println("执行力"+method.getName()+"方法,结果为:"+returnValue);
        }
    }
    
  3. Finally, register in the spring configuration file and implement AOP cut-in. Pay attention to import constraints and configure the applicationContext.xml file.

    <?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-->
        <bean id="userService" class="com.hwt.service.UserServiceImpl"/>
        <bean id="log" class="com.hwt.log.Log"/>
        <bean id="afterLog" class="com.hwt.log.AfterLog"/>
    <!--    方式一:使用原生的Spring API接口-->
    <!--    配置aop的约束-->
        <aop:config>
            <!--切入点  expression:表达式 execution(要执行的位置)-->
            <aop:pointcut id="pointcut" expression="execution(* com.hwt.service.UserServiceImpl.*(..))"/>
            <!--执行环绕增加 -->
            <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
            <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
        </aop:config>
    
    </beans>
    
  4. test

    public class MyTest {
          
          
        public static void main(String[] args) {
          
          
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserService userService = (UserService) context.getBean("userService");
            userService.add();
        }
    }
    

The execution() expression can be divided into five parts

  1. execution(): expression body.
  2. The first ***** number: indicates the return type, and the ***** number indicates all types.
  3. Package name: Indicates the name of the package that needs to be intercepted. The two periods after it respectively indicate the methods of the current package and all sub-packages of the current package, the com.sample.service.impl package, and the descendant packages of all classes.
  4. The second ***** sign: represents the class name, and the * sign represents all classes.
  5. *****(…): The third asterisk represents the method name, the ***** symbol represents all methods, the following brackets represent the parameters of the method, and the two periods represent any parameters.
11.3.2. Method 2:

Customize classes to implement AOP [aspect definition]

  1. Define your own DiyPointCut cut-in class under the diy package

    public class DiyPointCut {
          
          
        public void before(){
          
          
            System.out.println("=======方法执行前========");
        }
        public void after(){
          
          
            System.out.println("======方法执行后=====");
        }
    }
    
  2. Go to the configuration file in spring

    <!--方式二:自定义类    -->
    <bean id="diy" class="com.hwt.diy.DiyPointCut"/>
    <aop:config>
        <!--自定义切面, ref要引用的类-->
        <aop:aspect ref="diy">
            <!--切入点 -->
            <aop:pointcut id="point" expression="execution(* com.hwt.service.UserServiceImpl.*(..))"/>
            <!--通知-->
            <aop:before method="before" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>
    
  3. test

    public class DiyPointCut {
          
          
        public void before(){
          
          
            System.out.println("=======方法执行前========");
        }
        public void after(){
          
          
            System.out.println("======方法执行后=====");
        }
    }
    
11.3.3. Method three:

Annotation implementation

  1. Define the directly implemented AnnotationPointCut enhanced class

    @Aspect//标注这个类是一个切面
    public class AnnotationPointCut {
          
          
        @Before("execution(* com.hwt.service.UserServiceImpl.*(..))")
        public void before(){
          
          
            System.out.println("=======方法执行前========");
        }
        @After("execution(* com.hwt.service.UserServiceImpl.*(..))")
        public void after(){
          
          
            System.out.println("======方法执行后=====11");
        }
        //在环绕增强中可以给定一个参数,代表我们要获取处理切入的点
        @Around("execution(* com.hwt.service.UserServiceImpl.*(..))")
        public void around(ProceedingJoinPoint jp) throws Throwable {
          
          
            System.out.println("环绕前");
            Signature signature = jp.getSignature();//获得签名
            System.out.println(signature);
            Object o = jp.proceed();
            System.out.println("环绕后");
        }
    }
    
  2. In the spring configuration file, register the bean and add configuration that supports annotations

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

12、MyBatis

12.1. Mybatis test

step:

  1. Import related jar packages

    • Junit

    • my shoe

    • MySQL

    • spring related

    • aop weaver

    • mybatis-spring integration package [Key point] Import the lombok package again

    • Configuring maven static resource filtering problem!

Jar packages used:

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.28</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.13</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.2</version>
    </dependency>
</dependencies>
  1. Write entity class

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Alias("user")
    public class User {
          
          
        private int id;
        private String name;
        private String pwd;
    }
    
  2. Write core configuration file

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "https://mybatis.org/dtd/mybatis-3-config.dtd">
    <!--configuration核心配置文件-->
    <configuration>
        <typeAliases>
            <typeAlias type="com.hwt.pojo.User"/>
        </typeAliases>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.cj.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="root"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper class="com.hwt.dao.UserMapper"/>
        </mappers>
    </configuration>
    
  3. Write interface

    public interface UserMapper {
          
          
        public List<User> slelctUser();
    }
    
  4. Write Mapper.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.hwt.dao.UserMapper">
    
        <select id="slelctUser" resultType="com.hwt.pojo.User">
            select * from user;
        </select>
    
    </mapper>
    
  5. test

    public class Mytext {
          
          
        @Test
        public void test() throws IOException {
          
          
            String resourcse = "mybatis-config.xml";
            InputStream in = Resources.getResourceAsStream(resourcse);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
    
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> userList = mapper.slelctUser();
            for (User user : userList) {
          
          
                System.out.println(user);
            }
        }
    }
    

12.2、MyBatis-spring

What is mybatis-spring

mybatis-spring will help you seamlessly integrate mybatis code into spring.

Document link: http://mybatis.org/spring/zh/getting-started.html

Implementation method one:

If you use Maven as the build tool, you only need to add the following code to pom.xml:

    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.2</version>
    </dependency>
  1. Introduce the spring configuration file 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">
        
    </beans>
    
  2. Configure the data source to replace the data source of the configuration file mybatis

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "https://mybatis.org/dtd/mybatis-3-config.dtd">
    <!--configuration核心配置文件-->
    <configuration>
    <!--    起别名-->
        <typeAliases>
            <typeAlias type="com.hwt.pojo.User"/>
        </typeAliases>
    
    <!--设置-->
    <!--    <settings>-->
    <!--        <setting name="" value=""/>-->
    <!--    </settings>-->
    
    </configuration>
    
  3. Configure SQLSessionFactory and associate it with mybatis

     <!--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 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="root"/>
     </bean>
    
     <!--配置SQLSessionFactory,关联mybatis-->
    
     <!--配置SQLSessionFactory-->
     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
         <property name="dataSource" ref="datasource"/>
    
         <!--关联mybatis-->
         <property name="configLocation" value="classpath:mybatis-config.xml"/>
         <property name="mapperLocations" value="classpath:com/hwt/dao/*.xml"/>
     </bean>
    
  4. Register sqlsessionTemplate and associate SQLSessionFactory

    <!--注册sqlsessionTemplate,关联SQLSessionFactory-->
    <!--sqlsessionTemplate:也就是之前我们用的SQLSession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!--注册sqlsessionTemplate,关联SQLSessionFactory 没有set方法-->
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>
    
  5. Requires UserMapperImpl implementation class of UserMapper interface, privatized sqlsessionTemplate

    //给接口添加实现类
    public class UserMapperImpl implements UserMapper{
          
          
        //原来所有操作,都是使用sqlSession来执行,现在使用sqlSessionTemplate
        private SqlSessionTemplate sqlSession;
    
        public void setSqlSession(SqlSessionTemplate sqlSession) {
          
          
            this.sqlSession= sqlSession;
        }
    
        @Override
        public List<User> slelctUser() {
          
          
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.slelctUser();
        }
    }
    
  6. Inject the implementation class you wrote into the spring configuration

    <bean id="userMapper" class="com.hwt.dao.UserMapperImpl">
        <property name="sqlSession" ref="sqlSession"/>
    </bean>
    
  7. test

    @Test
    public void test2(){
          
          
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");
        UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
        List<User> userList = userMapper.slelctUser();
        for (User user : userList) {
          
          
            System.out.println(user);
        }
    }
    
Implementation method two:
  1. Modify the UserMapperImpl written above

    //给接口添加实现类
    public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
          
          
    
    
        @Override
        public List<User> slelctUser() {
          
          
            return getSqlSession().getMapper(UserMapper.class).slelctUser();
        }
    
    }
    
  2. Entity classes are injected into Spring configuration files.

    <bean id="userMapper2" class="com.hwt.dao.UserMapperImpl2">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
    
  3. Test: Remember to modify the spring configuration file name

    @Test
    public void test3() throws IOException {
          
          
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper mapper = (UserMapper) context.getBean("userMapper2");
        for (User user : mapper.slelctUser()) {
          
          
            System.out.println(user);
        }
    }
    

13. Declarative transactions

13.1. Review affairs

  • Treat a group of businesses as one business, either all succeed at the same time, or all fail at the same time;
  • Transactions are very important in project development, and cannot be careless when it comes to data consistency issues;
  • Ensure completeness and consistency

ACID principles for transactions:

  • Atomicity : Transactions are atomic operations that either complete all at the same time or have no effect at all.
  • **Consistency:** Once all transaction actions are completed, the transaction will be submitted, and the data and resources are in a consistent state that meets the business specifications. The integrity of the data remains unchanged before and after the transaction is submitted.
  • **Isolation:** Multiple transactions process the same data at the same time. Each transaction should be isolated from other transactions to prevent data corruption.
  • **Persistence:** Once the transaction is completed, no matter what errors occur in the system, the results will not be affected. Normally, once the transaction is committed, it will be persisted to the database.

Test without using transactions:

  1. In the previous case, we added two methods to the userMapper interface, deleting and adding users;

    //添加一个用户
    int addUser(User user);
    
    //根据id删除用户
    int deleteUser(int id);
    
  2. UserMapper file, we deliberately wrote deletes wrong, test!

    <insert id="addUser" parameterType="user">
        insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
    </insert>
    
    <delete id="deleteUser" parameterType="int">
        deletes from user where id = #{id}
    </delete>
    
  3. Write an interface practice class and call add and SQL problematic delete respectively in the query.

    //给接口添加实现类
    public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
          
          
    
    
        //增加一些操作
        public List<User> slelctUser() {
          
          
            User user = new User(6, "小王", "185161");
            UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
            mapper.addUser(user);
            mapper.deleteUser(5);
    
            return mapper.slelctUser();
        }
    
        //新增
        public int addUser(User user) {
          
          
            return getSqlSession().getMapper(UserMapper.class).addUser(user);
        }
    
        //删除
        public int deleteUser(int id) {
          
          
            return getSqlSession().getMapper(UserMapper.class).deleteUser(id);
        }
    }
    
  4. test

    public class MyTest {
          
          
        public static void main(String[] args) {
          
          
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
            List<User> userList = userMapper.slelctUser();
            for (User user : userList) {
          
          
                System.out.println(user);
            }
        }
    }
    

Insert image description here

Through testing, it was found that the SQL error was reported: prompting that delete was written incorrectly.

But refreshing the database found that the database insertion was successful!

There is no management of affairs; we want them all to succeed before they succeed. If one fails, they all fail, so we should need affairs!

In the past, we had to manage things manually, which was very troublesome!

But Spring provides us with transaction management, we only need to configure it;

13.2. Transaction management in Spring

Spring defines an abstraction layer on top of different transaction management APIs, so developers can use spring's transaction management mechanism without knowing the underlying transaction management API. Spring supports programmatic transaction management and declarative transaction management

Programmatic transaction management

  • Embed transaction management code into business methods to control transaction commit and rollback
  • Disadvantage: Additional transaction management code must be included in the operational business logic of each transaction

Declarative Transaction Management (AOP)

  • Generally easier to use than programmatic transaction management
  • Separate transaction management code from business methods and implement transaction management in a declarative manner
  • Treat transaction management as a cross-cutting concern and modularize it through AOP methods. Spring supports declarative transaction management through the spring aop framework

Spring transaction propagation properties (Propagation):

  1. REQUIRED (default property)

    If a transaction exists, the current transaction is supported. If there is no transaction, start a new transaction. When set to this level, a logical transaction domain is created for each method called. If the previous method has created a transaction, the later method supports the current transaction. If there is no current transaction, the transaction will be re-established.

  2. MANDATORY

​ Supports current transactions. If there is no current transaction, an exception will be thrown.

  1. NEVER
    executes in a non-transactional manner and throws an exception if a transaction currently exists.

  2. NOT_SUPPORTED
    performs operations in a non-transactional manner. If a transaction currently exists, the current transaction is suspended.

  3. REQUIRES_NEW
    creates a new transaction. If a transaction currently exists, suspend the current transaction.

  4. SUPPORTS
    supports the current transaction. If there is no current transaction, it will be executed in a non-transactional manner.

  5. NESTED
    supports the current transaction, adds Savepoint, and commits or rolls back synchronously with the current transaction. A very important concept of nested transactions is that the inner transaction depends on the outer transaction. When the outer transaction fails, the actions performed by the inner transaction will be rolled back. The failure of the inner transaction operation will not cause the outer transaction to be rolled back.

  6. Use spring management practices, pay attention to the constraint import of the header file: tx

    <?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"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           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
            http://www.springframework.org/schema/aop
            https://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx
            https://www.springframework.org/schema/tx/spring-tx.xsd">
    
  7. JDBC transactions

    <!--    配置声明式事务-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="datasource"/>
        </bean>
    
  8. Configure declarative transactions

    <!--结合AOP实现事务的织入-->
    <!--配置事务通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!--给那些方法配置事务-->
        <!--配置事务的传播特性: new -->
        <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>
    
  9. Configure transaction entry

    <!--配置事务切入-->
    <aop:config>
        <aop:pointcut id="txPointCut" expression="execution(* com.hwt.dao.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>
    

Why do we need transactions?

  • If transactions are not configured, data submission may be inconsistent.
  • If we don't configure declarative transactions in spring, we need to manually configure transactions in code
  • Transactions are very important in project development and involve issues of data consistency and integrity.

Guess you like

Origin blog.csdn.net/qq_44624801/article/details/129158995