zxpnet网站 zxpnet网站
首页
前端
后端服务器
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

zxpnet

一个爱学习的java开发攻城狮
首页
前端
后端服务器
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 大后端课程视频归档
  • 南航面试题
  • 并发编程

  • 性能调优

  • java8语法

  • lombok

  • 日志

  • 工具类

  • spring

  • mybatis

  • springboot

  • redis

  • zookeeper

  • springcloud

  • dubbo

  • netty

  • springsecurity

  • mq消息中间件

  • shiro

  • beetle

  • 模板引擎

  • jpa

    • jpa基础
    • 对象关系
    • model相关
      • 主键生成策略
        • 1、同时支持自增和自定义设置主键值的策略
        • 2、雪花算法生成主键的策略
      • 枚举类型数据处理
        • 常规方式
      • 多类对应一张表
    • repository相关
    • 雪花算法snowflake
  • 数据结构与算法

  • 数据库知识与设计

  • gradle

  • maven

  • bus

  • 定时任务

  • docker

  • centos

  • 加解密

  • biz业务

  • pigx项目

  • 开源项目

  • 品达通用权限项目-黑马

  • 货币交易项目coin-尚学堂

  • php

  • backend
  • jpa
shollin
2021-11-22
目录

model相关

  • 主键生成策略
    • 1、同时支持自增和自定义设置主键值的策略
    • 2、雪花算法生成主键的策略
  • 枚举类型数据处理
    • 常规方式
  • 多类对应一张表

# 主键生成策略

JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO.

  • TABLE:使用一个特定的数据库表格来保存主键。
  • SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
  • IDENTITY:主键由数据库自动生成(主要是自动增长型),Oracle不支持这种方式。
  • AUTO:主键由程序控制(也是默认的,在指定主键时,如果不指定主键生成策略,默认为AUTO)

# 1、同时支持自增和自定义设置主键值的策略

public class CustomIdGenerator extends IdentityGenerator {
	
	public static final String STRATEGY = "com.zxp.model.support.CustomIdGenerator";
	
    @Override
    public Serializable generate(SharedSessionContractImplementor session, Object object) {
        Object id = getFieldValue("id", object);
        if (id != null) {
            return (Serializable) id;
        }
        return super.generate(session, object);
    }
    
    private  Object getFieldValue(@NonNull String fieldName, @NonNull Object object) {
        Assert.notNull(fieldName, "FieldName must not be null");
        Assert.notNull(object, "Object type must not be null");
        Object value = null;
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = object.getClass().getMethod(getter);
            value = method.invoke(object);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 2、雪花算法生成主键的策略

public class SnowflakeGenerator implements IdentifierGenerator {
	
	public static final String STRATEGY = "com.zxp.model.support.SnowflakeGenerator";
    
	@Override
	public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
		
		// 有自定义的id,就用自定义的
		Object id = com.zxp.utils.ReflectionUtils.getFieldValue("id", object);
        if (id != null) {
            return (Serializable) id;
        }
        
		Snowflake snowflake = IdUtil.getSnowflake();
		return snowflake.nextId();
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

参考文章 :

JPA中使用 @GenericGenerator 自定义方式 生成 主键 ID_exception_index的博客-CSDN博客 (opens new window)

Long类型的主键,在序列化时,注意要用String方式序列化,以免丢失精度。

@JSONField(serializeUsing = ToStringSerializer.class)  // 阿里fastjson
@JsonSerialize(using = com.fasterxml.jackson.databind.ser.std.ToStringSerializer.class) // objectMapper
1
2

# 枚举类型数据处理

# 常规方式

public class EnumConvert implements AttributeConverter<StatusEnum, Integer> {
    @Override
    public Integer convertToDatabaseColumn(StatusEnum attribute) {
        return attribute.getValue();
    }

    @Override
    public StatusEnum convertToEntityAttribute(Integer dbData) {
        return StatusEnum.fromValue(dbData);
    }
}
1
2
3
4
5
6
7
8
9
10
11
@Convert(converter = EnumConvert.class)
@Column(name = "STATUS")
private StatusEnum status;
1
2
3

参考文章 : 解决JPA的枚举局限性 - JPA映射枚举的最佳实现 - xiaoqhuang - 博客园 (cnblogs.com) (opens new window)

# 多类对应一张表

场景:博客系统里面,有文章Post、独立页面Sheet,这两个类,可以对应一个post表,通过类型来区分,在设置对象类属性的时候,可以设计文章Post、页面Sheet,以及公共的BasePost

@Data
@Entity(name = "BasePost")
@Table(name = "posts", indexes = {
    @Index(name = "posts_type_status", columnList = "type, status"),
    @Index(name = "posts_create_time", columnList = "create_time")})
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.INTEGER,
    columnDefinition = "int default 0")
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class BasePost extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id")
    @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support"
        + ".CustomIdGenerator")
    private Integer id;

    /**
     * Post title.
     */
    @Column(name = "title", nullable = false)
    private String title;

    /**
     * Post status.
     */
    @Column(name = "status")
    @ColumnDefault("1")
    private PostStatus status;

    /**
     * Post slug.
     */
    @Column(name = "slug", unique = true)
    private String slug;

    /**
     * Post editor type.
     */
    @Column(name = "editor_type")
    @ColumnDefault("0")
    private PostEditorType editorType;

    /**
     * Original content,not format.
     */
    @Column(name = "original_content", nullable = false)
    @Lob
    private String originalContent;

    /**
     * Cover thumbnail of the post.
     */
    @Column(name = "thumbnail", length = 1023)
    private String thumbnail;

    /**
     * Post visits.
     */
    @Column(name = "visits")
    @ColumnDefault("0")
    private Long visits;

    /**
     * Whether to allow comments.
     */
    @Column(name = "disallow_comment")
    @ColumnDefault("0")
    private Boolean disallowComment;

    /**
     * Likes
     */
    @Column(name = "likes")
    @ColumnDefault("0")
    private Long likes;

    /**
     * Edit time.
     */
    @Column(name = "edit_time")
    @Temporal(TemporalType.TIMESTAMP)
    private Date editTime;

    /**
     * Meta keywords.
     */
    @Column(name = "meta_keywords", length = 511)
    private String metaKeywords;

    @Override
    public void prePersist() {
        super.prePersist();

        if (editTime == null) {
            editTime = getCreateTime();
        }

        if (status == null) {
            status = PostStatus.DRAFT;
        }

        if (editorType == null) {
            editorType = PostEditorType.MARKDOWN;
        }
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
对象关系
repository相关

← 对象关系 repository相关→

最近更新
01
国际象棋
09-15
02
成语
09-15
03
自然拼读
09-15
更多文章>
Theme by Vdoing | Copyright © 2019-2023 zxpnet | 粤ICP备14079330号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式