spring boot 六:SpringBoot整合JPA
1 前言
JPA: 即java persistence api(Java持久性API)。JPA通过JDK5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
实体类创建后,一般接下来需要手动编写建表语句,方便起见,可利用Hibernate-JPA进行建表。
依赖配置
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.5.4</version>
</parent>
<dependencies>
<!-- SpringBoot整合JPA依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
spring-boot-starter-parent中的parent:spring-boot-dependencies,有依赖的jpa版本2.5.4,以及mysql-connector-java的版本8.0.26:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.5.4</version>
</dependency>
<mysql.version>8.0.26</mysql.version>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
<exclusions>
<exclusion>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</exclusion>
</exclusions>
</dependency>
2 使用
2.1 建库
utf8mb4_general_ci不区分大小写,ci:case insensitive缩写,
即大小写不敏感。
utf8mb4_general_cs区分大小写,cs:case sensitive的缩写,
即大小写敏感。
这里选择utf8mb4_bin
建库sql:
create database fruitMall DEFAULT CHARACTER set utf8mb4
COLLATE utf8mb4_bin
2.2 实体类编写
主程序类MainApplication和实体类entity位于同一包路径下:
主程序类:
package com.xiaoxu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
/**
* @author xiaoxu
* @date 2022-03-26 12:48
* FruitMall:PACKAGE_NAME.com.xiaoxu.MainApplication
*/
@SpringBootApplication
@ComponentScan(basePackages = {"com.xiaoxu"})
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class,args);
}
}
实体类:
package com.xiaoxu.entity.Fruit;
import com.xiaoxu.entity.base.BaseTimeEntity;
import javax.persistence.*;
import java.math.BigDecimal;
/**
* @author xiaoxu
* @date 2022-03-26 13:01
* FruitMall:com.xiaoxu.entity.Fruit.Fruit
*/
@Entity
//如果省略@Table(name = "my_fruit"),默认是对应的fruit表
@Table(name = "my_fruit")
public class Fruit extends BaseTimeEntity {
/*
* 水果ID
* */
//主键
@Id
//自增主键
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long fruitId;
/*
* 水果名称
* */
//和数据表对应的列,以及varchar的长度50
@Column(name = "name",length = 50)
private String name;
/*
* 水果单价
* */
// 省略,默认列名就是属性名
@Column
private BigDecimal unitPrice;
/*
* 水果划线价格(根据季节变动,价格进行浮动,可高可低可等)
* */
@Column(name = "cross_out_price")
private BigDecimal crossOutPrice;
/*
* 水果单位质量
* */
@Column(name = "unit_weight")
private int unitWeight;
/*
* 水果供销商ID
* */
private long supId;
/*
* 水果库存
* */
private long fruitStock;
/*
* 水果销量
* */
private long sales;
}
2.3 jpa配置文件编写
application.yml:
spring:
banner:
location:
classpath:/banner/mybanner.txt
datasource:
username: root
password: ******
url: jdbc:mysql://localhost:3306/fruitmall?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
# 更新或者创建数据表
ddl-auto: update
# 控制台显式sql
show-sql: true
# properties:
# hibernate:
# dialect: org.hibernate.dialect.MySQL8Dialect
主程序类启动日志打印如下:
Using dialect: org.hibernate.dialect.MySQL8Dialect
可见,mysql8版本的,默认dialect也是使用的MySQL8Dialect。
2.4 建表
执行后,my_fruit表建表成功:
navicat查看对象信息ddl:
CREATE TABLE `my_fruit` (
`fruit_id` bigint NOT NULL AUTO_INCREMENT,
`cross_out_price` decimal(19,2) DEFAULT NULL,
`fruit_stock` bigint NOT NULL,
`name` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL,
`sales` bigint NOT NULL,
`sup_id` bigint NOT NULL,
`unit_price` decimal(19,2) DEFAULT NULL,
`unit_weight` int DEFAULT NULL,
PRIMARY KEY (`fruit_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
1.fruit_id为主键,且不为null,为AUTO_INCREMENT自增id,long型为mysql中bigint类型;
2.name为String类型,即为mysql中的varchar类型,且长度为50;
3.cross_out_price为BigDecimal类型,对应mysql中的decimal(19,2)类型,默认金额保留到小数点后两位;
4.unit_weight是int类型,对应mysql中的int类型。
5.成员变量名均为小驼峰写法,JPA生成的数据库表的字段,转换后默认也是按照下划线来展示的。
2.5 继承类的字段
建表中,常常遇到重复且必须的字段,如创建时间、更新时间等字段,此时可以选择在抽象类中将公共数据表字段提取出来,然后使用@MappedSuperclass注解修饰抽象父类,此时所有继承该父类的@Entity子类,建表时会带上父类的表字段。
上述没有对Fruit的父类BaseTimeEntity中字段进行处理,处理方式如下:
修改实体类如下:
BaseTimeEntity:
package com.xiaoxu.entity.base;
import javax.persistence.*;
import java.util.Date;
/**
* @author xiaoxu
* @date 2022-03-26 13:16
* FruitMall:com.xiaoxu.entity.com.xiaoxu.base.BaseTimeEntity
*/
@MappedSuperclass
public abstract class BaseTimeEntity {
/*
* 创建时间
* */
Date createTime;
/*
* 更新时间
* */
Date modifyTime;
/*
* 额外信息
* */
String extraInfo;
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getModifyTime() {
return modifyTime;
}
public void setModifyTime(Date modifyTime) {
this.modifyTime = modifyTime;
}
public String getExtraInfo() {
return extraInfo;
}
public void setExtraInfo(String extraInfo) {
this.extraInfo = extraInfo;
}
}
Fruit:
package com.xiaoxu.entity.Fruit;
import com.xiaoxu.entity.base.BaseTimeEntity;
import javax.persistence.*;
import java.math.BigDecimal;
/**
* @author xiaoxu
* @date 2022-03-26 13:01
* FruitMall:com.xiaoxu.entity.Fruit.Fruit
*/
@Entity
//如果省略@Table(name = "my_fruit"),默认是对应的fruit表
@Table(name = "my_fruit")
public class Fruit extends BaseTimeEntity {
/*
* 水果ID
* */
//主键
@Id
//自增主键
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long fruitId;
/*
* 水果名称
* */
//和数据表对应的列,以及varchar的长度50
@Column(name = "name",length = 50)
private String name;
/*
* 水果单价
* */
// 省略,默认列名就是属性名
@Column
private BigDecimal unitPrice;
/*
* 水果划线价格(根据季节变动,价格进行浮动,可高可低可等)
* */
@Column(name = "cross_out_price")
private BigDecimal crossOutPrice;
/*
* 水果单位质量
* */
@Column(name = "unit_weight")
private int unitWeight;
/*
* 水果供销商ID
* */
private long supId;
/*
* 水果库存
* */
private long fruitStock;
/*
* 水果销量
* */
private long sales;
}
手动删除原先建的表,重新执行结果如下:
CREATE TABLE `my_fruit` (
`fruit_id` bigint NOT NULL AUTO_INCREMENT,
`create_time` datetime(6) DEFAULT NULL,
`extra_info` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
`modify_time` datetime(6) DEFAULT NULL,
`cross_out_price` decimal(19,2) DEFAULT NULL,
`fruit_stock` bigint NOT NULL,
`name` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL,
`sales` bigint NOT NULL,
`sup_id` bigint NOT NULL,
`unit_price` decimal(19,2) DEFAULT NULL,
`unit_weight` int DEFAULT NULL,
PRIMARY KEY (`fruit_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
由上述可知,my_fruit表建表时,自动带上了所继承的BaseTimeEntity父类的createTime、modifyTime、extraInfo字段。