1. 程式人生 > >SpringBoot整合Spring Data JPA(包含分頁、排序操作)完成資料獲取

SpringBoot整合Spring Data JPA(包含分頁、排序操作)完成資料獲取

Spring Data JPA是Spring基於Hibernate開發的一個JPA框架。如果用過Hibernate或者MyBatis的話,就會知道物件關係對映(ORM)框架有多麼方便。但是Spring Data JPA框架功能更進一步,為我們做了 一個數據持久層框架幾乎能做的任何事情。
這裡總結一下我的整合流程的一個簡單例子
詳細程式碼見我的github倉庫 https://github.com/29DCH/Imitation-nowcoder-questionbank-background-system 歡迎star+fork
首先快速構建一個springboot專案我就不說了,這個比較簡單。
專案架構
在這裡插入圖片描述


1.pom.xml檔案加上Spring Data JPA的依賴

<!--spring data jpa 資料持久化元件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

2.application.properties配置檔案中加入如下配置資訊:

# jdbc連線配置
spring.datasource.url=jdbc:mysql://localhost/questionbank?useSSL=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

#jpa hibernate 配置
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.generate-ddl=true
#最常用的屬性,第一次載入hibernate時根據model類會自動建立起表的結構(前提是先建立好資料庫),
#以後載入hibernate時根據model類自動更新表結構,即使表結構改變了但表中的行仍然存在不會刪除以前的行。
#要注意的是當部署到伺服器後,表結構是不會被馬上建立起來的,是要等應用第一次執行起來後才會。
spring.jpa.hibernate.ddl-auto=update

實體層entity(和資料庫表相對應):

package olcp.entity;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

/**
 * 題目
 */
@Entity
@Table(name="question")
public class question implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 題目Id
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column
    private Integer id;
    /**
     * 題目內容
     */
    @Column
    private String content;
    /**
     * 題目選項
     */
    @Column
    private String option;
    /**
     * 題目圖片地址
     */
    @Column
    private String imgurl;
    /**
     * 題目型別
     */
    @Column
    private Integer type;
    /**
     * 難度
     */
    @Column
    private Integer difficulty;
    /**
     * 題目建立時間
     */
    @Column
    private Date creation_time;
    /**
     * 題目方向
     */
    @Column
    private String direction;
    /**
     * 題目熱度
     */
    @Column
    private Integer hot;

    @Column
    @Transient
    private question question;

    public question getQuestion() {
        return question;
    }

    public void setQuestion(question question) {
        this.question = question;
    }
    public question(){

    }

    public question(String content, String option, String imgurl, Integer type, Integer difficulty, Date
            creation_time, String direction, Integer hot) {
        this.content = content;
        this.option = option;
        this.imgurl = imgurl;
        this.type = type;
        this.difficulty = difficulty;
        this.creation_time = creation_time;
        this.direction = direction;
        this.hot = hot;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getOption() {
        return option;
    }

    public void setOption(String option) {
        this.option = option;
    }

    public String getImgurl() {
        return imgurl;
    }

    public void setImgurl(String imgurl) {
        this.imgurl = imgurl;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public Integer getDifficulty() {
        return difficulty;
    }

    public void setDifficulty(Integer difficulty) {
        this.difficulty = difficulty;
    }

    public Date getCreation_time() {
        return creation_time;
    }

    public void setCreation_time(Date creation_time) {
        this.creation_time = creation_time;
    }

    public String getDirection() {
        return direction;
    }

    public void setDirection(String direction) {
        this.direction = direction;
    }

    public Integer getHot() {
        return hot;
    }

    public void setHot(Integer hot) {
        this.hot = hot;
    }
}

dao層(主要作用是定義一系列的介面):

package olcp.dao;

import olcp.entity.question;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;

import java.util.List;

public interface questionDao extends JpaRepository<question, Integer>{
    //分頁查詢對應方向的所有題目
    Page<question> findByDirection(@Param("direction") String direction, Pageable pageable);
    question findById(int id);
    //獲取對應方向的題目總數
    int countByDirection(String direction);

}

注意這裡方法命名的格式,JPA對命名格式要求比較嚴格,一旦不符合標準將很有可能報錯。比如這裡的findByDirection方法的含義是每次查詢對應direction(資料庫中的欄位名)的所有資料(類似select語句)。我們只要繼承它提供的介面,然後按照命名規則定義相應的查詢方法。Spring就會自動建立實現了該介面和查詢方法的物件,我們直接使用就可以了。也就是說,Spring Data JPA連查詢方法都可以幫我們完成(不用寫sql語句,但是可以擴充套件sql語句,使用Query註解)。

public interface UserRepository extends JpaRepository<User, Long> {

  @Query("select u from User u where u.emailAddress = ?1")
  User findByEmailAddress(String emailAddress);
}

基本的方法如下:

關鍵字 方法命名 sql where字句
And findByNameAndPwd where name= ? and pwd =?
Or findByNameOrSex where name= ? or sex=?
Is,Equals findById,findByIdEquals where id= ?
Between findByIdBetween where id between ? and ?
LessThan findByIdLessThan where id < ?
LessThanEquals findByIdLessThanEquals where id <= ?
GreaterThan findByIdGreaterThan where id > ?
GreaterThanEquals findByIdGreaterThanEquals where id > = ?
After findByIdAfter where id > ?
Before findByIdBefore where id < ?
IsNull findByNameIsNull where name is null
isNotNull,NotNull findByNameNotNull where name is not null
Like findByNameLike where name like ?
NotLike findByNameNotLike where name not like ?

StartingWith

findByNameStartingWith where name like '?%'
EndingWith findByNameEndingWith where name like '%?'
Containing findByNameContaining where name like '%?%'
OrderBy findByIdOrderByXDesc where id=? order by x desc
Not findByNameNot where name <> ?
In findByIdIn(Collection<?> c) where id in (?)
NotIn findByIdNotIn(Collection<?> c) where id not  in (?)
True

findByAaaTue

where aaa = true
False findByAaaFalse where aaa = false
IgnoreCase findByNameIgnoreCase where UPPER(name)=UPPER(?)
      <S extends T> S save(S entity); // 儲存並返回(修改後的)實體
 
	<S extends T> Iterable<S> save(Iterable<S> entities); // 儲存並返回(修改後的)實體集合
 
	T findOne(ID id); // 根據ID獲取實體
 
	boolean exists(ID id); // 判斷指定ID的實體是否存在
 
	Iterable<T> findAll(); // 查詢所有實體
 
	Iterable<T> findAll(Iterable<ID> ids); // 根據ID集合查詢實體
 
	long count(); // 獲取實體的數量
 
	void delete(ID id); // 刪除指定ID的實體
 
	void delete(T entity); // 刪除實體
 
	void delete(Iterable<? extends T> entities); // 刪除實體集合
 
	void deleteAll(); // 刪除所有實體

	Iterable<T> findAll(Sort sort); // 查詢所有實體並排序
 
	Page<T> findAll(Pageable pageable); // 分頁查詢實體
       
     void flush(); // 提交事務
 
	<S extends T> S saveAndFlush(S entity); // 儲存實體並立即提交事務
 
	void deleteInBatch(Iterable<T> entities); // 批量刪除實體集合
 
	void deleteAllInBatch();// 批量刪除所有實體
 
	T getOne(ID id); // 根據ID查詢實體

service層(定義一系列的介面)

package olcp.service;

import olcp.entity.question;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;
public interface questionService {
    /**
     * 根據id查詢
     *
     * @param id
     * @return question
     */
    question findById(int id);
    /**
     * 分頁查詢所有題目
     *
     * @param pageable
     * @return
     */
    Page<question> findAll(Pageable pageable);
    List<question> findAll();
    /**
     * 按條件查詢
     *
     * @param example
     * @return
     */
    List<question> findAllExample(Example<question> example);
    /**
     * 更新
     *
     * @param question1
     * @return
     */
    void update(question question1);

    /**
     * 建立
     *
     * @param question1
     * @return
     */
    int create(question question1);
    void save(question question1);

    /**
     * 根據id刪除
     *
     * @param id
     * @return
     */
    void delById(int id);

    /**
     * 根據方向查詢
     * @param direction
     * @return
     */
    Page<question> findByDirection(String direction,Pageable pageable);
    /**
     * 根據方向查詢題目總數
     * @param direction
     * @return
     */
    int countByDirection(String direction);
}

impl層(實現service層中定義的介面)

package olcp.service.impl;

import olcp.dao.questionDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import olcp.entity.question;
import olcp.service.questionService;

import java.util.List;

@Service
public class questionServiceImpl implements questionService {
    @Autowired
    private questionDao questionDao1;

    @Override
    public List<question> findAll() {
        return questionDao1.findAll();
    }

    @Override
    public Page<question> findAll(Pageable pageable) {
        return questionDao1.findAll(pageable);
    }

    @Override
    public List<question> findAllExample(Example<question> example) { return questionDao1.findAll(example);
    }

    @Override
    public question findById(int id){ return questionDao1.getOne(id); }

    @Override
    public void update(question question1){ questionDao1.save(question1); }

    @Override
    public int create(question question1){ return questionDao1.save(question1).getId(); }

    @Override
    public void delById(int id){ questionDao1.delete(id); }

    @Override
    public void save(question question1){ questionDao1.save(question1); }

    @Override
    public Page<question> findByDirection(String direction,Pageable pageable) { return questionDao1.findByDirection(direction,pageable); }

    @Override
    public int countByDirection(String direction)
    {
        return questionDao1.countByDirection(direction);
    }
}

controller層(控制層,實現資料介面)

package olcp.web.admin;

import olcp.entity.question;
import olcp.service.questionService;
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.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

@RestController
@RequestMapping("/admin/question")
public class adminQuestionController {
    @Autowired
    private questionService questionservice;

    /**
     *  分頁檢視對應方向的題目
     */
    @RequestMapping("/allquestions")
    public Page<question> getallquestions(String direction, @RequestParam(defaultValue = "0", required = true)
            Integer page) {
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        Pageable pageable = new PageRequest(page, 8, sort);
        Page<question> questions = questionservice.findByDirection(direction, pageable);
        return questions;
    }

    /**
     *  獲得對應方向的題目總數
     */
    @RequestMapping("/getTotal")
    public int geTotal(String direction) {
        int total = questionservice.countByDirection(direction);
        return total;
    }

    /**
     *  新增題目
     */
    @RequestMapping("/add")
    public Boolean add(@RequestBody question question1) {
        question question2 = new question();
        question2.setContent(question1.getContent());
        question2.setOption(question1.getOption());
        question2.setImgurl(question1.getImgurl());
        question2.setType(question1.getType());
        question2.setDifficulty(question1.getDifficulty());
        question2.setCreation_time(question1.getCreation_time());
        question2.setDirection(question1.getDirection());
        question2.setHot(question1.getHot());
        questionservice.save(question2);
        return true;
    }

    /**
     *  修改題目
     */
    @RequestMapping("/update")
    public Boolean update(@RequestBody question question1) {
        question question2 = questionservice.findById(question1.getId());
        question2.setContent(question1.getContent());
        question2.setOption(question1.getOption());
        question2.setImgurl(question1.getImgurl());
        question2.setType(question1.getType());
        question2.setDifficulty(question1.getDifficulty());
        question2.setCreation_time(question1.getCreation_time());
        question2.setDirection(question1.getDirection());
        question2.setHot(question1.getHot(