1. 程式人生 > >Spring Boot(六):Spring Boot 整合 hibernate & JPA

Spring Boot(六):Spring Boot 整合 hibernate & JPA

轉眼間,2018年的十二分之一都快過完了,忙於各類事情,部落格也都快一個月沒更新了。今天我們繼續來學習Springboot物件持久化。

首先JPA是Java持久化API,定義了一系列物件持久化的標準,而hibernate是當前非常流行的物件持久化開源框架,Spring boot就預設集成了這種框架,加速web應用開發。

1. 建立資料庫

Hibernate 可以自動幫我們建立表,但不能幫我們建立資料庫,所以說建立資料庫及為資料庫指定使用者和許可權,這是我們必須要做的工作。本文用的是MySQL資料庫管理系統軟體。

a) 首先用root進入MySQL;

mysql -hlocalhost
-uroot -proot;

其中:

-h 後面跟著MySQL主機名稱,我們這裡將MySQL安裝在本地,所以用localhost;

-u 後面跟著要訪問MySQL的使用者名稱,安裝成功後,預設會有root使用者,該使用者擁有訪問整個資料庫的所有許可權;

-p 後面跟著該使用者的密碼,root使用者的密碼由安裝MySQL裡指定,如若未指定,MySQL會隨機生成一個密碼,可在C:\Users\{username}\AppData\Roaming\si.data 裡檢視。

b) 新建立一個數據庫

登入MySQL成功後,我們可以用我們的超級使用者root為我們的專案建立一個新的database.

create database springbootbase;

執行上面的sql指令碼,即可建立一個名為springbootbase新的空資料庫。

c) 為新資料庫springbootbase新增一張表

理論上,hibernate可以根據JPA POJO為我們自動生成我們想要的表,但是我個人覺得還是自己手動建立會更好一點,可以自己理解設計我們的關係型資料,理清各張表的關聯情況。

接下來,我們來建立一張新表user

create table user (
  id int(11) auto_increment not null primary key, 
  username varchar
(255) not null, password varchar(255) not null, role enum('ADMIN', 'USER') not null default 'USER');

該表有4個欄位:id, username, password, role. 其中id型別為int(11), 自增,非空,主鍵;username, password型別為varchar(255), 非空;role型別為列舉,非空,預設值為USER。

d) 建立MySQL新使用者並授權

由於我們不能直接讓我們的web應用直接使用MySQL root超級使用者,因為如果讓web應用直接使用root賬號,這樣會導致諸多風險,比如我們原本設計web應用只能訪問springbootbase資料庫,但root卻也可以訪問其它database,這樣可能會導致其它資訊暴露;再比如root可以刪除某個資料庫的許可權,如果不使用不當,將某個資料庫刪除,那將悔之晚矣。因為我們有必要為web應用單獨建立使用者,並授予相應的許可權來保證我們的資料庫安全。

create user 'onroad'@'localhost' identified by 'onroadtech';

該sql表示建立一個使用者名稱為onroad,密碼為onroadtech的新使用者。

grant select, insert, update on springbootbase.user to 'onroad'@'localhost';

該sql表示授權onroad使用者對資料庫springbootbase具有查詢,插入及更新操作。一般普通使用者授權這三個許可權即可滿足大部分web應用開發需求。

到此,我們的資料庫已搭建成功。

2. Spring boot 整合hibernate & JPA

我們還是以SpringBootBase這個專案為基礎來整合hibernate & JPA:

2.1. 新增Maven依賴

由於Spring boot預設已經集成了Hibernate, 所在我們只需在pom.xml引用jpa及mysql連線庫.

<dependency>  
  <groupId>org.springframework.boot</groupId>  
  <artifactId>spring-boot-starter-data-jpa</artifactId>  
</dependency>  

<dependency>  
  <groupId>mysql</groupId>  
  <artifactId>mysql-connector-java</artifactId>  
</dependency>

2.2 在application.properties裡配置資料庫地址及相應的JPA

#----------------------database-------------------------
spring.datasource.url = jdbc:mysql://localhost:3306/springbootbase?useUnicode=true&characterEncoding=utf8
spring.datasource.username = onroad
spring.datasource.password = onroadtech
spring.datasource.driverClassName = com.mysql.jdbc.Driver

#----------------------JPA------------------------------
# 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.DefaultNamingStrategy

# stripped before adding them to the entity manager
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

2.3 建立一個實體類UserVO與之對應

@Entity
@Table(name = "user") //引入@Table註解,name賦值為表名
public class UserVO {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false)
    private Long id;
    private String username;
    private String password;
    private String role;

    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 getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    @Override
    public String toString() {
        return "userame: " + username + ", password: " + password + "role: " + role;
    }

}

2.4 新建UserVORepository介面繼承CrudRepository,實現對資料庫的增刪改查

public interface UserVORepository extends CrudRepository<UserVO, Long>{

    @Query("select u from UserVO u where u.username=:username")
    public UserVO findUserByName(@Param("username") String username);

    public UserVO findUserByUsername(String username);

}

其實上面這兩個介面是等價的,查詢的結果也是一樣的,只是表達方式不一樣。

2.5 前端增加一個註冊頁面register.html

<!DOCTYPE html>
<html lang="zh-cn" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8"/>

    <title>Register</title>

    <link rel="stylesheet" th:href="@{css/bootstrap.min.css}"/>
    <link rel="stylesheet" th:href="@{css/customer/login.css}"/>
</head>

<body>
    <h3 align="center">註冊</h3> 
    <div class="container">
        <form class="form-signin" th:action="@{/reg}" th:object="${user}" method="post">
            <input type="text" class="form-control" placeholder="賬號" th:field="*{username}"/>
            <input type="password" class="form-control" placeholder="密碼" th:field="*{password}"/>
            <p th:if="${param.success}" class="error-code">註冊成功</p>
            <p th:if="${param.error}" class="error-code">使用者名稱已被註冊</p>
            <button class="btn btn-lg btn-primary btn-block" type="submit">註冊</button>
        </form>
    </div>
</body>
</html>

2.6 首頁增加一個超連結到register頁面

<h2 class="form-signin-heading">請 登 錄     <a th:href="@{/register}">註冊</a></h2>

當然這個連結請求也不能攔截, 所以需要在WebSecurityConfig類中的configure()方法加上:

http
    .authorizeRequests()
    .antMatchers("/", "/register", "/reg").permitAll()

2.7 再增加個RegisterController響應register請求

@Controller
public class RegisterController {
    @Autowired UserVORepository userRepo;

    @RequestMapping(value ="/register", method = RequestMethod.GET)
    public String register(Model model, UserVO user) {
        model.addAttribute("user", user);
        return "register";
    }

    @RequestMapping(value ="/reg")
    public String addUser(Model model, UserVO user) {
        model.addAttribute("user", user);
        //UserVO isNewUser = userRepo.findUserByName(user.getUsername());
        UserVO isNewUser = userRepo.findUserByUsername(user.getUsername());
        //判斷該使用者名稱是否被註冊過
        if (null == isNewUser) {
            userRepo.save(user);
            return "redirect:register?success";
        } else {
            return "redirect:register?error";
        }
    }
}

點選首頁註冊連結,跳轉到註冊頁面,輸入註冊使用者名稱及密碼,點選註冊,呼叫UserVORepository介面進行查詢,如果註冊的使用者不存在,則新增並且返回成功,如果已存在,則返回錯誤。

3. 驗證

image

點選註冊連結,跳轉到註冊頁面:

image

輸入賬戶名及密碼,點選註冊,若成功,則顯示如下圖

image

若該使用者名稱已被註冊,則提示對應的錯誤資訊。

image

進入springbootbase資料庫檢視該註冊使用者資訊是否存到user表裡

select * from user;

image

說明我們的資料已經正確寫到資料庫的user表裡了。

相關推薦

Spring BootSpring Boot 整合 hibernate & JPA

轉眼間,2018年的十二分之一都快過完了,忙於各類事情,部落格也都快一個月沒更新了。今天我們繼續來學習Springboot物件持久化。 首先JPA是Java持久化API,定義了一系列物件持久化的標準,而hibernate是當前非常流行的物件持久化開源框架,Sp

Spring系列Spring事務原始碼解析

一、事務概述   1.1 什麼是事務   事務是一組原子性的SQL查詢,或者說是一個獨立的工作單元。要麼全部執行,要麼全部不執行。   1.2 事務的特性(ACID)   ①原子性(atomicity)    一個事務必須被視為一個不可分割的最小工作單元,整個事務中的所有操作要麼全部提交成功,要麼全

Spring Boot學習Spring Boot日誌管理

講Spring Boot日誌管理前,先看看目前有哪些常用的日誌框架吧。 我們熟悉的應該有:log4j,  log4j2,  logback,  slf4j, 還有不太熟悉的,JUL,  JCL, Jboss-logging... 具體的資料可以百度看一下。 這些日誌

Spring Boot JPA 插上翅膀的 QueryDSL

在前面的文章中,我們介紹了 JPA 的基礎使用方式,《Spring Boot (三): ORM 框架 JPA 與連線池 Hikari》,本篇文章,我們由入門至進階的介紹一下為 JPA 插上翅膀的 QueryDSL。 1. 引言 不可否認的是 JPA 使用是非常方便的,極簡化的配置,只需要使用註解,無需

Spring基礎快速入門spring boot7spring boot 2.0簡單介紹

從這篇文章開始以spring boot2為主要版本進行使用介紹。 Spring boot 2特性 spring boot2在如下的部分有所變化和增強,相關特性在後續逐步展開。 特性增強 基礎元件升級: JDK1.8+ tomcat 8+ Thymeleaf 3

Spring基礎快速入門spring boot2SPRING INITIALIZR

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Spring基礎快速入門spring boot10spring boot + sonarqube +jacoco

上篇文章我們瞭解到瞭如何使用SonarQube對建立的SpringBoot的應用進行分析,這篇文章來接著確認一些如何視覺化地確認測試覆蓋率。 SpringBootTest 需要測試覆蓋率,自然,在此之前需要有測試用例,在前面的例子中已經簡單講述了在SpringBoot應用中進行

Spring boot3Spring boot中Redis 的使用

Spring boot除了常用的資料庫支援外,對nosql資料庫也進行了封裝自動化。 1 Redis介紹 Redis 是目前業界使用最廣泛的記憶體資料儲存。相比memcached, (1)Redis支援更豐富的資料結構,例如hashes,lists,sets等

Spring bootSpring boot+ mybatis 多資料來源最簡解決方案

多資料來源一般解決哪些問題?主從模式或者業務比較複雜需要連線不同的分庫來支援業務。 直接上程式碼。 配置檔案 pom包依賴,該依賴的依賴。主要是資料庫這邊的配置: mybatis.config-locations=classpath:mybatis/mybati

Spring BootSpring Boot 整合 Spring Security (I)

1. 新增Maven依賴 在pom.xml引用spring security. <dependency> <groupId>org.springframework.boot</groupId> <artifac

Spring Boot Spring Boot Admin 監控 Spring Boot 應用

1. 引言 在上一篇文章《Spring Boot (九): 微服務應用監控 Spring Boot Actuator 詳解》我們介紹了 Spring Boot 基於 Spring Boot Actuator 的服務監控, Spring Boot Actuator 提供了對單個 Spring Boot 的監

Spring Boot 十三 Spring Boot 整合 RabbitMQ

1. 前言 RabbitMQ 是一個訊息佇列,說到訊息佇列,大家可能多多少少有聽過,它主要的功能是用來實現應用服務的非同步與解耦,同時也能起到削峰填谷、訊息分發的作用。 訊息佇列在比較主要的一個作用是用來做應用服務的解耦,訊息從訊息的生產者傳遞到訊息佇列,消費者從訊息佇列中獲取訊息並進行消費,生產者不需要

白話Spring原始碼BeanDefinition的註冊過程

上一篇部落格講了bean的建立過程。這次跟大家分享BeanDefinition的註冊過程。 一、什麼是BeanDefinition BeanDefinition:就是bean的定義資訊,比如bean的名稱,對應的class,bean的屬性值,bean是否是單列等等,一般是通過xml來定義的,

Spring Configuration事件ApplicationEvent

Spring的事件:    為Bean與Bean之間的訊息通訊提供了支援。當一個Bean處理完一個任務之後,希望另外一個Bean知道並能做響應的處理,這時我們就需要讓另外一個Bean監聽當前Bean所傳送的事件。    Spring的事件需要遵循如下流程:        (1

Spring Cloud服務閘道器zuul

通過前面幾篇文章的介紹,Spring Cloud微服務架構可通過Eureka實現服務註冊與發現,通過Ribbon或Feign來實現服務間的負載均衡呼叫,通過Hystrix來為服務呼叫提供服務降級、熔斷機制避免雪崩效應,通過Spring Cloud Config實現服務配置的集中化管理。微服務架構內部管理的基本

Spring學習3Spring概述轉載

效率 調度 jpa 源代碼 一個 維護 html www hiberna 1. Spring是什麽?   Spring是一個開源的輕量級Java SE(Java 標準版本)/Java EE(Java 企業版本)開發應用框架,其目的是用於簡化企業級應用程序開發。   在面向對

Spring基礎快速入門spring cloud1Spring Cloud介紹

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

白話Spring原始碼spring原始碼分享的思路

做事先列個大綱,這樣思路清晰了才不會亂。 這次spring原始碼系列的部落格每個字我都堅持自己手敲,然後文采不好,但是真實。希望大家喜歡。 大綱: 1.spring框架的理解 2.beanfactory:怎麼建立bean的,怎麼載入xml中bean的定義的 3.AOP 4.a

白話Spring原始碼spring框架的理解

一、為什麼需要Spring 我們想一下如果沒有spring框架我們是怎麼去開發web應用呢? 我估計大部分程式碼是跟業務無關而跟底層或者網路介面互動;物件,模組關係錯綜複雜;開發週期特別的長很容易流產;後期維護時程式碼會越來越爛,最後可能無法維護。。。 那spring框架給我們解決什麼問

探析Spring AOPSpring AOP的底層實現原理

一、前言   前面第一篇我們講到了AOP的概念和使用,第二篇也講到了 AOP的實現機制,在第一篇,講到了joinpoint,pointcut,aspect,weave等AOP的核心概念,接下來我們詳解分析他們的實現原理!   在動態代理 和 CGLIB 的支