目录
- 引出
- 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;