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. 驗證
點選註冊連結,跳轉到註冊頁面:
輸入賬戶名及密碼,點選註冊,若成功,則顯示如下圖
若該使用者名稱已被註冊,則提示對應的錯誤資訊。
進入springbootbase資料庫檢視該註冊使用者資訊是否存到user表裡
select * from user;
說明我們的資料已經正確寫到資料庫的user表裡了。
相關推薦
Spring Boot(六):Spring 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 boot(7):spring boot 2.0簡單介紹
從這篇文章開始以spring boot2為主要版本進行使用介紹。 Spring boot 2特性 spring boot2在如下的部分有所變化和增強,相關特性在後續逐步展開。 特性增強 基礎元件升級: JDK1.8+ tomcat 8+ Thymeleaf 3
Spring基礎:快速入門spring boot(2):SPRING INITIALIZR
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Spring基礎:快速入門spring boot(10):spring boot + sonarqube +jacoco
上篇文章我們瞭解到瞭如何使用SonarQube對建立的SpringBoot的應用進行分析,這篇文章來接著確認一些如何視覺化地確認測試覆蓋率。 SpringBootTest 需要測試覆蓋率,自然,在此之前需要有測試用例,在前面的例子中已經簡單講述了在SpringBoot應用中進行
Spring boot(3):Spring boot中Redis 的使用
Spring boot除了常用的資料庫支援外,對nosql資料庫也進行了封裝自動化。 1 Redis介紹 Redis 是目前業界使用最廣泛的記憶體資料儲存。相比memcached, (1)Redis支援更豐富的資料結構,例如hashes,lists,sets等
Spring boot(七):Spring boot+ mybatis 多資料來源最簡解決方案
多資料來源一般解決哪些問題?主從模式或者業務比較複雜需要連線不同的分庫來支援業務。 直接上程式碼。 配置檔案 pom包依賴,該依賴的依賴。主要是資料庫這邊的配置: mybatis.config-locations=classpath:mybatis/mybati
Spring Boot(五):Spring 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學習(3):Spring概述(轉載)
效率 調度 jpa 源代碼 一個 維護 html www hiberna 1. Spring是什麽? Spring是一個開源的輕量級Java SE(Java 標準版本)/Java EE(Java 企業版本)開發應用框架,其目的是用於簡化企業級應用程序開發。 在面向對
Spring基礎:快速入門spring cloud(1):Spring 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 AOP(三):Spring AOP的底層實現原理
一、前言 前面第一篇我們講到了AOP的概念和使用,第二篇也講到了 AOP的實現機制,在第一篇,講到了joinpoint,pointcut,aspect,weave等AOP的核心概念,接下來我們詳解分析他們的實現原理! 在動態代理 和 CGLIB 的支