SSM backend development minutes

Table of Contents

introduction

technology stack

Knowledge points

interface

Static class

accomplish

Spring

MyBatis

SpringMVC

SpringBoot

question


Introduction

Recently, I need to complete the development of the backend of a management system. During the summer training of my sophomore year, I learned the backend framework, including springBoot, mybatis, spring, springMVC, etc. However, the study period was very short. I only tested the simple examples in the teacher’s notes. The understanding of the Dao layer, Service layer, and Controller layer in the backend was not deep enough. This time, I used the actual project to test the previously learned backend knowledge. To consolidate and improve, the following is a review of the basics of each back-end framework. There may be inappropriate places. If some content is consistent with your question, but I didn’t explain it clearly, please leave a message and I will try my best to solve it for you. ,study together.

Technology stack

spring boot: focus on spring development and reduce configuration

mybatis: persistence layer, lightweight semi-automated ORM framework

springMVC: A lightweight web framework that implements MVC based on JAVA.

Knowledge Point

Interface

In JAVA, an interface is a public abstract class with only method characteristics and no method implementation. It can be implemented by multiple classes, and these implementations can have different behaviors. Provides a solution to JAVA’s inability to implement multiple inheritance. An interface can be implemented in multiple places

Static class

Static means static or global. What is modified by static can be a variable, a class or a block of code. There is no such thing as a global variable in Java. Member variables or member methods modified by static are independent of any object of the class. It does not depend on a specific instance of the class, is shared by all instances, and can be accessed when a class is created.

implementation

Spring

A lightweight control inversion and aspect-oriented programming framework.

Try the traditional way of implementing a simple function, create an interface for the function implementation in the Dao layer, then create an implementation class of the interface, and then create an interface in the Service layer and create its implementation class. When you need to use it, you need to instantiate the implementation class of the Service layer. When you need to perform another operation, you immediately need to instantiate another implementation class. This method is very cumbersome.

//implementation class of userDao
package dao.Impl;
import dao.userDao;
public class userDaoImpl implements userDao{
    @Override
    public void getUser() {
        System.out.println("Get user");
    }
}
// userDao interface
package dao;

public interface userDao {
    public void getUser();
}
//implementation class of userService
package service.Impl;

import dao.Impl.userDaoImpl;
import dao.userDao;
import service.userService;

public class userServiceImpl implements userService {
    private userDao userDao = new userDaoImpl();
    @Override
    public void getUser() {
        userDao.getUser();
    }
}
// userService interface
package service;

public interface userService {
    public void getUser();
}

If we try to leave an interface in the Service implementation class instead of specifically implementing a certain function, it will bring greater convenience.

//Set an interface in the service implementation class
package service.Impl;

import dao.Impl.userDaoImpl;
import dao.userDao;
import service.userService;

public class userServiceImpl implements userService {
// This method is overly coupled, use the set method to flow out an interface
// private userDao userDao = new userDaoImpl();
    private userDao userDao;

    public void setUserDao(userDao userDao){
        this.userDao = userDao;
    }
    @Override
    public void getUser() {
        userDao.getUser();
    }
}
// When a certain function needs to be used, directly pass the implementation class of the Dao layer into the interface set aside previously.
import dao.Impl.userDaoImpl;
import dao.Impl.userDaoMysqlImpl;
import service.Impl.userServiceImpl;
import service.userService;

public class Test {
    @org.junit.Test
    public void test(){
        //Execute userDaoMysqlImpl first
        userServiceImpl userService = new userServiceImpl();
        userService.setUserDao(new userDaoMysqlImpl());
        userService.getUser();

        // At this time, I want to perform another function
        userService.setUserDao(new userDaoImpl());
        userService.getUser();
    }
}

Through set injection, it effectively solves the problem that when using different functions of the data layer, new implementation classes of different data layers are needed in the Service layer. However, there is still a problem that as long as the data layer is used, a new implementation class must be added in the service layer. When the data layer changes, the service layer also needs to change accordingly, so the implementation class of the service-initiated new data layer is adjusted to provide the Service layer from the outside. This is the idea of Inversion of Control (IOC). Inversion of control creates and initializes the class objects of the Dao layer and the Service layer through a bean container. Although there are class objects of the Dao layer and the Service layer in the container, the program cannot be executed yet because the Service layer relies on the Dao layer to provide services. Therefore, it is necessary to establish a dependency relationship between the Service layer and the Dao layer in the bean container, which is dependency injection (DI).

//Add spring dependency
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>

//Write beans.xml file
<bean id="hello" class="pojo.Hello" >
    <property name="name" value="spring"/>
</bean>

// test
@org.junit.Test
public void test2(){
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

    Hello hello = (Hello) context.getBean("hello");

    System.out.println(hello.toString());

    hello.show();

}

Let’s use inversion of control and dependency injection at the same time

<!-- Dependency injection -->
        <bean id="userDao" class="dao.Impl.userDaoImpl"/>
<!-- Bind userDaoService to userDao -->
        <bean id="userDaoService" class="service.Impl.userServiceImpl">
            <property name="userDao" ref="userDao"/>
        </bean>
// userServiceImpl sets aside the interface implemented by the function
package service.Impl;

import dao.Impl.userDaoImpl;
import dao.userDao;
import service.userService;

public class userServiceImpl implements userService {
// This method is overly coupled, use the set method to flow out an interface
// private userDao userDao = new userDaoImpl();
    private userDao userDao;

    public void setUserDao(userDao userDao){
        this.userDao = userDao;
    }
    @Override
    public void getUser() {
        userDao.getUser();
    }
}
// test
    @org.junit.Test
    public void test3(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        userServiceImpl userService = (userServiceImpl)context.getBean("userDaoService");
        userService.getUser();
    }
MyBatis

Mybatis is a framework for the persistence layer. Recall that the traditional way of operating data is as follows: configuring the connection to the database, using SQL statements to perform specific operations, and encapsulating the results using objects to undertake. These operations all need to be completed manually. Mybatis can greatly simplify these operations. You can feel the convenience of mybatis through the following two pictures facing each other.

Write entity class

public class User {
    private long id;
    private String username;
    private String password;
    private String name;
    private String phone;
    private String head_url;
    private long dept_id;
    private long post_id;
    private String description;
    private int status;
    private Date create_time;
    private Date update_time;
    private int is_deleted;
    public User(){

    }
    public User(long id, String username, String password, String name, String phone, String head_url, long dept_id, long post_id, String description, int status, Date create_time, Date update_time, int is_deleted) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.name = name;
        this.phone = phone;
        this.head_url = head_url;
        this.dept_id = dept_id;
        this.post_id = post_id;
        this.description = description;
        this.status = status;
        this.create_time = create_time;
        this.update_time = update_time;
        this.is_deleted = is_deleted;
    }

    public long getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

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

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getHead_url() {
        return head_url;
    }

    public void setHead_url(String head_url) {
        this.head_url = head_url;
    }

    public long getDept_id() {
        return dept_id;
    }

    public void setDept_id(long dept_id) {
        this.dept_id = dept_id;
    }

    public long getPost_id() {
        return post_id;
    }

    public void setPost_id(long post_id) {
        this.post_id = post_id;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public Date getCreate_time() {
        return create_time;
    }

    public void setCreate_time(Date create_time) {
        this.create_time = create_time;
    }

    public Date getUpdate_time() {
        return update_time;
    }

    public void setUpdate_time(Date update_time) {
        this.update_time = update_time;
    }

    public int getIs_deleted() {
        return is_deleted;
    }

    public void setIs_deleted(int is_deleted) {
        this.is_deleted = is_deleted;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + ''' +
                ", password='" + password + ''' +
                ", name='" + name + ''' +
                ", phone='" + phone + ''' +
                ", head_url='" + head_url + ''' +
                ", dept_id=" + dept_id +
                ", post_id=" + post_id +
                ", description='" + description + ''' +
                ", status=" + status +
                ", create_time=" + create_time +
                ", update_time=" + update_time +
                ", is_deleted=" + is_deleted +
                '}';
    }
}

Write Dao interface

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

Write mapper specific implementation

<mapper namespace="dao.userDao">
    <select id="getUserList" resultType="pojo.User">
        select * from user;
    </select>
</mapper>

Register in the mybatis-config.xml core configuration file

 <mappers>
        <mapper resource="dao/mapper/userDaoMapper.xml"></mapper>
    </mappers>

Create a sqlSessionFacrory tool class

public class MybatisUtils {
    //Define a factory
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            // Use mybatis to get the sqlsessionFactory object
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

test

 public void test4(){
        // Get the sqlSession object
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //Execute sql
        userDao mapper = sqlSession.getMapper(userDao.class);
        List<User> userList = mapper.getUserList();
        userList.forEach(System.out::println);
        //Close sqlSession
        sqlSession.clearCache();
    }
SpringMVC

It cannot be started using the built-in tomcat, which will be solved later.

SpringBoot

Springboot requires only a minimal amount of configuration to run a web program.

<properties>
        <java.version>1.8</java.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
?
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
?
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

main boot

@SpringBootApplication
public class SpringBoot01Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringBoot01Application.class, args);
    }
}

Control class

@RestController // @Controller + @ResponseBody
@RequestMapping("/hello")
public class HelloController {

    @RequestMapping("/h1")
    public String hello(){
        return "Hello~ SpringBoor, it's really delicious when you use it";
    }


}

Question

1. Idea connects to the Alibaba Cloud MySQL database and uses idea to automatically download the database connection driver. The download fails. The host uses a proxy, but idea has not been set up, so it is still very slow. Use auto detect proxy to solve the problem. I guess after using this setting, idea will automatically look for the host’s proxy.

2. Idea uses kotlin, and the version of the delivered back-end code idea is version 23. The default kotlin is version 1.9x, and it is also set to 1.9 in maven. My idea is version 21, which supports up to version 1.6. I tried to lower the configuration of the kotlin version in maven, but found that it did not work. It showed that mybatis had dependencies on version 1.9 of kotlin, so I tried to install the idea23 version and installed it again. maven configuration. It may also be necessary to configure the idea agent. Although the maven warehouse of Alibaba Cloud is installed in maven, the speed is still very slow. After hanging for 2 hours, the download was finally completed.

3. Configure mybatis to appear:

(1) org.apache.ibatis.binding.BindingException: Type interface dao.userDao is not known to the MapperRegistry.

This problem occurs probably because userDaoMapper.xml is not registered in mybatis-config.xml

(2) Caused by: java.io.IOException: Could not find resource com/lxyk/dao/UserMapper.xml. This error is likely to have two reasons. One is that the path of the set Pojo class or Dao class is incorrect, and the other is One reason is that the following code is not added to pom.xml.

 <!--Configure resources in the build to prevent our resource export failure-->
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>

4. Use Spring Boot to start the simplest web. I have configured the startup class and the control class that needs to be accessed, but the Whitelabel Error Page keeps appearing. After checking the information, I found that the startup class and the control class are not in the same package. If @ComponentScan is not used, There will be a situation where the startup class cannot find the control class. The correct organization method is shown below. The two classes need to be under the same main package.

You can also use @ComponentScan(“control class path”) in the startup class

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 138132 people are learning the system