轉眼間,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/得到如下界面:

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

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

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

進入springbootbase數據庫查看該注冊用戶信息是否存到user表里
select * from user;
- 1

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