目录
配置文件
mysql8.0和5.7有区别
- 如启动报错:Communications link failure
The driver has not received any packets from the server. 则注意检查连接mysql版本
点击查看代码
## 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
## Spring Data JPA 配置 5.7的
spring.jpa.database-platform=org.hibernate.dialect.MySQL57Dialect
##Spring Data JPA 配置 8.0的
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
## 运行时输出 jpa 执行的 sql 语句
## 打印sql
spring.jpa.show-sql=true
## 根据实体类自动生成数据表(SpringDataJPA可以自动生成数据表)
## create:每次运行项目会自动创建新表,如果之前已经存在,则删除,重新创建
## update:只会更新数据表
# create-drop,启动时生成表,停止时,把表删除!!!
spring.jpa.hibernate.ddl-auto=update
#jackson对日期时间格式化设置:时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
#jackson对日期时间格式化设置:时区设置
spring.jackson.time-zone=GMT+8
如何初始化数据库
# 控制spring.jpa.hibernate.ddl-auto=xxx是否执行
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
- spring.jpa.hibernate.ddl-auto= 有5个属性
value值 | 含义 |
---|---|
none | 不做处理 |
create | 每次加载会先删除上一次生成的表,哪怕2次没任何变化也要删,数据会丢失 |
create-drop | 每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。即系统停止时,会删表,数据会丢失 |
update | 每次启动先检查是否有表,无则创建,有再检查是否有新字段,无此字段则添加,老字段,列类型无法修改 |
validate | 验证创建数据库表结构,只进行比较,不会创建新表,但是会插入新值 |
生产环境
spring.jpa.hibernate.ddl-auto=none
spring.jpa.generate-ddl=false
生产环境的数据不允许随便修改,属性类型有调整,可以新建个字段和属性,把原来的数据用脚本迁移过去
原生写法
- load方法(代码中使用该对象时才查库)
User user = entityManager.getReference(User.class,1);
此时user是个代理对象
- get方法(正常查询)
User user = entityManager.find(User.class,1);
实体类注解
点击查看代码
@Entity
@Data
@Table(name = "student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long sid;
@Column(length = 30,unique = true)
private String name;
// 属性在字段的实际类型
@Column(columnDefinition = "char")
private int age;
@Column
private String home;
}
@Entity 加在类上,表示类名和表名的映射
@Table类上,当类名和表名不同时使用
@GeneratedValue(strategy = GenerationType.AUTO) 主键的生产策略
IDENTITY :自增(oracle不支持)
AUTO: jpa自动选择合适的策略,(默认值)
SEQUENCE: 通过序列产生主键,通过@SequenceGenerator注解指定序列名(mysql不支持);
TABLE: 通过表产生主键,借由表模拟序列产生主键,此策略可以使应用更易于数据库移植
@Basic,属性和字段的映射,getXxx()默认即为@Basic。
fetch属性,optional属性,是否允许为null,默认true
@Column 加在属性、get方法上,属性名和字段名不同时,使用。
有unique,length等属性
@Transient 加在属性上,表中可以没有此属性的字段(javax.persistence包)
// 表的字段会为date
@Temporal(TemporalType.DATE) 日期的格式,精确到日(3种:DATE--date,TIME,TIMESTAMP--datetime)
private Date birthday;
原生sql
MP和JPA对比
实体类
jpa | MP | 备注 | |
---|---|---|---|
类上 | @Entity(name = "distribution_task_temp") 或 @Table(name = "distribution_task_temp") | 1.@TableName("tb_user") | 表名和类名映射 |
主键属性 | "@Id @GeneratedValue(generator = "system-uuid")@GenericGenerator(name = "system-uuid", strategy = "uuid")@Column(name = "id") | @TableId(type= IdType.AUTO) | 3 |
普通属性 | @Column(name = "customer_id") | @TableField |
dao
栗子:
@Repository
public interface WriteOffRecordRepository extends JpaRepository<WriteOffRecord, Long>,
JpaSpecificationExecutor
JPQL语法
@Query注意点
1:大多情况下需要将*改为别名
2:表名要改为类名
3:字段名改为属性名
4:修改、删除还需要加注解:@Modifying
5:想写原生sql设置属性nativeQuery = true
- 查一个列(泛型是属性的类型)
- 查多个列
多对多
@ManyToMany
@JoinTable
一对多
多方表会创建外键(一方的主键)
@OneToMany(加在一方)
注解要加在多端,JPA规范由多端维护。
@ManyToOne(加在多端)
@JoinColumn 填写一方的属性名
下图是错误的示范,在一方,fetch=FetchType.Lazy会造成查询时报错,无法级联查出多方数据
查一方,自动级联查出多方
1:一方的注解:@OneToMany(mappedBy="一方在多方的属性名",fecth=FetchTypeEAGER),如果是LAZY,会报could not initialize proxy - no Session
2: 注意循环依赖问题(StackOverflowError),在多方排除一方(双引号里面是一方属性名)
一对一
@OneToOne
-
实体类(截图中会自动创建外键)
-
dao
save(子对象和主对象都插入了)
删(删主对象,关联对象那行也别删了)
高级用法
- findBy
属性名首字母大写 - eq
/**
* 固定语法格式:findBy 加属性名首字母大写(where student0_.name=?)
* @param name
* @return
*/
ListfindByName(String name);
-
and
-
文档
-
对比
jpa | MP | 备注 | |
---|---|---|---|
dao层 | JpaRepository | BaseMapper | 对单表的curd方法 |