why?
JPA的作用類似於MyBatis,但更加的自動化,在對數據庫性能要求不是特別高的時候很方便。
可以避免繁複的JDBC數據庫操作代碼的編寫,提高java持久層開發的效率。
what?
JPA(Java Persistence API)是Sun官方提出的Java持久化規範,用來方便大家操作數據庫。
真正幹活的可能是Hibernate,TopLink等等實現了JPA規範的不同廠商,默認是Hibernate。
how?
現在就開始學習簡單的使用
1. 基礎部件介紹
數據庫 + 實體類 + Dao接口
2. 數據庫結構
3. jpa的jar包依賴配置(Maven)
<!-- mysql驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
<!-- jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
4. JPA的配置
配置文件位置:src/main/resources/application.properties
添加的配置:
# 配置數據源
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 自動更新數據庫表結構
spring.jpa.properties.hibernate.hbm2ddl.auto=update
這個根據個人的數據庫情況來修改
5. 實體類
package com.how2java.springboot.pojo;
import javax.persistence.*;
/**
* @Author guozhi
* @Date 2019/7/1 11:18
* @Description TODO
*/
@Entity
@Table( name="name")
public class TableTest {
// 表示這是主鍵
@Id
// 表示這是自增長類型
@GeneratedValue(strategy = GenerationType.IDENTITY)
// 顯式設置列名
@Column(name = "id")
private int id;
@Column(name ="value")
private String value;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "TableTest{" +
"id=" + id +
", value='" + value + '\'' +
'}';
}
}
6. DAO接口
package com.how2java.springboot.dao;
import com.how2java.springboot.pojo.TableTest;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
// 繼承封裝好的jpa方法
public interface TestDAO extends JpaRepository<TableTest, Integer> {
/**
* 簡單條件查詢
* @param value
* @return
*/
public List<TableTest> findByValue(String value);
}
這裏需要做簡單的說明
- 繼承了JpaRepository,並且提供泛型<Category,Integer> 表示這個是針對Category類的DAO,Integer表示主鍵是Integer類型。
- JpaRepository 這個接口,提供了CRUD, 分頁等等一系列的查詢了等自帶方法。
下面列舉條件查詢的方法規範,符合這些規範就可以不用自己去實現方法,而讓框架幫你實現。
7. 測試代碼
package com.how2java.springboot.web;
import com.how2java.springboot.dao.TestDAO;
import com.how2java.springboot.pojo.TableTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @Author guozhi
* @Date 2019/7/1 16:14
* @Description TODO
*/
@Controller
@RequestMapping("/jpa")
public class JPAController {
//內部servlet之間重定向
private final String res = "redirect:/jpa/select";
private final TestDAO testDAO;
// 自動裝配的註解
@Autowired
public JPAController(TestDAO testDAO) {
this.testDAO = testDAO;
}
// 刪除
@RequestMapping("/delete")
public String delete(TableTest test){
testDAO.delete(test);
return res;
}
// 插入
@RequestMapping("/insert")
public String insert(TableTest test){
testDAO.save(test);
return res;
}
// 分頁查詢
@RequestMapping("/select")
public String selects(Model model, @RequestParam(value = "start", defaultValue = "0") int start,
@RequestParam(value = "size", defaultValue = "5") int size) throws Exception{
// 記錄在數據庫中的開始位置; size 表示這一頁的長度
start = start <0 ? 0 :start;
// 排序的規則, 按id降序
Sort sort = new Sort(Sort.Direction.DESC, "id");
// 分頁的支持
Pageable pageable = new PageRequest(start, size, sort);
Page<TableTest> page;
page = testDAO.findAll(pageable);
// 測試條件查詢
System.out.println(testDAO.findByValue("abc").toString());
model.addAttribute("page", page);
return "jpa";
}
// 更新, 含有事務機制
@Transactional
@RequestMapping("/update")
public String update(TableTest test, Model model){
try{
testDAO.save(test);
}catch (Exception e){
// 事務回滾
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return res;
}
}
這裏對使用到的Page和Pageable類做一個說明
public interface Page<T> extends Iterable<T> {
int getNumber(); //當前第幾頁 返回當前頁的數目。總是非負的
int getSize(); //返回當前頁面的大小。
int getTotalPages(); //返回分頁總數。
int getNumberOfElements(); //返回當前頁上的元素數。
long getTotalElements(); //返回元素總數。
boolean hasPreviousPage(); //返回如果有上一頁。
boolean isFirstPage(); //返回當前頁是否爲第一頁。
boolean hasNextPage(); //返回如果有下一頁。
boolean isLastPage(); //返回當前頁是否爲最後一頁。
Iterator<T> iterator();
List<T> getContent(); //將所有數據返回爲List
boolean hasContent(); //返回數據是否有內容。
Sort getSort(); //返回頁的排序參數。
}
public interface Pageable {
/**
* 返回要返回的頁面.
*
* @return the page to be returned.
*/
int getPageNumber();
/**
* 返回要返回的項目的數量。
*
* @return the number of items of that page
*/
int getPageSize();
/**
* 根據底層頁面和頁面大小返回偏移量。
*
* @return the offset to be taken
*/
int getOffset();
/**
* 返回排序參數。
*
* @return
*/
Sort getSort();
}