Jpa实体类篇

基于Springboot框架

pom.xml

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.common</groupId>
            <artifactId>web-common</artifactId>
            <version>1.0</version>
        </dependency>
        <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.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

定义一个基本实体类,自动生成公用属性

/**
 * 实体类继承此类
 * insert操作createTime赋值为当前时间
 * insert或update操作updateTime赋值为当前时间
 */
@MappedSuperclass
public abstract class BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    private String remark; //备注

    @Temporal(TemporalType.TIMESTAMP)
    @UpdateTimestamp
    private Date updateTime;

    @Temporal(TemporalType.TIMESTAMP)
    @CreationTimestamp
    private Date createTime;

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}

主键定义

定义Long类型主键基础类

@MappedSuperclass
public abstract class LongKey extends BaseEntity{

    private static final long serialVersionUID = 9134650665687245260L;

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "jpa_sequence")
    @TableGenerator(
            name = "jpa_sequence",
            initialValue = 999,            //初始化值
            allocationSize = 1             //累加值
    )
    private Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

注解@GeneratedValue默认GenerationType.AUTO主键从1自增

这里使用GenerationType.TABLE规则,初始化值999,每次+1,那么主键从1000开始做为第一条数据主键自增

定义String类型主键基础类

@MappedSuperclass
public abstract class StringKey extends BaseEntity{

    private static final long serialVersionUID = 3151655709311338868L;

    @Id
    @Column(length = 32)
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

方式一:

使用uuid:

@Id
@GenericGenerator(name = "jpa-uuid", strategy = "uuid")
@GeneratedValue(generator = "jpa-uuid")
private String id;

方式二:不定义规则,采用下列方式

重写JpaRepository

public class SimpleJpaRepositoryImpl<T, ID> extends SimpleJpaRepository<T, ID> {

    private final JpaEntityInformation<T, ?> entityInformation;
    private final EntityManager em;

    public SimpleJpaRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityInformation = entityInformation;
        this.em = entityManager;
    }

    /**
     * 保存数据
     * @param entity
     * @param <S>
     * @return
     */
    @Override
    @Transactional
    public <S extends T> S save(S entity) {
        //获取ID
        ID entityId = (ID) entityInformation.getId(entity);
        Optional<T> optionalT = null;
        if (StringUtils.isEmpty(entityId)) {
            // 获取主键字段的属性
            SingularAttribute<? super T, ?> idAttribute = entityInformation.getIdAttribute();
            TypeDescriptor ptd = new BeanWrapperImpl(entity).getPropertyTypeDescriptor(idAttribute.getName());
            //重写主键生成规则
            if (idAttribute.getJavaType().equals(String.class)){
                String key = SequentialUuidHexGenerator.generates();
                new BeanWrapperImpl(entity).setPropertyValue(idAttribute.getName(), key);
            }
            //标记为新增数据
            optionalT = Optional.empty();
        } else {
            //若ID非空 则查询最新数据
            optionalT = findById(entityId);
        }
        //获取空属性的字段
        String[] ignoreNullProperties = this.getNullProperties(entity);
        //若根据ID查询结果为空
        if (optionalT.isPresent()) {
            //1.获取最新对象
            T target = optionalT.get();
            //2.将非空属性覆盖到最新对象
            BeanUtils.copyProperties(entity, target, ignoreNullProperties);
            //3.更新非空属性
            em.merge(target);
            return entity;
        } else {
            em.persist(entity);//新增
            return entity;
        }
    }

    private static String[] getNullProperties(Object src) {
        //1.获取Bean
        BeanWrapper srcBean = new BeanWrapperImpl(src);
        //2.获取Bean的属性描述
        PropertyDescriptor[] pds = srcBean.getPropertyDescriptors();
        //3.获取Bean的空属性
        Set<String> properties = new HashSet<>();
        for (PropertyDescriptor propertyDescriptor : pds) {
            String propertyName = propertyDescriptor.getName();
            Object propertyValue = srcBean.getPropertyValue(propertyName);
            if (null == propertyValue) { //参数值为null
                //srcBean.setPropertyValue(propertyName, null);
                properties.add(propertyName);
            }
        }
        return properties.toArray(new String[properties.size()]);
    }
}

String key = SequentialUuidHexGenerator.generates();

主键生成方式可以自定义选择

这里采用的uuid有序生成工具参考Java 生成有序 UUID - VictorBu - 博客园

重写了save中的更新规则,过滤null值,避免更新部分字段时导致其他字段赋空

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的rookie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值