springboot relearning (week 2)

Spring boot integration persistence layer

Persistence layer is the core operation of accessing database in Java EE. Spring boot provides automatic configuration for common persistence layer frameworks, such as JDBC template, JPA, etc. MyBatis provides automatic configuration officially.

  1. Integrate JDBC template:
    JDBC tempalt is a set of JDBC template framework provided by springboot. It uses AOP technology to solve the problem of a large number of duplicate code when using JDBC directly. Although JdbcTemplate is not as flexible as MyBatis, single = is much more convenient than using JDBC directly. The use of JdbcTemplate in springboot provides the automatic configuration class of JdbcTemplateAutoConfiguration. The specific dao layer code is as follows:
    In the query operation, there needs to be a RowMapper to match the queried columns with the attributes in the entity class one by one. If the column name and the attribute name are the same, you can directly use the bean propertyrowmaper; if they are different, you need to implement the RowMapper interface yourself.
  2. Integrate MyBatis:
    MyBatis avoids almost all JDBC code manually setting parameters and getting result sets. In traditional SSM framework integration, MyBatis requires xml configuration with volume. In springboot, MyBatis officially provides a set of automatic configuration scheme, which can be used out of the box.
    Create Mapper class
    
    

@Mapper
public interface BookMapper {
int addBook(Book book);
int deleteBookById(Integer id);
int updateBookById(Book book);
Book getBookById(Integer id);
List getAllBooks();
}

Create in the same location mapper.xml

```java
<?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="org.sang.mapper.BookMapper">
    <insert id="addBook" parameterType="org.sang.model.Book">
    INSERT INTO book(name,author) VALUES (#{name},#{author})
    </insert>
    <delete id="deleteBookById" parameterType="int">
        DELETE FROM book WHERE id=#{id}
    </delete>
    <update id="updateBookById" parameterType="org.sang.model.Book">
        UPDATE book set name=#{name},author=#{author} WHERE id=#{id}
    </update>
    <select id="getBookById" parameterType="int" resultType="org.sang.model.Book">
        SELECT * FROM book WHERE id=#{id}
    </select>
    <select id="getAllBooks" resultType="org.sang.model.Book">
        SELECT * FROM book
    </select>
</mapper>

For each method in the mapper interface, the implementation is listed in mapper.xml. In Maven project, it is recommended to write the XML configuration file in the resource directory, but the mapper.xml above is written in the package, which will be ignored when Maven runs. Therefore, it is necessary to re indicate the location of the resource file in pom.xml.

  1. Integrating Spring Data JPA:
    As a java EE engineer, I have heard about hibernate framework. Hibernate is an ORM framework, while JPA is an ORM specification. The relationship between JPA and Hibernate is just like that between JDBC and jdbc driver, that is, JPA has formulated ORM specifications, and Hibernate is the implementation of these specifications (in fact, hibernate is the first one followed by JPA, and the drafter of JPA specification is also the author of Hibernate). Therefore, in terms of function, j PA is a subset of hibernate. We usually use JPA the most simple, so the frequency is relatively high, I just write a little code here to show.
public interface BookDao extends JpaRepository<Book,Integer>{
    List<Book> getBooksByAuthorStartingWith(String author);
    List<Book> getBooksByPriceGreaterThan(Float price);
    @Query(value = "select * from t_book where id=(select max(id) from t_book)",nativeQuery = true)
    Book getMaxIdBook();
    @Query("select b from t_book b where b.id>:id and b.author=:author")
    List<Book> getBookByIdAndAuthor(@Param("author") String author, @Param("id") Integer id);
    @Query("select b from t_book b where b.id<?2 and b.name like %?1%")
    List<Book> getBooksByIdAndName(String name, Integer id);
}

The established method naming rules do not necessarily meet all development requirements, so JPA also supports custom JPQL or native SQL.

Building RESTful services

REST is a style of Web software architecture. It is a style, not a standard. Network services that match or are compatible with this style of architecture become REST services. REST services are simple and hierarchical, and REST is usually based on HTTP,URI and XML, as well as HTML, which are widely popular protocols and standards. In REST, resources are defined by URIs. The operations of adding, deleting, modifying and querying resources can be realized through GET, POST, PUT, DELETE and other methods provided by HTTP protocol. Using REST can make more efficient use of cache to improve the response speed, while the communication call state in REST is maintained by the client, which enables different servers to handle different requests in a series of requests, thus improving the scalability of the server. In the project of front-end and back-end separation, a well-designed Web software architecture must meet the REST style.

Spring Boot cache

spring.31 starts to provide support for caching. The core idea is to cache methods. When a developer calls a method, the parameters and return values of the method are cached as key/value. When the method is called again, if there is data in the cache, it is directly retrieved from the cache. Otherwise, the method is executed. However, spring does not provide the implementation of cache, but provides a set of cache api. Developers can choose the implementation of cache freely. At present, the cache supported by spring boot is as follows:
<JCache,EhCache,Hazelcast,Infinispan,Couchbase,Redis,Caffenine,Simple>

Ehcache

Ecache cache has been well-known in java development field for a long time. Under springboot, only one configuration file is needed to integrate Ehcache into the project. General steps for using Ehcache 2.x.

<ehcache>
    <diskStore path="java.io.tmpdir/cache"/>
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
    />
    <cache name="book_cache"
           maxElementsInMemory="10000"
           eternal="true"
           timeToIdleSeconds="120"
           timeToLiveSeconds="120"
           overflowToDisk="true"
           diskPersistent="true"
           diskExpiryThreadIntervalSeconds="10"/>
</ehcache>

Create ehcache.xml file under resources directory as Ehcache cache configuration file.
Add @ EnableCaching to the entry class of the project

@Service
@CacheConfig(cacheNames = "book_cache")
public class BookDao {
    @Autowired
    MyKeyGenerator myKeyGenerator;
    @Cacheable(keyGenerator = "myKeyGenerator")
    public Book getBookById(Integer id) {
        System.out.println("getBookById");
        Book book = new Book();
        book.setId(id);
        book.setName("Romance of the Three Kingdoms");
        book.setAuthor("Luo Guanzhong");
        return book;
    }
    @CachePut(key = "#book.id")
    public Book updateBookById(Book book) {
        System.out.println("updateBookById");
        book.setName("Romance of the Three Kingdoms 2");
        return book;
    }
    @CacheEvict(key = "#id")
    public void deleteBookById(Integer id) {
        System.out.println("deleteBookById");
    }
}

Create BOOKDAO
If the developers think these keys can not meet the development requirements, they can customize the key generator of the cache key.

spring Boot security management

Generally, projects have strict authentication and authorization operations. The common security frameworks in the java development field are Shiro and spring security. Shiro is a lightweight security management framework, providing authentication, authorization, session management, password management, cache management and other functions. Spring security is a relatively complex security management framework, which has more powerful functions than Shiro, higher granularity of permission control, and more friendly support for OAuth2. Because spring security comes from the spring family, it can be seamlessly integrated with the spring framework, especially the automatic configuration scheme provided in Spring Boot, which can make the use of spring security more convenient.
spring security is widely used in project development. I will not show it here, but mainly show the usage of Shiro security framework that I haven't touched before.

Shiro integration

In the traditional ssm framework, there are many steps to manually integrate Shiro. For Spring Boot, Shiro officially provides Shiro Spring Boot web starter to simplify the configuration of Shiro in Spring Boot.

shiro.enabled=true
shiro.web.enabled=true
shiro.loginUrl=/login
shiro.successUrl=/index
shiro.unauthorizedUrl=/unauthorized
shiro.sessionManager.sessionIdUrlRewritingEnabled=true
shiro.sessionManager.sessionIdCookieEnabled=true

shiro's configuration
Next, configure two basic beans

@Configuration
public class ShiroConfig {
    @Bean
    public Realm realm() {
        TextConfigurationRealm realm = new TextConfigurationRealm();
        realm.setUserDefinitions("sang=123,user\n admin=123,admin");
        realm.setRoleDefinitions("admin=read,write\n user=read");
        return realm;
    }
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition =
                new DefaultShiroFilterChainDefinition();
        chainDefinition.addPathDefinition("/login", "anon");
        chainDefinition.addPathDefinition("/doLogin", "anon");
        chainDefinition.addPathDefinition("/logout", "logout");
        chainDefinition.addPathDefinition("/**", "authc");
        return chainDefinition;
    }
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }
}

The last Shiro dialect, if you don't use the tymeleaf template, you don't need to add this.

@Controller
public class UserController {
    @PostMapping("/doLogin")
    public String doLogin(String username, String password, Model model) {
        UsernamePasswordToken token =
                new UsernamePasswordToken(username, password);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
        } catch (AuthenticationException e) {
            model.addAttribute("error", "Wrong user name or password!");
            return "login";
        }
        return "redirect:/index";
    }
    @RequiresRoles("admin")
    @GetMapping("/admin")
    public String admin() {
        return "admin";
    }
    @RequiresRoles(value = {"admin","user"},logical = Logical.OR)
    @GetMapping("/user")
    public String user() {
        return "user";
    }
}

Configure controller
For other interfaces that can be accessed without roles, you can configure them directly in WebMvc.

@Configuration
public class WebMvcConfig implements WebMvcConfigurer{
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/index").setViewName("index");
        registry.addViewController("/unauthorized").setViewName("unauthorized");
    }
}

You can create a global exception handler, which mainly deals with authorization exceptions.

@ControllerAdvice
public class ExceptionController {
    @ExceptionHandler(AuthorizationException.class)
    public ModelAndView error(AuthorizationException e) {
        ModelAndView mv = new ModelAndView("unauthorized");
        mv.addObject("error", e.getMessage());
        return mv;
    }
}

spring integration of websocket and message service is under study
Published 9 original articles, won praise 1, visited 1056

Tags: Spring Shiro JDBC Mybatis

Posted on Wed, 05 Feb 2020 01:04:42 -0500 by fiddler80