Spring Boot + Hibernate 項目搭建和登錄注冊例子


開發工具:IntelliJ IDEA
數據庫:MySql

目錄

Spring + Spring MVC + Mybatis 項目搭建和登錄注冊例子

Spring Boot + Mybatis 項目搭建和登錄注冊例子

Spring + Spring MVC + Hibernate 項目搭建和登錄注冊例子

Spring Boot + Hibernate 項目搭建和登錄注冊例子

Spring Boot 使用 JWT

本篇將記錄創建一個 Spring Boot + Hibernate 項目,並且編寫一個注冊登錄的例子,畢竟Java的東西配置起來真有點麻煩

創建數據庫

就隨便一點吧,使用MySql,數據庫就用 test ,新建一個 users 表,隨便設置幾個字段

注意

  1. 要按照命名規范,單詞均小寫,不同單詞之間使用下划線隔開
  2. Hibernate 貌似不推薦使用外鍵,需要我們在代碼中手動控制實體之間的關系
    其實是我在使用 Hibernate 和 Mybatis 的時候,用了很多時間都沒解決外鍵的問題,寫配置也覺得挺麻煩的
    感覺有時候不如自己封裝JDBC,只能感嘆 Entity Framework Core 是真的好用,(貌似 Mybatis 的外鍵和 EF Core蠻像的)大概是我還太菜了吧,等我有時間解決外鍵的問題再寫另一篇記錄吧 T_T

輸入用戶名和密碼,填寫連接字符串,然后點擊 Test Connection
連接字符串參考:jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false

創建 Spring Boot 項目

注意:有可能因為網絡問題創建不成功,可以使用代理網絡或者手機熱點試試

新建項目,選擇 Spring Initializr,JDK 一般都是1.8吧,因為只是例子,所以我就隨便選一個版本了

Group:一般的是域名
Artifact:項目名稱

因為是例子,所以我隨便起名了,然后Next

可以選擇一些需要的庫,也可以之后用Maven添加,這里我就選一個Web,然后Next

到這里其實只需要改一個路徑就好了,路徑最后的文件夾名稱一定要和項目名稱一致,然后就創建了

創建完項目,右鍵 src

配置Maven,這里就不詳細展開講了,Maven的配置 baidu bing之類的搜索引擎隨便查都有答案

修改 pom.xml 文件,因為配置過於麻煩,所以我直接把做好的扔出來了,不包括數據庫日志依賴庫,需要什么就自己添加吧

<?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 https://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.4.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.springboot_hibernate.online_shop</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--springboot依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!-- 移除嵌入式tomcat插件 -->
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- JAP -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>
        <!-- 數據庫驅動-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

配置本地 tomcat

當然,上方的配置已經移除了自帶的 tomcat ,接下來我們自己部署

選擇本地 tomcat 路徑,到 tomcat 文件夾即可

配置部署文件

這個兩個選哪個都行,然后應用和確定

項目結構 和 application.peoperties

項目結構,僅供參考

  • Controllers:控制器
  • DAO:數據庫訪問
  • Filters:過濾器
  • Models:實體模型類
  • Services:服務層
  • Utils:工具類
  • Views:視圖

配置 application.peoperties

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 這里是數據庫連接字符串,可能需要修改
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.thymeleaf.encoding=UTF-8
# 視圖路徑
spring.thymeleaf.prefix=classpath:/templates/Views/

# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them to the entity manager
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

主頁和控制器

主函數

@SpringBootApplication
@EnableJpaRepositories
@EntityScan(basePackages = "com.springboot.demo.Models")
public class DemoApplication extends SpringBootServletInitializer
{
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder springApplicationBuilder)
    {
        return springApplicationBuilder.sources(DemoApplication.class);
    }

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

}

主頁 html,在 Views,新建 Home 文件夾,在Home文件夾下新建 Index.html 文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link href="css/MySheetStyle.css" type="text/css" rel="stylesheet">
    <title>Index</title>
</head>
<body>
<h1>This is Home Index Page</h1>
</body>
</html>

控制器,這里注意一下,我使用 ModelAndView 作為返回值,主要是懶得敲前端代碼,具體返回值可以自己定義字符串或者Json之類的
  我還是喜歡 ASP.NET Core ,View 和 ViewComponent 是真的方便,雖然前后端不分離,但是后端代碼寫起來着爽啊,畢竟我只是寫后端的 ( ̄_, ̄ )

@RestController
public class HomeController
{
    @RequestMapping("/")
    public ModelAndView Index()
    {
        ModelAndView mav=new ModelAndView();
        mav.setViewName("Home/Index");
        return mav;
    }
}

運行項目,還算成功

Hibernate 生成實體類

選擇項目結構

選擇 Modules ,添加 Hibernate

應用和確定,就會在左側出現 persistence 選項

點擊,然后右鍵 demo 選項,再選擇 Generate Persistence Mapping ,選擇 By Database Schema

選擇數據庫連接,再選擇需要生成的實體類,這里我稍微更改了類名,因為數據庫的表是 users ,而實體類我想叫 User ,前綴后綴看個人喜好吧,hibernate 配置文件可以自己新建一個,我的配置文件在 resources 目錄下,然后 Ok 就會生成實體類和相應的配置文件

生成的實體類 UserEntity ,這里我去掉了 catalog

package com.springboot.demo.Models;

import javax.persistence.*;

@Entity
@Table(name = "users", schema = "test")
public class UserEntity
{
    private int id;
    private String username;
    private String password;

    @Id
    @Column(name = "id", nullable = false)
    public int getId()
    {
        return id;
    }

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

    @Basic
    @Column(name = "username", nullable = false, length = 50)
    public String getUsername()
    {
        return username;
    }

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

    @Basic
    @Column(name = "password", nullable = false, length = 20)
    public String getPassword()
    {
        return password;
    }

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

    @Override
    public boolean equals(Object o)
    {
        if (this == o)
        {
            return true;
        }
        if (o == null || getClass() != o.getClass())
        {
            return false;
        }

        UserEntity that = (UserEntity) o;

        if (id != that.id)
        {
            return false;
        }
        if (username != null ? !username.equals(that.username) : that.username != null)
        {
            return false;
        }
        if (password != null ? !password.equals(that.password) : that.password != null)
        {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode()
    {
        int result = id;
        result = 31 * result + (username != null ? username.hashCode() : 0);
        result = 31 * result + (password != null ? password.hashCode() : 0);
        return result;
    }
}

生成的實體配置文件 UserEntity.hbm.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="com.springboot.demo.Models.UserEntity" table="users" schema="test">
        <id name="id">
            <column name="id" sql-type="int"/>
        </id>
        <property name="username">
            <column name="username" sql-type="varchar(50)" length="50"/>
        </property>
        <property name="password">
            <column name="password" sql-type="varchar(20)" length="20"/>
        </property>
    </class>
</hibernate-mapping>

DAO 接口

這里你可以選擇編寫一個基礎接口,類似這樣的,然后再去繼承,要注意命名規范,這個IDEA有提示

@Repository
public interface IBaseDAO<T> extends JpaRepository<T,Integer>
{
    public T findById(int id);

    public List<T> findAll();
}

其實我覺得這樣做的意義不是很大,所以我直接繼承 JpaRepository

@Repository
public interface IUserDAO extends JpaRepository<UserEntity, Integer>
{
    //    @Query(value = "SELECT u FROM UserEntity u WHERE u.id=:id")
    @Query(value = "select * from users where id=?1", nativeQuery = true)
    public UserEntity findById(int id);

    @Query(value = "select * from users", nativeQuery = true)
    public List<UserEntity> findAll();

    @Query(value = "select * from users where username=?1 and password=?2", nativeQuery = true)
    public UserEntity findByUsernameAndPassword(String username, String password);

    @Query(value = "select * from users where username=?1", nativeQuery = true)
    public UserEntity findByUsername(String username);

    //增刪改的sql語句,要使用@Modifying和@Transactional
    @Modifying
    @Transactional
    @Query(value = "delete from users where id=?1", nativeQuery = true)
    public void deleteById(int id);
}

Service

@Service
public class UserService
{
    @Autowired
    private IUserDAO _userDAO;

    public UserEntity GetUserById(int id)
    {
        return this._userDAO.findById(id);
    }

    public List<UserEntity> GetAllUser()
    {
        return this._userDAO.findAll();
    }

    public UserEntity GetUserByUsernameAndPassword(String username, String password)
    {
        return this._userDAO.findByUsernameAndPassword(username, password);
    }

    public UserEntity GetUserByUsername(String username)
    {
        return this._userDAO.findByUsername(username);
    }

    public void DeteleById(int id)
    {
        this._userDAO.deleteById(id);
    }

    //保存操作,用於增加和修改數據
    public void Save(UserEntity userEntity)
    {
        this._userDAO.save(userEntity);
    }

}

控制器

這里的控制器使用了兩種獲取值的方式分別是 th:objectname

@RestController
public class UserController
{
    @Autowired
    private UserService _userService;

    @RequestMapping("/User/")
    public ModelAndView Index(Model model)
    {
        ModelAndView mav = new ModelAndView();
        //初始化Index頁面需要的變量
        model.addAttribute("userEntity", new UserEntity());
        model.addAttribute("LoginMessage", "");
        mav.setViewName("User/Index");
        return mav;
    }

    @RequestMapping(value = "/UserController/Login/DoLogin", method = RequestMethod.POST)
    public ModelAndView DoLogin(@ModelAttribute UserEntity userEntity, Model model, @RequestParam(name = "btn") String btn)
    {
        ModelAndView mav = new ModelAndView();
        //先確定點擊的按鈕
        if (true == btn.equals("Register"))
        {
            mav.setViewName("User/Register");
        }
        else
        {
            String username = userEntity.getUsername();
            String password = userEntity.getPassword();
            if (username.equals("") || password.equals(""))
            {
                model.addAttribute("LoginMessage", "用戶名或密碼不能為空");
                mav.setViewName("User/Index");
            }
            else
            {
                UserEntity user = this._userService.GetUserByUsernameAndPassword(username, password);
                if (user == null)
                {
                    model.addAttribute("LoginMessage", "用戶名或密碼錯誤");
                    mav.setViewName("User/Index");
                }
                else
                {
                    mav.setViewName("User/Success");
                }
            }
        }

        return mav;
    }

    //初始化注冊頁面
    @RequestMapping("/User/Register")
    public ModelAndView Register(Model model)
    {
        model.addAttribute("username", "");
        model.addAttribute("RegisterMessage", "");
        ModelAndView mav = new ModelAndView();
        mav.setViewName("User/Register");
        return mav;
    }

    //注冊操作
    @RequestMapping(value = "/UserController/Register/DoRegister", method = RequestMethod.POST)
    public ModelAndView DoRegister(Model model, @RequestParam(name = "username") String username, @RequestParam(name = "password") String password, @RequestParam(name = "repeatPassword") String repeatPassword)
    {
        ModelAndView mav = new ModelAndView();
        if (username.equals("") || password.equals("") || repeatPassword.equals(""))
        {
            model.addAttribute("RegisterMessage", "用戶名、密碼或重復密碼不能為空");
            mav.setViewName("User/Register");
        }
        else
        {
            if (false == password.equals(repeatPassword))
            {
                model.addAttribute("RegisterMessage", "兩次密碼不一致");
                model.addAttribute("username", username);
                mav.setViewName("User/Register");
            }
            else if (null != this._userService.GetUserByUsername(username))
            {
                model.addAttribute("RegisterMessage", "用戶已存在");
                mav.setViewName("User/Register");
            }
            else
            {
                UserEntity user = new UserEntity();
                user.setUsername(username);
                user.setPassword(password);
                this._userService.Save(user);
                model.addAttribute("userEntity", new UserEntity());
                model.addAttribute("LoginMessage", "");
                mav.setViewName("User/Index");
            }
        }

        return mav;
    }
}

三個頁面添加

添加到 Views/User目錄下
Index.html 首頁,登錄和注冊使用的是不同的傳值方法,登錄使用的是 th:object ,注冊用的是從標簽的 name 屬性取值, th:value 只用於顯示后端傳到前端的值,可以不用

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <link href="http://localhost:8080/demo_war/css/MyStyleSheet.css" type="text/css"
          rel="stylesheet">
    <title>User Index</title>
</head>
<body>
<h1>This is User Index View</h1>
<form action="#" th:action="@{/UserController/Login/DoLogin}" th:object="${userEntity}" method="post">
    <label>用戶名:
        <input type="text" th:field="*{username}"/>
    </label>
    <br>
    <label>密碼:
        <input type="password" th:field="*{password}"/>
    </label>
    <br>
    <label style="color: red" th:text="${LoginMessage}" th:if="${not #strings.isEmpty(LoginMessage)}">

    </label>
    <br>
    <label>
        <button type="submit" name="btn" value="Login">登錄</button>
    </label>
    <button type="submit" name="btn" value="Register">注冊</button>
</form>
</body>
</html>

Register.html 注冊頁面

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <link href="http://localhost:8080/demo_war/css/MyStyleSheet.css" type="text/css"
          rel="stylesheet">
    <title>Register Page</title>
</head>
<body>
<h1>This is Register Page</h1>
<form action="#" th:action="@{/UserController/Register/DoRegister}" method="post">
<label>用戶名:
    <input type="text" name="username" th:value="${username}"/>
</label>
<br>
<label>密碼:
    <input type="password" name="password" />
</label>
<br>
<label>重復密碼:
    <input type="password" name="repeatPassword"/>
</label>
<br>
<label style="color: red" th:text="${RegisterMessage}" th:if="${not #strings.isEmpty(RegisterMessage)}">

</label>
<br>
<label>
    <input type="submit" value="注冊"/>
</label>
</form>
</body>
</html>

Success.html 登錄成功的頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link href="http://localhost:8080/demo_war/css/MyStyleSheet.css" type="text/css"
          rel="stylesheet">
    <title>Success Page</title>
</head>
<body>
<h1>Login Success</h1>
</body>
</html>

因為控制器的返回值是視圖,所以要這樣訪問,根據控制器的標注修改 url ,如果只是 html + js 的話,可以直接 Views/ 訪問視圖

最終項目結構

Spring Boot + Hibernate 項目搭建和登錄注冊例子 結束

可以運行了,可能不太符合 Spring Boot 的編程規范,畢竟我更喜歡 ASP.NET 的規范


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM