Springboot整合jpa框架---jpa自帶的增刪改查以及分頁操作
阿新 • • 發佈:2021-03-18
Springboot整合jpa框架
JPA概述
PA是一個持久層的ORM框架,對jdbc的封裝,使用jpa可以實現操作實體物件就能夠實現對資料庫表的CRUD。
ORM關係對映:
關係型資料庫---java
資料表---對應java當中的實體類
記錄數---對應java當中的物件
Field----對應java當中的屬性
Java程式設計師面向物件的角度操作物件,由於我們的表以及表中的屬性已經和關係型資料庫當中表和欄位進行了一一對映。我們操作了物件就能夠操作表當中的記錄。
Jpql查詢
Java Pesistence Query Language:java的持久化查詢語言,類似sql語句
Sql:操作的關係型資料庫當中的記錄
Jpql:操作的是java當中的實體類物件
Sql語句:
Select field1,field2 from tableName (field1—關係型資料庫中欄位的名稱,tableName---表的名稱)
Jpql語句:
Select attributeName1,attributeName2 from entityName(attributeName1---實體類屬性的名稱,entityName---實體類的名稱)
Jpql編寫時候注意的細節:
1.裡面不能出現表名,列名,只能出現java的類名,屬性名,區分大小寫
2.出現的sql關鍵字是一樣的意思, 關鍵字不區分大小寫
3.不能寫select * 要寫select 別名
一個小例子
dao—PetDao
/**
* 類名
* generated by hik-ga-archetype-webapp
* <p>
* 建立PetDao介面,實現Pet實體類的操作
* JpaRepository<T,ID> jpa提供的介面,介面當中定義了實體的基本操作
* T 指定具體操作的實體類:Pet實體類
* ID 指定主鍵欄位的型別(實體類當中帶有id註解的屬性):Integer
*
* @date 2021/3/15 9:59
* @since
*/
public interface PetDao extends JpaRepository<Pet, Integer> {
/**
* 自定義查詢:
* (1)什麼時候進行自定義查詢
* JpaRepository介面當中提供的方法不能正常滿足實際業務需求,此時我們需要進行自定義查詢:
* PetDao介面當中自定義方法:
*
* (2)方法定義注意事項:
* 方法的返回值是根據實際的業務需求定義: List pet
* 方法的名稱必須滿足規範:findByXxx findBy固定開始Xxx屬性名稱:findByPname
* 引數列表:根據實際的業務需求定義
*
* 注意:方法的名稱必須滿足響應的規範
*/
List<Pet> findByPname(String pname);
List<Pet> findByColor(String color);
/**
* 根據pname查詢並且根據color查
* select pet0_.id as id1_0_, pet0_.color as color2_0_, pet0_.pname as pname3_0_ from t_pet pet0_ where pet0_.pname=?
* select * from t_pet pet0_ where pet0_.pname=? and pet0_.color=?
*/
List<Pet> findByPnameAndAndColor(String pname,String color);
/**
* 根據id查詢:查詢id在1-5之間的pet物件
*/
List<Pet> findByIdBetweenOrderById(Integer minId,Integer maxId);
/**
* jpql查詢
* 語法: select attName... from entityName
*
*/
//需求查詢pet列表
/**
*
* sql:select * from t_pet
* jpql:from com.example.jpa.entity.Pet
* select 別名 from xxx
* select pet from com.example.jpa.entity.Pet pet
*/
// @Query(value="from com.example.jpa.entity.Pet")
@Query(value="select pet from com.example.jpa.entity.Pet pet")
List<Pet> loadPetsList();
/**
* 查詢t_pet表中的id pname color
* sql: select id,pname,color from t_pet
* jpql: select id,pname,color from com.example.jpa.entity.Pet
*
* 注意:
* 查詢的結果集並沒有直接封裝到pet物件當中,所以用pet接收,就會出現異常ConversionFailedException
*
* 原因:查詢的資料封裝到了Obejct[] 不是直接封裝到pet當中
*/
@Query(value="select id,pname,color from com.example.jpa.entity.Pet")
List<Object[]> loadPetsList2();
/**
*
* 查詢的實體類直接封裝到了物件當中
*/
@Query("select new com.example.jpa.entity.Pet(id,pname,color) from com.example.jpa.entity.Pet")
List<Pet> loadPetsList3();
}
entity—Pet 類
/**
* 類名
* generated by hik-ga-archetype-webapp
* Pet實體類,對應底層資料庫表。mysql資料庫當中沒有t_pet表,可以使用jpa提供的****
* 實體類--->關係表
* @Entity 註解,表明當前是實體類,當前的實體類和底層的t_pet關係表進行對映
*
* @date 2021/3/12 17:35
* @since
*/
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Entity(name = "t_pet")
public class Pet {
@Id//id唯一
//指定當前主鍵的一個生成策略,自增
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column//註解,標識pname是一個普通的列,註解當中可以指定很多屬性,我們可以都使用預設值
private String pname;
@Column
private String color;
}
測試PetDao中的介面
@SpringBootTest(classes = JpaApplication.class)
class JpaApplicationTests {
@Test
void contextLoads() {
System.out.println("table 建立成功了......");
}
//對jpa提供的介面方法進行測試
@Autowired
PetDao petDao;//springboot在啟動的時候,底層使用了動態代理的方式獲得了一個介面的實現類,完成了注入
@Test
void addPet(){
System.out.println("pet add");
Pet pet = new Pet();
//pet.setId(); id欄位是自增,不需要手動設定值
pet.setPname("小花狗");
pet.setColor("黃色");
//完成新增操作
petDao.save(pet);
}
/**
* save方法:
* 如果沒有指定id,直接進行一個insert操作;
* 如果指定了id欄位:
* 根據指定的id先去查詢
* 如果查詢id對應的記錄存在的話,進行一個更新操作;
* 如果查詢id對應的記錄不存在的話,進行一個新增操作;
*
*/
@Test
void addPet1(){
System.out.println("pet add");
Pet pet = new Pet();
pet.setId(5); //id欄位是自增,不需要手動設定值
pet.setPname("hot dog");
pet.setColor("hot");
//完成新增操作
petDao.save(pet);
}
//查詢操作
/**
* 查詢操作
* 根據id查詢 findById();jpaRepository介面當中提供的,不是我們自定義的
* 查詢的內容封裝到了Optinal物件
* get();//獲取Pet物件,如果查詢的物件不存在,返回的一個異常是java.util.NoSuchElementException: No value present
*/
@Test
void findPet(){
//獲得一個Option物件
Optional<Pet> optional = petDao.findById(4);
Pet pet = optional.get();
System.out.println(pet.getId()+" ,"+pet.getPname()+" ,"+pet.getColor());
}
/**
* 列表查詢:返回的是列表集合
* findAll();沒有指定任何引數,查詢的列表
* findAll();在使用的時候可以指定引數。Sort 物件,指定排序欄位,升序或降序
*/
@Test
void findAllPets(){
// //獲得一個Option物件
// List<Pet> pets = petDao.findAll();
// for(Pet pet:pets){
// System.out.println(pet.getId()+" ,"+pet.getPname()+" ,"+pet.getColor());
// }
List<Pet> pnames = petDao.findAll(Sort.by("pname"));
for (Pet pet:pnames){
System.out.println(pet.getPname());
}
}
/**
* 分頁查詢
*/
@Test
void findAllPetWithPage(){
/**
* Pageable:介面型別
* PageRequest:介面的實現類物件;實現類不是直接new,構造器protect
* PageRequest:類中of方法,返回本類物件
* of():方法,static 靜態方法
* 引數一:
* page:查詢第一頁,使用者指定,page:0-----代表第一頁
* size:當前頁顯示的記錄數
* Direction.DESC:指定按降序進行排序
* properties:指定具體的哪個屬性進行排序
* Pageable物件封裝了一些分頁相關的引數
*/
Pageable pageable = PageRequest.of(0, 3, Sort.Direction.DESC,"id");
Page<Pet> allPets = petDao.findAll(pageable);
for (Pet pet:allPets) {
System.out.println(pet.getId()+" ,"+pet.getPname()+" ,"+pet.getColor());
}
//獲得分頁相關資訊
// long totalElements = allPets.getTotalElements();//獲得元素的個數
// int totalPages = allPets.getTotalPages();//獲得頁碼個數
}
/**
* 刪除操作
* delete(pet);傳遞一個pet物件,刪除傳遞物件
* 刪除的具體步驟:
* 1.先根據id進行一個查詢
* 2.執行delete操作
*/
@Test
void deletePet(){
// Pet pet = new Pet();
// pet.setId(5);
// petDao.delete(pet);
petDao.deleteById(3);
}
@Test
public void test3(){
//按照pname查詢
List<Pet> pname = petDao.findByPname("black dog");
System.out.println(pname);
//按照color查詢
List<Pet> color = petDao.findByColor("black");
System.out.println(color);
/* for(Pet pet:pname){
System.out.println(pet.getId()+" ,"+pet.getPname()+" ,"+pet.getColor());
}*/
//按照pname和color聯合查詢
List<Pet> list = petDao.findByPnameAndAndColor("black dog", "black");
System.out.println(list);
//根據id區間查詢並且排序
List<Pet> list1 = petDao.findByIdBetweenOrderById(1,5);
System.out.println(list1);
}
//測試jpql
@Test
public void test4(){
List<Pet> list2 = petDao.loadPetsList();
System.out.println(list2);
}
@Test
public void test5(){
List<Object[]> list3 = petDao.loadPetsList2();
for(Object[] pet:list3) {
System.out.println(Arrays.toString(pet));
}
}
@Test
public void test6(){
List<Pet> list4 = petDao.loadPetsList3();
System.out.println(list4);
}
}
application.properties
# 連線資料庫的四大引數
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/jpa
spring.datasource.username=postgres
spring.datasource.password=123456
# jpa相關配置
# 開發階段可以 設定為true,開啟****,在實際上線執行階段,實體類和底層的資料庫表都是已經存在,應該設定成false
# 資料庫和java對映 正向工程 ****
# ****: 存在資料庫的表,然後資料庫表可以生成對應實體類
# 正向工程: 先是存在實體類,然後根據實體類,生成底層的表
spring.jpa.generate-ddl=true
# create: 設定為create,每次執行程式都會將原來的資料表刪除,然後重新建立一個表
# create-drop: 每次床架你個數據表,資料表使用完畢之後,將資料表再次刪除
# none: 將功能不生效
# update: 如果你設定的實體類發生了改變,資料表會更新
# 如果資料庫當中有資料表,就使用原來的表,沒有資料表,就會建立一個數據表。也是在開發當中使用
# validate: 實體類和資料表進行校驗,如果屬性或個數不一致,就會出異常
spring.jpa.hibernate.ddl-auto=update
# 操作實體物件的時候,會為我們生成sql語句: false 不生成sql語句
spring.jpa.show-sql=true
# 指定資料庫的型別
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL10Dialect
# 上線執行時只有spring.jpa.database-platform是真實有效的
pom依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--jpa-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--postgresql-->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>