【實驗一 】Spring Boot 集成 hibernate & JPA


 

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

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

1. 創建數據庫

Hibernate 可以自動幫我們創建表,但不能幫我們創建數據庫,所以說創建數據庫及為數據庫指定用戶和權限,這是我們必須要做的工作。本文用的是MySQL數據庫管理系統軟件。

a) 首先用root進入MySQL;

mysql -hlocalhost -uroot -proot;
  • 1

其中:

-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;
  • 1

執行上面的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');
  • 1
  • 2
  • 3
  • 4
  • 5

該表有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';
  • 1

該sql表示創建一個用戶名為onroad,密碼為onroadtech的新用戶。

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

該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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

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; } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

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); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

2.6 首頁增加一個超鏈接到register頁面

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

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

http
    .authorizeRequests()
    .antMatchers("/", "/register", "/reg").permitAll()
  • 1
  • 2
  • 3

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"; } } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

點擊首頁注冊鏈接,跳轉到注冊頁面,輸入注冊用戶名及密碼,點擊注冊,調用UserVORepository接口進行查詢,如果注冊的用戶不存在,則新增並且返回成功,如果已存在,則返回錯誤。

3. 驗證

訪問https://localhost:8443/SpringBootBase/得到如下界面:

image

點擊注冊鏈接,跳轉到注冊頁面:

image

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

image

若該用戶名已被注冊,則提示對應的錯誤信息。

image

進入springbootbase數據庫查看該注冊用戶信息是否存到user表里

select * from user;
  • 1

image

說明我們的數據已經正確寫到數據庫的user表里了。



免責聲明!

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



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