目錄
- 引出
- Jpa是啥?
- Jpa的使用
- 創建實體類
- 寫dao接口類
- 寫服務類
- crud增刪改查
- 增加
- 修改
- 根據id刪除
- 全查詢
- 分頁查詢
- 條件查詢模糊查詢
- 單條件查詢
- 多條件查詢
- 模糊查詢
- 排序查詢
- 多對一查詢
- 定義實體類
- auto主鍵策略下新增
- 進行全查詢測試
- 全部代碼
- application.yml配置類
- pom配置文件
- 實體類
- Car實體類
- Factory實體類
- dao接口類
- service服務類
- 測試代碼
- 總結
引出
1.jpa是啥?java持久層的api,SpringBoot官方支持;
2.約定大于配置的理念,增刪改查,save,deleteById,findAll;
3.多條件查詢,and,or,like,約定大于配置;
4.多對一的查詢,@ManyToOne;
Jpa是啥?
Spring Data JPA
JPA是Java Persistence API的縮寫,是Java EE(Enterprise Edition)中用于實現對象關系映射(ORM)的一種規范。它提供了一組用于管理和持久化Java對象的API,使開發人員能夠以面向對象的方式操作數據庫。
JPA的目標是提供一種統一的、面向對象的數據訪問方式,使開發人員能夠更加方便地進行數據庫操作,而不需要關注底層數據庫的細節。它抽象了不同數據庫之間的差異,提供了一套通用的API,使開發人員能夠以相同的方式操作不同的數據庫。
JPA的核心概念包括實體(Entity)、實體管理器(EntityManager)、持久化上下文(Persistence Context)等。開發人員可以通過注解或XML配置來定義實體類和數據庫表之間的映射關系,然后使用EntityManager進行增刪改查等數據庫操作。
JPA的實現有很多,比較常用的有Hibernate、EclipseLink等。開發人員可以根據自己的需求選擇合適的JPA實現框架來使用。
Jpa的使用
創建實體類
javax
-
@Entity
@Table
- @Id
- @GeneratedValue(strategy) AUTO/IDENTITY(數據庫自己的主鍵自增長策略???)
- @Column
GenerationType.AUTO:會多一張表,記錄鍵
GenerationType.IDENTITY:用數據庫自增的主鍵
@GeneratedValue(strategy = GenerationType.IDENTITY) // 用數據庫自增長策略
在jpa中,ddl-auto共分為四種:
spring.jpa.hibernate.ddl-auto = create ----每次啟動SpringBoot程序時,沒有表會新建表格,表內有數據會清空;
spring.jpa.hibernate.ddl-auto = create-drop ----每次啟動SpringBoot程序時,會清空表數據;
spring.jpa.hibernate.ddl-auto = update ---- 每次啟動SpringBoot程序時,沒有表格會新建表格,表內有數據不會清空,只會更新;
spring.jpa.hibernate.ddl-auto = validate ---- 每次啟動SpringBoot程序時,會校驗實體類字段與數據庫字段的類型是否相同,不同則會報錯;
package com.tianju.jpa.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.persistence.*;
import java.math.BigDecimal;@Data
@NoArgsConstructor
@AllArgsConstructor// 表示這個實體類是和數據庫表對應的
@Entity
@Table(name = "car_tab") // 對應的表名
public class Car {@Id // 是主鍵// GenerationType.AUTO:會多一張表,記錄鍵// GenerationType.IDENTITY:用數據庫自增的主鍵@GeneratedValue(strategy = GenerationType.IDENTITY) // 用數據庫自增的策略@Column(name = "car_id")private Integer id;@Column(name = "car_num")private String carNum; // 車牌@Column(name = "car_brand")private String brand; // 品牌@Column(name = "car_color")private String color; // 顏色@Column(name = "car_price")private BigDecimal price; // 價格
}
寫dao接口類
JpaRepository<Identity,String>:實體類以及主鍵的類型
package com.tianju.jpa.mapper;import com.tianju.jpa.entity.Car;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;/*** JpaRepository<Identity,String>:實體類以及主鍵的類型*/
@Repository // 用在持久化對象上,類似于mapper
public interface CarDao extends JpaRepository<Car,Integer> {
}
寫服務類
package com.tianju.jpa.service.impl;import com.tianju.jpa.entity.Car;
import com.tianju.jpa.mapper.CarDao;
import com.tianju.jpa.service.ICarService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class CarServiceImpl implements ICarService {@Autowiredprivate CarDao carDao;@Overridepublic void add(Car car) {carDao.save(car);}
}
crud增刪改查
增加
carDao.save(car);
插入多條數據
插入后的結果
修改
@Overridepublic void update(Car car) {carDao.save(car);}@Overridepublic Car findById(int id) {Car car = carDao.findById(id).get();return car;}
根據id刪除
@Overridepublic void deleteById(int id) {carDao.deleteById(id);}
全查詢
@Overridepublic List<Car> findAll() {return carDao.findAll();}
分頁查詢
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
@Overridepublic Page findByPage(int pageNum, int pageSize) {PageRequest pageRequest = PageRequest.of(pageNum, pageSize);Page<Car> carPage = carDao.findAll(pageRequest);return carPage;}
分頁查詢的sql
條件查詢模糊查詢
單條件查詢
package com.tianju.jpa.mapper;import com.tianju.jpa.entity.Car;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;import java.util.List;/*** JpaRepository<Identity,String>:實體類以及主鍵的類型*/
@Repository // 用在持久化對象上,類似于mapper
public interface CarDao extends JpaRepository<Car,Integer> {List<Car> findCarsByColor(String color);
}
多條件查詢
package com.tianju.jpa.mapper;import com.tianju.jpa.entity.Car;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;import java.util.List;/*** JpaRepository<Identity,String>:實體類以及主鍵的類型*/
@Repository // 用在持久化對象上,類似于mapper
public interface CarDao extends JpaRepository<Car,Integer> {List<Car> findCarsByColor(String color);List<Car> findByColorAndBrand(String color,String brand);List<Car> findByColorOrBrand(String color,String brand);}
or查詢
模糊查詢
package com.tianju.jpa.mapper;import com.tianju.jpa.entity.Car;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;import java.util.List;/*** JpaRepository<Identity,String>:實體類以及主鍵的類型*/
@Repository // 用在持久化對象上,類似于mapper
public interface CarDao extends JpaRepository<Car,Integer> {List<Car> findCarsByColor(String color);List<Car> findByColorAndBrand(String color,String brand);List<Car> findByColorOrBrand(String color,String brand);List<Car> findByBrandLike(String brand);}
排序查詢
package com.tianju.jpa.service.impl;import com.tianju.jpa.entity.Car;
import com.tianju.jpa.mapper.CarDao;
import com.tianju.jpa.service.ICarService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class CarServiceImpl implements ICarService {@Autowiredprivate CarDao carDao;@Overridepublic void add(Car car) {carDao.save(car);}@Overridepublic void update(Car car) {carDao.save(car);}@Overridepublic Car findById(int id) {Car car = carDao.findById(id).get();return car;}@Overridepublic void deleteById(int id) {carDao.deleteById(id);}@Overridepublic List<Car> findAll() {return carDao.findAll();}@Overridepublic Page findByPage(int pageNum, int pageSize) {PageRequest pageRequest = PageRequest.of(pageNum, pageSize);Page<Car> carPage = carDao.findAll(pageRequest);return carPage;}@Overridepublic List<Car> findCarsByColor(String color) {return carDao.findCarsByColor(color);}@Overridepublic List<Car> findByColorAndBrand(String color, String brand) {return carDao.findByColorAndBrand(color, brand);}@Overridepublic List<Car> findByColorOrBrand(String color, String brand) {return carDao.findByColorOrBrand(color,brand);}@Overridepublic List<Car> findByBrandLike(String brand) {return carDao.findByBrandLike(brand);}@Overridepublic List<Car> orderByPrice() {Sort price = Sort.by(Sort.Direction.DESC, "price");return carDao.findAll(price);}
}
多對一查詢
定義實體類
package com.tianju.jpa.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.persistence.*;
import java.math.BigDecimal;@Data
@NoArgsConstructor
@AllArgsConstructor// 表示這個實體類是和數據庫表對應的
@Entity
@Table(name = "car_tab") // 對應的表名
public class Car {@Id // 是主鍵// GenerationType.AUTO:會多一張表,記錄鍵// GenerationType.IDENTITY:用數據庫自增的主鍵@GeneratedValue(strategy = GenerationType.IDENTITY) // 用數據庫自增的策略@Column(name = "car_id")private Integer id;@Column(name = "car_num")private String carNum; // 車牌@Column(name = "car_brand")private String brand; // 品牌@Column(name = "car_color")private String color; // 顏色@Column(name = "car_price")private BigDecimal price; // 價格@ManyToOne@JoinColumn(name = "factory_id")private Factory factory; // 多對一的工廠
}
package com.tianju.jpa.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.persistence.*;/*** 生產車的工廠,多個車對應一個工廠*/@Data
@NoArgsConstructor
@AllArgsConstructor// 表示這個實體類是和數據庫表對應的
@Entity
@Table(name = "car_factory") // 對應的表名public class Factory {@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "factory_id")private Integer id;@Column(name = "factory_name")private String name;}
自動建的表
auto主鍵策略下新增
新增后的表
進行全查詢測試
運行的SQL語句
全部代碼
application.yml配置類
在jpa中,ddl-auto共分為四種:
spring.jpa.hibernate.ddl-auto = create ----每次啟動SpringBoot程序時,沒有表會新建表格,表內有數據會清空;
spring.jpa.hibernate.ddl-auto = create-drop ----每次啟動SpringBoot程序時,會清空表數據;
spring.jpa.hibernate.ddl-auto = update ---- 每次啟動SpringBoot程序時,沒有表格會新建表格,表內有數據不會清空,只會更新;
spring.jpa.hibernate.ddl-auto = validate ---- 每次啟動SpringBoot程序時,會校驗實體類字段與數據庫字段的類型是否相同,不同則會報錯;
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.111.130:3306/jpa_db?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&allowMultiQueries=trueusername: rootpassword: 123jpa:# 允許顯示sqlshow-sql: truehibernate:# 自動對表進行增刪改查的操作,創建表# 可以開始的時候打開,等表創建好之后關閉ddl-auto: updateserver:port: 9089
pom配置文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.tianju.jpa</groupId><artifactId>spring-boot-jpa</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><!-- 起步依賴--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.13</version></parent><dependencies><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></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--mysql驅動--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi2-spring-boot-starter</artifactId><version>4.0.0</version></dependency><!-- Jpa的包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency></dependencies></project>
實體類
Car實體類
package com.tianju.jpa.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.persistence.*;
import java.math.BigDecimal;@Data
@NoArgsConstructor
@AllArgsConstructor// 表示這個實體類是和數據庫表對應的
@Entity
@Table(name = "car_tab") // 對應的表名
public class Car {@Id // 是主鍵// GenerationType.AUTO:會多一張表,記錄鍵// GenerationType.IDENTITY:用數據庫自增的主鍵@GeneratedValue(strategy = GenerationType.IDENTITY) // 用數據庫自增的策略@Column(name = "car_id")private Integer id;@Column(name = "car_num")private String carNum; // 車牌@Column(name = "car_brand")private String brand; // 品牌@Column(name = "car_color")private String color; // 顏色@Column(name = "car_price")private BigDecimal price; // 價格@ManyToOne@JoinColumn(name = "factory_id")private Factory factory; // 多對一的工廠
}
Factory實體類
package com.tianju.jpa.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.persistence.*;/*** 生產車的工廠,多個車對應一個工廠*/@Data
@NoArgsConstructor
@AllArgsConstructor// 表示這個實體類是和數據庫表對應的
@Entity
@Table(name = "car_factory") // 對應的表名public class Factory {@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "factory_id")private Integer id;@Column(name = "factory_name")private String name;}
dao接口類
package com.tianju.jpa.mapper;import com.tianju.jpa.entity.Car;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;import java.util.List;/*** JpaRepository<Identity,String>:實體類以及主鍵的類型*/
@Repository // 用在持久化對象上,類似于mapper
public interface CarDao extends JpaRepository<Car,Integer> {List<Car> findCarsByColor(String color);List<Car> findByColorAndBrand(String color,String brand);List<Car> findByColorOrBrand(String color,String brand);List<Car> findByBrandLike(String brand);}
service服務類
package com.tianju.jpa.service.impl;import com.tianju.jpa.entity.Car;
import com.tianju.jpa.mapper.CarDao;
import com.tianju.jpa.service.ICarService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class CarServiceImpl implements ICarService {@Autowiredprivate CarDao carDao;@Overridepublic void add(Car car) {carDao.save(car);}@Overridepublic void update(Car car) {carDao.save(car);}@Overridepublic Car findById(int id) {Car car = carDao.findById(id).get();return car;}@Overridepublic void deleteById(int id) {carDao.deleteById(id);}@Overridepublic List<Car> findAll() {return carDao.findAll();}@Overridepublic Page findByPage(int pageNum, int pageSize) {PageRequest pageRequest = PageRequest.of(pageNum, pageSize);Page<Car> carPage = carDao.findAll(pageRequest);return carPage;}@Overridepublic List<Car> findCarsByColor(String color) {return carDao.findCarsByColor(color);}@Overridepublic List<Car> findByColorAndBrand(String color, String brand) {return carDao.findByColorAndBrand(color, brand);}@Overridepublic List<Car> findByColorOrBrand(String color, String brand) {return carDao.findByColorOrBrand(color,brand);}@Overridepublic List<Car> findByBrandLike(String brand) {return carDao.findByBrandLike(brand);}@Overridepublic List<Car> orderByPrice() {Sort price = Sort.by(Sort.Direction.DESC, "price");return carDao.findAll(price);}
}
測試代碼
package com.tianju.jpa.mapper;import com.tianju.jpa.entity.Car;
import com.tianju.jpa.entity.Factory;
import com.tianju.jpa.service.ICarService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.math.BigDecimal;
import java.util.List;
import java.util.Random;import static org.junit.Assert.*;@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class CarDaoTest {@Autowiredprivate ICarService carService;@Testpublic void addCar(){for (int i =0;i<10;i++){double random = Math.round(Math.random() * 100) / 100.0 + 8888;
// carService.add(new Car(null,"蘇A888" +i,"BMW","紅色",new BigDecimal(random)));}}@Testpublic void updateCar(){Car car = carService.findById(10);car.setCarNum("浙江888");carService.update(car);}@Autowiredprivate FactoryDao factoryDao;@Testpublic void addFactory(){factoryDao.save(new Factory(null,"上海工廠"));factoryDao.save(new Factory(null,"南京工廠"));factoryDao.save(new Factory(null,"山西工廠"));}@Testpublic void deleteById(){carService.deleteById(11);}@Testpublic void findCarsByColor(){List<Car> cars = carService.findCarsByColor("紅色");cars.forEach(System.out::println);}@Testpublic void findCarsByColorAndBrand(){List<Car> cars = carService.findByColorAndBrand("紅色","BYD");cars.forEach(System.out::println);}@Testpublic void findCarsByColorOrBrand(){List<Car> cars = carService.findByColorOrBrand("紅色","BYD");cars.forEach(System.out::println);}@Testpublic void findByPage(){Page page = carService.findByPage(1, 3);page.forEach(car -> {System.out.println(car);});}@Testpublic void findAll(){List<Car> all = carService.findAll();all.forEach(car -> {System.out.println(car);});}@Testpublic void findLike(){List<Car> all = carService.findByBrandLike("B"+"%");all.forEach(car -> {System.out.println(car);});}@Testpublic void orderByPrice(){List<Car> all = carService.orderByPrice();all.forEach(car -> {System.out.println(car);});}public static void main(String[] args) {double random = Math.round(Math.random() * 100) / 100.0;System.out.println(random);}}
總結
1.jpa是啥?java持久層的api,SpringBoot官方支持;
2.約定大于配置的理念,增刪改查,save,deleteById,findAll;
3.多條件查詢,and,or,like,約定大于配置;
4.多對一的查詢,@ManyToOne;