1.jpa是啥?java持久层的api,SpringBoot官方支持;
2.约定大于配置的理念,增删改查,save,deleteById,findAll;
3.多条件查询,and,or,like,约定大于配置;
4.多对一的查询,@ManyToOne;
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实现框架来使用。
javax
@Entity
@Table
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; // 价格
}
JpaRepository
:实体类以及主键的类型
package com.tianju.jpa.mapper;
import com.tianju.jpa.entity.Car;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* JpaRepository:实体类以及主键的类型
*/
@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 {
@Autowired
private CarDao carDao;
@Override
public void add(Car car) {
carDao.save(car);
}
}
carDao.save(car);
插入多条数据
插入后的结果
@Override
public void update(Car car) {
carDao.save(car);
}
@Override
public Car findById(int id) {
Car car = carDao.findById(id).get();
return car;
}
@Override
public void deleteById(int id) {
carDao.deleteById(id);
}
@Override
public List<Car> findAll() {
return carDao.findAll();
}
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
@Override
public 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:实体类以及主键的类型
*/
@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:实体类以及主键的类型
*/
@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:实体类以及主键的类型
*/
@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 {
@Autowired
private CarDao carDao;
@Override
public void add(Car car) {
carDao.save(car);
}
@Override
public void update(Car car) {
carDao.save(car);
}
@Override
public Car findById(int id) {
Car car = carDao.findById(id).get();
return car;
}
@Override
public void deleteById(int id) {
carDao.deleteById(id);
}
@Override
public List<Car> findAll() {
return carDao.findAll();
}
@Override
public Page findByPage(int pageNum, int pageSize) {
PageRequest pageRequest = PageRequest.of(pageNum, pageSize);
Page<Car> carPage = carDao.findAll(pageRequest);
return carPage;
}
@Override
public List<Car> findCarsByColor(String color) {
return carDao.findCarsByColor(color);
}
@Override
public List<Car> findByColorAndBrand(String color, String brand) {
return carDao.findByColorAndBrand(color, brand);
}
@Override
public List<Car> findByColorOrBrand(String color, String brand) {
return carDao.findByColorOrBrand(color,brand);
}
@Override
public List<Car> findByBrandLike(String brand) {
return carDao.findByBrandLike(brand);
}
@Override
public 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;
}
自动建的表
新增后的表
运行的SQL语句
在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.Driver
url: jdbc:mysql://192.168.111.130:3306/jpa_db?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&allowMultiQueries=true
username: root
password: 123
jpa:
# 允许显示sql
show-sql: true
hibernate:
# 自动对表进行增删改查的操作,创建表
# 可以开始的时候打开,等表创建好之后关闭
ddl-auto: update
server:
port: 9089
<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.0modelVersion>
<groupId>com.tianju.jpagroupId>
<artifactId>spring-boot-jpaartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
properties>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.6.13version>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>com.github.xiaoymingroupId>
<artifactId>knife4j-openapi2-spring-boot-starterartifactId>
<version>4.0.0version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
dependencies>
project>
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;
}
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:实体类以及主键的类型
*/
@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 {
@Autowired
private CarDao carDao;
@Override
public void add(Car car) {
carDao.save(car);
}
@Override
public void update(Car car) {
carDao.save(car);
}
@Override
public Car findById(int id) {
Car car = carDao.findById(id).get();
return car;
}
@Override
public void deleteById(int id) {
carDao.deleteById(id);
}
@Override
public List<Car> findAll() {
return carDao.findAll();
}
@Override
public Page findByPage(int pageNum, int pageSize) {
PageRequest pageRequest = PageRequest.of(pageNum, pageSize);
Page<Car> carPage = carDao.findAll(pageRequest);
return carPage;
}
@Override
public List<Car> findCarsByColor(String color) {
return carDao.findCarsByColor(color);
}
@Override
public List<Car> findByColorAndBrand(String color, String brand) {
return carDao.findByColorAndBrand(color, brand);
}
@Override
public List<Car> findByColorOrBrand(String color, String brand) {
return carDao.findByColorOrBrand(color,brand);
}
@Override
public List<Car> findByBrandLike(String brand) {
return carDao.findByBrandLike(brand);
}
@Override
public 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 {
@Autowired
private ICarService carService;
@Test
public 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)));
}
}
@Test
public void updateCar(){
Car car = carService.findById(10);
car.setCarNum("浙江888");
carService.update(car);
}
@Autowired
private FactoryDao factoryDao;
@Test
public void addFactory(){
factoryDao.save(new Factory(null,"上海工厂"));
factoryDao.save(new Factory(null,"南京工厂"));
factoryDao.save(new Factory(null,"山西工厂"));
}
@Test
public void deleteById(){
carService.deleteById(11);
}
@Test
public void findCarsByColor(){
List<Car> cars = carService.findCarsByColor("红色");
cars.forEach(System.out::println);
}
@Test
public void findCarsByColorAndBrand(){
List<Car> cars = carService
.findByColorAndBrand(
"红色","BYD");
cars.forEach(System.out::println);
}
@Test
public void findCarsByColorOrBrand(){
List<Car> cars = carService
.findByColorOrBrand(
"红色","BYD");
cars.forEach(System.out::println);
}
@Test
public void findByPage(){
Page page = carService
.findByPage(1, 3);
page.forEach(car -> {
System.out.println(car);
});
}
@Test
public void findAll(){
List<Car> all = carService.findAll();
all.forEach(car -> {
System.out.println(car);
});
}
@Test
public void findLike(){
List<Car> all = carService.findByBrandLike("B"+"%");
all.forEach(car -> {
System.out.println(car);
});
}
@Test
public 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;