SpringBoot整合Spring Data JPA(包含分頁、排序操作)完成資料獲取
阿新 • • 發佈:2018-12-20
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(