Learning log (November 8, 2021) (1. Springboot integrates Junit, Mybatis, Redis and thymeleaf)

Learning content: learn SpringBoot (Day67)

1. Spring boot integrates Junit
2. Spring boot integrates Mybatis
3. Spring boot integrates Redis
4. Spring boot integrates thymeleaf

1. Spring boot integrates Junit

(1) The new version integrates Junit5 by default

<!--introduce test Scene launcher for-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
</dependency>

Import junit4 dependent package

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <scope>test</scope>
</dependency>

Add test related annotations, @ SpringBootTest(classes = startup class. class), @ RunWith(SpringRunner.class)

@SpringBootTest(classes = Main.class)
@RunWith(SpringRunner.class)
public class SpringBootApplicationTest {
    @Test
    public void ValueTest2(){
        System.out.println("Hello");
    }
}

2. Spring boot integrates Mybatis

(1) Add the dependency package of mybatis integration springboot

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>
<!--Mysql drive-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

(2) Configure the data source and Mybatis in the application.properties file

#data source
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root

#Mybatis
#Alias
mybatis.type-aliases-package=com.hisoft.pojo
#Configure and load the mapper.xml file
mybatis.mapperLocations=classpath:mapper/*.xml
#Turn on hump matching
mybatis.configuration.map-underscore-to-camel-case=true

(3) Configure scan package in startup class

/**
 * Specify the package to be scanned, and all classes marked @ Component under the specified package will be automatically scanned and registered as bean s,
 * Of course, it includes the sub annotations @ Service,@Repository,@Controller under @ Component.
*/
@SpringBootApplication(scanBasePackages = {"com.hisoft.*"})
@MapperScan("com.hisoft.mapper")//Scan the Mapper interface. If there is @ Mapper annotation on the Mapper interface, you don't need to add it
public class SpringBootMybatisApplication {

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

(4) Code implementation
pojo class

@Data
public class User {
    private Long id;
    private String userName;
    private String sex;
}

Mapper interface

@Mapper
public interface UserMapper {
    User queryById(Long id);

    List<User> ueryUserAll();

}

Mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hisoft.mapper.UserMapper">

    <!-- according to id Make a query -->
    <select id="queryById" resultType="User">
        select * from tb_user where id = #{id}
    </select>

    <!-- Query all -->
    <select id="ueryUserAll" resultType="User">
        select * from tb_user
    </select>
</mapper>

Service layer

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public List<User> queryUserAll() {
        return this.userMapper.ueryUserAll();
    }

}

Controller layer

@RestController
public class UserController {
    //Inject service
    @Autowired
    private UserService userService;
    @GetMapping("/queryall")
    public List<User> queryUserAll(){
        return this.userService.queryUserAll();
    }

}

3. Spring boot integrates Redis

(1) Add redis start dependency

<!--Redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

(2) Configure Redis in yml

spring:   
  redis:    
    #Database index    
    database: 0    
    host: 192.168.7.5    
    port: 6379    
    password: 123456   
    jedis:      
      pool:        
        #maximum connection        
        max-active: 8        
        #Maximum blocking waiting time (negative number indicates no limit)        
        max-wait: -1        
        #Maximum idle        
        max-idle: 8        
        #Minimum idle        
        min-idle: 0    
        #Connection timeout    
        timeout: 10000

(3) Redis template configuration, rewrite the serialization of key and value, otherwise the object cannot be stored in RedisTemplate
Create RedisConfig class and configure RedisTemplate

//Redis template configuration, rewrite the serialization of key and value, otherwise the object cannot be stored in RedisTemplate
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // Configure redisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);//
        RedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer); // key serialization
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); // value serialization
        redisTemplate.setHashKeySerializer(stringSerializer); // Hash key serialization
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); // Hash value serialization
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

}

(4) Create RedisService class and set the method of storing data and value in cache

@Service
public class RedisService {
    @Resource
    private RedisTemplate redisTemplate;

    /**
     * Save data
     * @param key
     * @param obj
     * @param timeout
     */
    public void setObj(final String key, Object obj, long timeout) {
        //Storage key, value, timeout time and timeout time. Because the memory space is limited, the timeout time needs to be set
        redisTemplate.opsForValue().set(key, obj, timeout, TimeUnit.SECONDS);
    }

    /**
     * Value
     * @param key
     * @return
     */
    public Object getObj(final String key) {
        Object o = redisTemplate.opsForValue().get(key);
        return o;
    }
}

(5) service and controller call instances

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisService redisService;

    /**
     *First check from the redis cache, and then from mysql
     * @param id
     * @return
     */
    public User queryById(Long id){
        User user = (User) redisService.getObj("user" + id);
        if (user == null){
            user = userMapper.queryById(id);
            redisService.setObj("user" + id,user,60*5);
        }
        return user;
    }
@RestController
public class UserController {
    //Inject service
    @Autowired
    private UserService userService;
     /*
     * Query by id
     */
    @GetMapping("/queryId/{id}")
    public User queryById(@PathVariable Long id) {
        return this.userService.queryById(id);
    }

}

4. Spring boot integrates thymeleaf

(1) Thymeleaf is a template engine similar to Velocity and FreeMarker, which can completely replace JSP. Compared with other template engines, it has the following three extremely attractive features.
1.Thymeleaf can run in both network and non network environments, that is, it allows artists to view the static effect of the page in the browser and programmers to view the dynamic page effect with data in the server. This is because it supports html prototypes, and then adds additional attributes in html tags to achieve the presentation of template + data. When the browser interprets html, it ignores undefined tag attributes, so the thymeleaf template can run statically; When data is returned to the page, the thymeleaf tag will dynamically replace the static content to make the page display dynamically.
2. Out of the box features of thymeleaf. It provides two dialects: standard and Spring standard. You can directly apply templates to achieve the effect of JSTL and OGNL expressions, so as to avoid the trouble of setting templates, changing JSTL and changing labels every day. At the same time, developers can also extend and create custom dialects.
3.Thymeleaf provides Spring standard dialect and an optional module perfectly integrated with Spring MVC, which can quickly realize form binding, Attribute Editor, internationalization and other functions.

(2) If you want to publish modules in the form of Jar, try not to use JSP related knowledge, because there are some problems with JSP running on the embedded Servlet container (embedded Tomcat and Jetty do not support JSP running in the form of Jar, and underwork does not support JSP). Thymeleaf is recommended as a template engine in Spring Boot because thymeleaf provides perfect Spring MVC support.
Spring Boot provides a large number of template engines, including FreeMarker, Groovy, Mustache, Thymeleaf, Velocity and Beetl.

(3) Introduce Thymeleaf dependency

<!--thymeleaf starter-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

(4) Create thymeleaf template and create userInfo.html under resources/templates

<!doctype html>
<!--Note: Introduction thymeleaf Namespace for-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>User information</title>
</head>
<body>
<!--If hello SpringBoot If not, the hello thymeleaf-->
<p th:text="'hello SpringBoot'">hello thymeleaf</p>
<p th:text="${user.id}"></p>
<p th:text="${user.userName}"></p>
<p th:text="${user.birthday}"></p>
</body>
</html>

(5) Relevant global configuration of thymeleaf

spring:
  thymeleaf:
    enabled: true  #Open thymeleaf view resolution
    ncoding: utf-8  #code
    prefix: classpath:/templates/  #prefix
    cache: false  #Use cache
    mode: HTML  #Strict HTML syntax pattern
    suffix: .html  #Suffix

(6) controller class

/*
 * Query by id
 */
@GetMapping("/queryId/{id}")
public String queryById(@PathVariable Long id, Model model) {
    User user = userService.queryById(id);
    model.addAttribute("user",user);
    return "userInfo";
}

(7) thymeleaf common tags
1.th:text is used for text display and simple calculation. If the value of th:text = is not displayed properly, the contents of the label are displayed.

<p th:text="${user.userName}">unknown</p>
<td th:text="9+7">2018</td>

2.th:utext is used for text replacement of html. The difference from th:text is that it can identify labels. It is often used to display the edited content of rich text editor on the foreground page. When the user.userName value is < h1 > Zhang San < / h1 >, Zhang San in h1 format is displayed.

<p th:utext="${user.userName}">unknown</p>

3.th:if is used to judge conditions. It can also be used for multiple conditions and, or (binary operator),!, not (unary operator).
If the user object is empty, it will not be displayed. If it is not empty, show will be displayed.

<div th:if="${user} !=null and ${otherUser} != null">show</div>

The operator can also be written in ${}. The operator is placed inside {}. At this time, the expression in the whole {} is calculated by ognl/spel engine; If the operator is placed outside, then the thymeleaf engine is responsible for the calculation.

<div th:if="${user.number >100}">show</div>

4.th:unless is used to judge conditions, which is opposite to th:if. If the user object is not empty, it will not be displayed. If it is empty, show will be displayed.

<div th:unless="${user} !=null">show</div>

5.th:switch th:case is used for multiple judgments of the same level and the same purpose, and one of them can be used. If the value in ${user.name} is maliming, first is displayed, and if the value is ${otherUser.name}, second is displayed, otherwise it is not displayed.

<div th:switch="${user.name}">    
    <p th:case="maliming">first</p>
    <p th:case="${otherUser.name}">second</p>
</div>

6.th:action is used to define the path of the background controller and the submission address of the form, which is equivalent to the action attribute of the < form > tag.
th:action = "@{}" can automatically add the configured context path.

<form th:action="@{user/login}" method="post"></form>

7.th:each is used to traverse the objects in the collection, which is equivalent to the < C: foreach > tag in jstl. userStat is called a state variable. Its attributes include index: index of the current iteration object (calculated from 0), am ount: index of the current iteration object (calculated from 1), size: size of the iterated object, current: current iteration variable, even/odd: Boolean value, whether the current loop is even/odd (calculated from 0), first: Boolean value, whether the current loop is the first, last: Boolean value, Whether the current loop is the last.

<tr th:each="user,userStat:${userList}">         
    <td th:text="${user.name}"></td>
    <td th:text="userStat.index"></td>
</tr>

8.th:value is used for attribute assignment

<option th:value="${user.name}"></option>

9.th:src is used to reference static files, which need to be placed in the / resources/static path

<script type="text/javascript" th:src="@{/js/user.js}"></script>

(8) Transfer parameters
userList page

<!doctype html>
<!--Note: Introduction thymeleaf Namespace for-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>User list</title>
</head>
<body>
<table border="1px" width="500px">
    <tr>
        <th>Serial number</th>
        <th>id</th>
        <th>user name</th>
        <th>date of birth</th>
    </tr>
    <tr th:each="user,s:${userList}">
        <td th:text="${s.count}"></td>
        <td th:text="${user.id}"></td>
        <td th:text="${user.userName}"></td>
        <!--Change date format-->
        <td th:text="${#dates.format(user.birthday,'yyyy-MM-dd')}"></td>
        <!--Method 1: the request path is localhost:8080/queryId?id=1-->
        <td><a th:href="@{/queryId(id=${user.id})}">see</a></td>
        <!--Method 2: the request path is localhost:8080/queryId/1-->
        <!--<td><a th:href="@{/queryId/} + ${user.id}">see</a></td>-->
    </tr>
</table>
</body>
</html>

userInfo page

<!doctype html>
<!--Note: Introduction thymeleaf Namespace for-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>User information</title>
    <script type="text/javascript" th:src="@{/js/user.js}"></script>
</head>
<body>
<img th:src="@{/img/1.jpg}"/>
<p th:text="${user.id}"></p>
<p th:text="${user.userName}"></p>
<p th:text="${user.birthday}"></p>
</body>
</html>

controller layer

@Controller
public class UserController {
    //Inject service
    @Autowired
    private UserService userService;
      /*
     * Query by id
     */
    @GetMapping("/queryId")
    public String queryById(Long id, Model model) {
        User user = userService.queryById(id);
        model.addAttribute("user",user);
        return "userInfo";
    }

    @RequestMapping("user")
    public String userList(Model model){
        List<User> userList = userService.queryUserAll();
        model.addAttribute("userList",userList);
        return "userList";
    }
}

Keywords: Mybatis Redis Spring Boot

Added by suzzane2020 on Mon, 08 Nov 2021 17:16:35 +0200