JPA 持久層框架的初學筆記

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();
}

完整項目

下載頁面鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章