Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

SpringBoot2.1.6 + Shiro1.4.1 + Thymeleaf + Jpa整合练习

搬块砖可以吗 2019-07-22 21:36:00 阅读数:115 评论数:0 点赞数:0 收藏数:0

  首先,添加maven依赖,完整的pom文件如下:

 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <version>2.1.6.RELEASE</version>
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
     <groupId>com.hui</groupId>
     <artifactId>SpringBoot22</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <name>SpringBoot22</name>
     <description>Demo project for Spring Boot</description>
 
     <properties>
         <java.version>1.8</java.version>
     </properties>
 
     <dependencies>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
 
         <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <scope>runtime</scope>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.shiro</groupId>
             <artifactId>shiro-spring</artifactId>
             <version>1.4.1</version>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-jpa</artifactId>
             <version>RELEASE</version>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-thymeleaf</artifactId>
             <version>RELEASE</version>
         </dependency>
     </dependencies>
 
     <build>
         <plugins>
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
 
 </project>

  接着,我们先编写自定义的Realm类(MyJbdcRealm)

 package com.hui.SpringBoot22.realm;
 
 import org.apache.shiro.authc.*;
 import org.apache.shiro.authz.AuthorizationException;
 import org.apache.shiro.authz.AuthorizationInfo;
 import org.apache.shiro.authz.SimpleAuthorizationInfo;
 import org.apache.shiro.realm.AuthorizingRealm;
 import org.apache.shiro.subject.PrincipalCollection;
 import org.apache.shiro.util.ByteSource;
 import org.apache.shiro.util.JdbcUtils;
 
 import javax.sql.DataSource;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.LinkedHashSet;
 import java.util.Set;
 
 public class MyJdbcRealm extends AuthorizingRealm {
 
     protected static final String DEFAULT_AUTHENTICATION_QUERY = "select password from users where username = ?";
     protected static final String DEFAULT_USER_ROLES_QUERY = "select role_name from user_roles where username = ?";
     protected static final String DEFAULT_PERMISSIONS_QUERY = "select permission from roles_permissions where role_name = ?";
     protected DataSource dataSource;
     protected String authenticationQuery = DEFAULT_AUTHENTICATION_QUERY;
     protected String userRolesQuery = DEFAULT_USER_ROLES_QUERY;
     protected String permissionsQuery = DEFAULT_PERMISSIONS_QUERY;
     protected boolean permissionsLookupEnabled = false;
 
     public void setDataSource(DataSource dataSource) {
         this.dataSource = dataSource;
     }
 
     public void setAuthenticationQuery(String authenticationQuery) {
         this.authenticationQuery = authenticationQuery;
     }
 
     public void setUserRolesQuery(String userRolesQuery) {
         this.userRolesQuery = userRolesQuery;
     }
 
     public void setPermissionsQuery(String permissionsQuery) {
         this.permissionsQuery = permissionsQuery;
     }
 
     public void setPermissionsLookupEnabled(boolean permissionsLookupEnabled) {
         this.permissionsLookupEnabled = permissionsLookupEnabled;
     }
 
     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
         UsernamePasswordToken upToken = (UsernamePasswordToken) token;
         String username = upToken.getUsername();
         if (username == null) {
             throw new AccountException("Null usernames are not allowed by this realm.");
         }
         Connection conn = null;
         SimpleAuthenticationInfo info = null;
         try {
             conn = dataSource.getConnection();
             String password = null;
             password = getPasswordForUser(conn, username);
             if (password == null) {
                 throw new UnknownAccountException("No account found for user [" + username + "]");
             }
             info = new SimpleAuthenticationInfo(username, password.toCharArray(), getName());
         } catch (SQLException e) {
             final String message = "There was a SQL error while authenticating user [" + username + "]";
             throw new AuthenticationException(message, e);
         } finally {
             JdbcUtils.closeConnection(conn);
         }
         return info;
     }
 
     private String getPasswordForUser(Connection conn, String username) throws SQLException {
         String result = null;
         PreparedStatement ps = null;
         ResultSet rs = null;
         try {
             ps = conn.prepareStatement(authenticationQuery);
             ps.setString(1, username);
             rs = ps.executeQuery();
             boolean foundResult = false;
             while (rs.next()) {
                 if (foundResult) {
                     throw new AuthenticationException("More than one user row found for user [" + username + "]. Usernames must be unique.");
                 }
                 result = rs.getString(1);
                 foundResult = true;
             }
         } finally {
             JdbcUtils.closeResultSet(rs);
             JdbcUtils.closeStatement(ps);
         }
         return result;
     }
 
     @Override
     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
         if (principals == null) {
             throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
         }
         String username = (String) getAvailablePrincipal(principals);
         Connection conn = null;
         Set<String> roleNames = null;
         Set<String> permissions = null;
         try {
             conn = dataSource.getConnection();
             roleNames = getRoleNamesForUser(conn, username);
             if (permissionsLookupEnabled) {
                 permissions = getPermissions(conn, username, roleNames);
             }
         } catch (SQLException e) {
             final String message = "There was a SQL error while authorizing user [" + username + "]";
             throw new AuthorizationException(message, e);
         } finally {
             JdbcUtils.closeConnection(conn);
         }
         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
         info.setStringPermissions(permissions);
         return info;
     }
 
     protected Set<String> getRoleNamesForUser(Connection conn, String username) throws SQLException {
         PreparedStatement ps = null;
         ResultSet rs = null;
         Set<String> roleNames = new LinkedHashSet<String>();
         try {
             ps = conn.prepareStatement(userRolesQuery);
             ps.setString(1, username);
             rs = ps.executeQuery();
             while (rs.next()) {
                 String roleName = rs.getString(1);
                 if (roleName != null) {
                     roleNames.add(roleName);
                 }
             }
         } finally {
             JdbcUtils.closeResultSet(rs);
             JdbcUtils.closeStatement(ps);
         }
         return roleNames;
     }
 
     protected Set<String> getPermissions(Connection conn, String username, Collection<String> roleNames) throws SQLException {
         PreparedStatement ps = null;
         Set<String> permissions = new LinkedHashSet<String>();
         try {
             ps = conn.prepareStatement(permissionsQuery);
             for (String roleName : roleNames) {
                 ps.setString(1, roleName);
                 ResultSet rs = null;
                 try {
                     rs = ps.executeQuery();
                     while (rs.next()) {
                         String permissionString = rs.getString(1);
                         String[] permissionNames = permissionString.split(",");
                         permissions.addAll(Arrays.asList(permissionNames));
                     }
                 } finally {
                     JdbcUtils.closeResultSet(rs);
                 }
             }
         } finally {
             JdbcUtils.closeStatement(ps);
         }
         return permissions;
     }
 }

MyJdbcRealm类就是从shiro中原有的JdbcRealm类copy来的,去掉了与密码盐(salt)有关的部分。

我在数据库的权限表中添加的权限字段值为 “user:add,user:delete,user:update,user:select,user:updateRole” 的格式,而shiro中原有的JdbcRealm中会将这一长串当成一种权限来看,在 MyJdbcRealm 类中改写了 JdbcRealm中的 getPermissions(Connection conn, String username, Collection<String> roleNames) 方法(具体看159-161行)来使权限字段的值为 5种 不同的权限。

    当然,你也可以在自定义的 Realm 类中重写 doGetAuthorizationInfo(PrincipalCollection principals) 方法,来实现自己的权限管理。

 

  接着,编写shiro的配置类(ShiroConfiguration)

 

 package com.hui.SpringBoot22;
 
 import com.hui.SpringBoot22.realm.MyJdbcRealm;
 import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
 import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
 import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
 import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
 
 import javax.sql.DataSource;
 import java.util.*;
 
 @Configuration
 public class ShiroConfiguration {
 
     @Autowired
     private DataSource dataSource;
 
     @Bean(name = "shiroFilter")
     public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager){
         ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
         shiroFilterFactoryBean.setSecurityManager(securityManager);
         //配置login页、登陆成功页、没有权限页
         shiroFilterFactoryBean.setLoginUrl("/");
         shiroFilterFactoryBean.setSuccessUrl("/index");
         shiroFilterFactoryBean.setUnauthorizedUrl("/403");
 
         //配置访问权限(顺序执行拦截)
         //   “/**” 放到最下面,如果将("/**","authc")放到("/userLogin","anon")的上面
         //          则“/userLogin”可能会被拦截
         Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();
         filterChainDefinitionMap.put("/logout","logout");
         filterChainDefinitionMap.put("/userLogin","anon");
         filterChainDefinitionMap.put("/403","roles");
         filterChainDefinitionMap.put("/**","authc");
         shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
         return shiroFilterFactoryBean;
     }
 
     @Bean(name = "securityManager")
     public SecurityManager securityManager(@Qualifier("myJdbcRealm")MyJdbcRealm myJdbcRealm){
         DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
         securityManager.setRealm(myJdbcRealm);
         return securityManager;
     }
 
     @Bean(name = "myJdbcRealm")
     public MyJdbcRealm myJdbcRealm(@Qualifier("credentialsMatcher") HashedCredentialsMatcher credentialsMatcher,
                                  @Qualifier("dataSource") DataSource dataSource){
         MyJdbcRealm myJdbcRealm = new MyJdbcRealm();
         //打开shiro的权限  (默认为false)  (不开启则不会检查权限 --> 点击“修改”,不管有没有权限都能进行跳转)
         myJdbcRealm.setPermissionsLookupEnabled(true);
         //设置datasource
         myJdbcRealm.setDataSource(dataSource);
         //设置密码加密器
         myJdbcRealm.setCredentialsMatcher(credentialsMatcher);
         //设置登陆验证sql语句
         String sql = "select password from test_user where username = ?";
         myJdbcRealm.setAuthenticationQuery(sql);
         //设置权限验证sql语句
         String permissionSql = "select permission from permissions where role_name = ?";
         myJdbcRealm.setPermissionsQuery(permissionSql);
         return myJdbcRealm;
     }
 
     //设置加密算法为MD5。加密次数为1
     @Bean(name = "credentialsMatcher")
     public HashedCredentialsMatcher credentialsMatcher(){
         HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
         credentialsMatcher.setHashAlgorithmName("md5");
         credentialsMatcher.setHashIterations(1);
         return credentialsMatcher;
     }
 
     /**
      * 开启aop注解支持 -- 借助SpringAOP扫描使用shiro注解的类
      *      (不开启则不能扫描到shiro的@RequiresPermissions等注解)
      * @param securityManager
      * @return
      */
     @Bean
     public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
         AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
         authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
         return authorizationAttributeSourceAdvisor;
     }
 
     //配置无权限异常处理,跳转到403
     @Bean(name="simpleMappingExceptionResolver")
     public SimpleMappingExceptionResolver
     createSimpleMappingExceptionResolver() {
         SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
         Properties mappings = new Properties();
         mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
         mappings.setProperty("UnauthorizedException", "403");
         r.setExceptionMappings(mappings);  // None by default
         r.setDefaultErrorView("error");    // No default
         r.setExceptionAttribute("ex");     // Default is "exception"
         return r;
     }
 
 }

 

  上面代码中有几个需要注意的点:

第一点:是再定义的名为“securityManager”的 Bean 中,使用的是 DefaultWebSecurityManager 这个类,而不是 DefaultSecurityManager(使用DefaultSecurityManager类会报错),前者是 org.apache.shiro.web.mgt 包下的,与web有关;后者是 org.apache.shiro.mgt 包下的。

第二点:开启aop注解支持 -- 借助SpringAOP扫描使用shiro注解的类,开启之后可以扫描到 Controller 类上的shiro注解(例如:@RequiresPermissions、@RequiresRoles等

第三点:配置无权限异常处理,这样就会拦截到没有权限的用户,然后跳转到403页面(

  这里配置无权限异常处理是为了配合shiro注解。

  如果不想使用shiro注解,也可以不配置该异常处理,直接在拦截链“filterChainDefinitionMap”中配置 -- 例如:/userList= roles["admin","admin1"] --> 表明访问路径 /userList 需要同时具备“admin”和“admin1”的角色,不合条件则403;             另一种与角色拦截相似:权限拦截 -- /userList= perms["user:select"]

第四点:在名为 “myJdbcRealm” Bean中,设置登陆验证与权限验证的sql查询语句,方法分别是 setAuthenticationQuery("select password from test_user where username = ?") 、 setPermissionsQuery("select permission from permissions where role_name = ?")  

之所以执行这两个setXxx()方法,是因为我这里的实体类对应生成的表名、字段名与shiro默认的不一致(如果你想使用shiro默认的,那么你就需要按照shiro源码中的sql语句来设置实体生成的表名、字段名与shiro默认的一致即可)

 

  接下来,编写实体类

User类

 package com.hui.SpringBoot22.pojo;
 
 import javax.persistence.*;
 
 @Entity
 @Table(name = "test_user")
 public class User {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)//默认为AUTO,这里设置为自增
     private Long id;
     @Column(name = "username",length = 50)
     private String username;
     @Column(name = "password",length = 50)
     private String password;
 
     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;
     }
 }

 

Role类

 package com.hui.SpringBoot22.pojo;
 
 import javax.persistence.*;
 
 @Entity
 @Table(name = "user_roles")
 public class Role {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
     @Column(name = "username",length = 50)
     private String username;
     @Column(name = "role_name",length = 50)
     private String roles;
 
     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 getRoles() {
         return roles;
     }
 
     public void setRoles(String roles) {
         this.roles = roles;
     }
 }
Permission类
 package com.hui.SpringBoot22.pojo;
 
 import javax.persistence.*;
 
 @Entity
 @Table(name = "permissions")
 public class Permission {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
     @Column(name = "role_name",length = 50)
     private String roleName;
     @Column(name = "permission",length = 120)
     private String permissions;
 
     public Long getId() {
         return id;
     }
 
     public void setId(Long id) {
         this.id = id;
     }
 
     public String getRoleName() {
         return roleName;
     }
 
     public void setRoleName(String roleName) {
         this.roleName = roleName;
     }
 
     public String getPermissions() {
         return permissions;
     }
 
     public void setPermissions(String permissions) {
         this.permissions = permissions;
     }
 }

这里就不多说了,主要注意的就是对应的表名、字段名要与 ShiroConfiguration 类中的sql语句的表名、字段名一致。

 

  接下来是Repository编写,直接看代码好了

 

 package com.hui.SpringBoot22.repository;
 
 import com.hui.SpringBoot22.pojo.User;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 
 import javax.transaction.Transactional;
 
 public interface UserRepository extends JpaRepository<User,Long> {
     User findUserById(Long id);
 
     @Transactional
     @Modifying
     @Query("update User set username=?2,password=?3 where id=?1")
     int updateUserById(Long id,String username,String password);
 
     @Transactional
     @Modifying
     @Query("delete from User where id=?1")
     void deleteUserById(Long id);
 }

 

这里继承了JpaRepository类,就不用再类上加Spring注解来将其注入(因为 JpaRepository 类上有一个@NoRepositoryBean注解,原理咱不懂!!!

select、delete之类的语句 Jpa 已经封装了一部分方法,我们可以直接调用,如 save(S entity)、delete(T entity)等

如果Jpa中封装的不能满足需求,那就自己写啦

  像上面的在 UserRepository 类中添加一个方法,然后再方法上加上@Query注解,里面有个value属性,用来指定编写的sql语句  -->  如:@Query(value="update ...")

值得注意的是,在 @Query 注解中的 sql 语句对应的表名应写 实体类名(上面代码中本人写的就是实体类 User );关于sql中的字段是不是需要用实体类属性名,有兴趣的朋友可以自己试一下。

如果觉得别扭,可以在@Query注解中编写 nativeQuery 属性,使其值为 true ,这样 Jpa 就能识别原生 sql 了   -->    

例子:  @Query(nativeQuery = true,
   value="select r.id,r.username,r.role_name from user_roles u left join user_roles r on u.username=r.username where u.id=?1")
     Role findRoleByUserid(Long id);

 

最后,如果是insert、delete、update之类的语句,还要在方法上面加上@Modifying和@Transactional注解等大佬帮我解惑ing...

 

  接着,再贴一下 controller 的代码

 

 package com.hui.SpringBoot22.controller;
 
 import com.hui.SpringBoot22.pojo.User;
 import com.hui.SpringBoot22.repository.UserRepository;
 import com.hui.SpringBoot22.utils.Md5;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authc.UsernamePasswordToken;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.apache.shiro.subject.Subject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import java.util.List;
 import java.util.Map;
 
 @Controller
 public class UserController {
     @Autowired
     private UserRepository userRepository;
 
     @RequestMapping("/")
     public String toLogin(){
         return "login";
     }
 
     @RequestMapping("/userLogin")
     public String userLogin(String username, String password, Map<String,Object> map){
         Subject subject = SecurityUtils.getSubject();
         UsernamePasswordToken token = new UsernamePasswordToken(username,password);
         try{
             subject.login(token);
             map.put("loginName",username);
         }catch(Exception e){
             map.put("msg","登陆失败");
             return "login";
         }
         return "forward:userList";
     }
 
     @RequestMapping("/userList")
     @RequiresPermissions("user:select")
     public String list(Map<String,Object> map){
         List<User> users = userRepository.findAll();
         map.put("userList",users);
         return "userList";
     }
 
     @RequestMapping("/toUserAdd")
     public String toAdd(){
         return "userAdd";
     }
 
     @RequestMapping("/userAdd")
     @RequiresPermissions("user:add")
     public String userAdd(User user){
         user.setPassword(Md5.md5(user.getPassword()));
         userRepository.save(user);
         return "forward:userList";
     }
 
     @RequestMapping("/toUserEdit")
     public String toEdit(Long id,Map<String,Object> map){
         User user = userRepository.findUserById(id);
         map.put("user",user);
         return "userEdit";
     }
 
     @RequestMapping("/userEdit")
     @RequiresPermissions("user:update")
     public String userEdit(Long id,String username,String password){
         password = Md5.md5(password);
         userRepository.updateUserById(id,username,password);
         return "forward:userList";
     }
 
     @RequestMapping("/userDelete")
     @RequiresPermissions("user:delete")
     public String deleteUser(Long id){
         userRepository.deleteUserById(id);
         return "forward:userList";
     }
 }

@RequiresPermissions注解是验证用户权限

@RequiresRoles注解是验证用户角色(这个在RoleController中用到,这里没有贴出来

 

  然后,再看一部分使用 thymeleaf 的HTML代码

 

 <!DOCTYPE html>
 <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
 </head>
 <body>
 <div style="margin-left: 30%">
     <form action="/roleUpdate" method="post">
         <input type="hidden" name="id" th:value="${role.id}"/>
         用  户  名:<input name="username" type="text" th:value="${role.username}"/><br/><br/>
         选择角色:<input style="margin-left: 8px;" type="radio" name="roles"
                     th:each="roleName,roleNameStat:${roleNameList}"
                     th:value="${roleName}"
                     th:text="${roleName}"
                     th:attr="checked=${roleName==role.roles?true:false}"
                     /><br/><br/>
         <input type="submit" value="提交"/>
     </form>
 </div>
 </body>
 </html>

 

老实说,第一次使用 thymeleaf 真的不大习惯,总是写成常规的 HTML 代码

 

上面也没什么好说的,也就一个下拉框的遍历(

                      th:text 表示文本值, th:value 表示value值,th:attr 表示是否选中状态,

                      th:each 就是遍历后台传来的 list 集合  -->  roleName 代表每一个 list 集合元素,roleNameStat.index 代表着该元素的下标

                      )

 

  最后,再看一下配置文件 application.properties

 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 spring.datasource.url=jdbc:mysql://localhost:3306/xxx?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
 spring.datasource.username=xxx
 spring.datasource.password=xxx
 
 spring.jpa.hibernate.ddl-auto=create-drop
 spring.jpa.show-sql=true
 spring.jpa.database=mysql
 
 spring.thymeleaf.cache=false
 spring.thymeleaf.mode=HTML

这个地方有一个坑,就是如果我们设置 spring.jpa.hibernate.ddl-auto=update,就不会执行 resources 目录下的 import.sql 文件等

根据官方文档来说,如果需要执行 resources 目录下的 import.sql 文件,就必须设置 spring.jpa.hibernate.ddl-auto 的值为 create 或者 create-drop

还一种办法就是不使用 spring.jpa.hibernate.ddl-auto ,直接在 resources 目录下添加 schema.sql 和 data.sql 文件(schema.sql用来执行DDL语句,data.sql用来执行DML语句)

 

  还有少部分代码和 HTML 就不贴出来了,有兴趣的可以去下载源代码看看。

  项目默认登陆用户   ==>   用户名:lmh,密码:123

  项目GitHub地址https://github.com/Lmh115/SpringBoot

 

版权声明
本文为[搬块砖可以吗]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/java-hui/p/11228601.html