参考:https://www.jianshu.com/p/91d3096f38a0
一、Jpa 多对多如何实现懒加载?
实体:Device 与 Group 是多对多的关系
Group 维护端:
@Data @Entity(name = "t_group") public class Group extends BaseEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(name = "category_id",nullable = true) private int categoryId; //分组名 private String name; @JsonIgnoreProperties(value = {"groupList"}) @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "t_group_device",joinColumns = @JoinColumn(name = "group_id"), inverseJoinColumns = @JoinColumn(name = "device_id")) private List<Device> deviceList; }
Device
@Data @Entity(name = "t_device") public class Device extends BaseEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; //设备二级分类id @Column(nullable = true) private int categoryId; //设备源id @Column(nullable = true) private int sourceId; //设备名称 private String name; //设备类型 1:实体设备 2:虚拟设备 3:系统设备 @Column(nullable = true) private int type; //设备描述 private String description; //设备实例化状态 @Column(nullable = true) private int status; @JsonIgnoreProperties(value = {"deviceList"}) @ManyToMany(mappedBy = "deviceList",fetch = FetchType.LAZY) private List<Group> groupList; }
发现懒加载无法生效:
1.添加依赖:
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-hibernate5</artifactId> <version>2.9.8</version>
</dependency>
2.yml 配置
spring:
jpa:
properties:
hibernate:
enable_lazy_load_no_trans: true
3.添加配置文件
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
/**
* 解决jpa懒加载
*/
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = converter.getObjectMapper();
mapper.registerModule(hibernate5Module());
return converter;
}
@Bean
public Hibernate5Module hibernate5Module() {
Hibernate5Module module = new Hibernate5Module();
module.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
module.enable(Hibernate5Module.Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS);
return module;
}
}
二、GeneratedValue 四种用法
GenerationType:
public enum GenerationType{ TABLE, SEQUENCE, IDENTITY, AUTO }
Table: 使用特定的数据库表保存主键,方便数据库移植
Sequence: 根据底层数据库的序列来生成主键,条件是数据库支持序列 mysql不支持
Identiy: 主键由数据库自动生成(是自动增长型) oracle 不支持
Auto: 主键由程序控制
在指定主键时,如果不指定主键生成策略,默认是 Auto
三、Jpa 中注解的使用
@Entity 标注在类上,告诉Jpa 运行的时候,生成对应的表
@Table(name= "自动义表明") 标注在类上,设置数据库生成的表
@Id 这是为主键
@GeneratedValue 设置主键生成策略,依赖具体的数据库
@Basic 表示属性到数据库字段的映射,属性的读取策略:EAGER,LAZY,表示主支抓取与延时加载。默认的是EAGER
@Column(name="自定义名称",length = "自定义长度",nullable="是否可以为空",unique = "是否唯一",columnDefinition = "自定义该字段的类型与长度")
@Transient 表示该属性并非一个到数据库表的字段映射。ORM 框架将忽略该属性,没有任何标注将默认主键为 @Basic
@Enumerated("需要定义存入数据库的类型") 映射枚举字段
@Embedded @Embeddable 标注类,当一个实体类在多个实体中进行使用,而本身不需要独立生成一个数据库表,就需要使用@Embedded @Embeddable
@ElementCollection 集合映射,当实体包含多个相同类型的变量的时候,使用@ElementController 来声明这个变量,而Jpa 会生成2张关联的表
@MappedSuperclass 实现将实体类的多个属性分装到不同的非实体类中,注解的类将不是完整的实体,不会映射到数据表,其属性映射到子类的数据库字段。
Json 相关
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") 将date属性转换为String 类型
@JsonProperty 作用在属性上,把属性名称序列化为另一名称
@JsonIgnoreProperties(ignoreUnknown=true) 作用来类上,忽略掉JSON数据里包含实体没有的字段
@JsonIgnore 在json 序列化时,将java bean 中的一些属性忽略掉,序列化和反序列化都受影响
四、Jpa 注解 @Version 乐观锁如何实现?
参考:https://blog.csdn.net/topdeveloperr/article/details/86496113
@Version 是 Jpa 提供的一个注解,作用是实现乐观锁。在Jpa 中,只需要将实体加上一个由 @Version 修饰的字段即可。每次去对这个实体操作时,Jpa 就会比较这个 version 并且在操作成功后自动更新它。若version 与当前的数据库不匹配,则更新操作失败并抛出异常 javax.persistence.OptimisticLockException