参考

@DynamicInsert属性:表示insert对象的时候,生成动态的insert语句,如果这个字段的值是null就不会加入到insert语句当中。

@DynamicUpdate属性:表示update对象的时候,生成动态的update语句,如果这个字段的值是null就不会被加入到update语句中。

@SelectBeforeUpdate //配合 @DynamicUpdate
**

注:

  1. 两个注解加上之后就不会为字段值不变的字段生成sql语句,这样sql的长度就减少了提高了传输效率和执行效率
  2. 如果不使用:@DynamicInsert 插入时参数为空为导致默认值失效
  3. 作用域
    1. 如果基类加了 @MappedSuperclass 则以父类为准,如果父类没加 @DynamicInsert @DynamicUpdate 注解,则全都不会生效,如果基类没加@MappedSuperclass 则各管各的
      1. jpa的基类一定要加@MappedSuperclass
        ```java

        基类

        package com.databstech.demo.standalone.jpa.bean;

import com.databstech.cache.jpa.entity.mysql.UuidEntity; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; import org.hibernate.annotations.SelectBeforeUpdate;

import javax.persistence.Column; import javax.persistence.MappedSuperclass;

/**

  • @author tn
  • @version 1
  • @ClassName comm
  • @description 测试
  • @date 2020/10/2 15:14 */ @MappedSuperclass @Getter @Setter @Accessors(chain = true) @DynamicInsert //动态插入 @DynamicUpdate //动态赋值 @SelectBeforeUpdate//配合 @DynamicUpdate public class comm extends UuidEntity {
  1. /**
  2. * 表示该字段为创建时间字段,在这个实体被insert的时候,会自动为其赋值
  3. */
  4. @ApiModelProperty(value = "创建时间",hidden=true)
  5. @Column(columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期' ")
  6. private String createTime;
  7. /**
  8. * 表示该字段为创建人,在这个实体被insert的时候,会自动为其赋值
  9. */
  10. @ApiModelProperty(value = "创建人",hidden=true)
  11. @Column(columnDefinition = "varchar(100) COMMENT '创建人'")
  12. private String createBy;
  13. /**
  14. * 表示该字段为修改时间字段,在这个实体被update的时候,会自动为其赋值
  15. */
  16. @ApiModelProperty(value = "修改时间",hidden=true)
  17. @Column(columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新日期'")
  18. private String updateTime;
  19. /**
  20. * 表示该字段为修改人,在这个实体被update的时候,会自动为其赋值
  21. */
  22. @ApiModelProperty(value = "修改人",hidden=true)
  23. @Column(columnDefinition = "varchar(100) COMMENT '更新人'")
  24. private String updateBy;

}

bean类

package com.databstech.demo.standalone.jpa.bean;

import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; import org.hibernate.annotations.SelectBeforeUpdate;

import javax.persistence.*;

/**

  • @author tn
  • @version 1
  • @ClassName TestDemo
  • @description 测试
  • @date 2020/10/2 10:16 */ @Entity @Table(name =”test_demo”,schema = “test”) @org.hibernate.annotations.Table(appliesTo = “test_demo”,comment = “test_demo”) @Getter @Setter @Accessors(chain = true) //@DynamicInsert //动态插入 //@DynamicUpdate //动态赋值 //@SelectBeforeUpdate //配合 @DynamicUpdate public class TestDemo extends comm { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(columnDefinition=”int COMMENT ‘主键,自动生成’”) @ApiModelProperty(value = “id”) private Integer id;
  1. @Column(columnDefinition = " varchar(100) not null comment '名字'" )
  2. private String name;
  3. @Column(name = "sex",columnDefinition="varchar(100) default '男' COMMENT '字典名'")
  4. private String sex;

// / // 表示该字段为创建时间字段,在这个实体被insert的时候,会自动为其赋值 // / // @ApiModelProperty(value = “创建时间”,hidden=true) // @Column(columnDefinition = “timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建日期’ “) // private String createTime; // // / // 表示该字段为创建人,在这个实体被insert的时候,会自动为其赋值 // / // @ApiModelProperty(value = “创建人”,hidden=true) // @Column(columnDefinition = “varchar(100) COMMENT ‘创建人’”) // private String createBy; // // / // 表示该字段为修改时间字段,在这个实体被update的时候,会自动为其赋值 // / // @ApiModelProperty(value = “修改时间”,hidden=true) // @Column(columnDefinition = “timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新日期’”) // private String updateTime; // // / // 表示该字段为修改人,在这个实体被update的时候,会自动为其赋值 // / // @ApiModelProperty(value = “修改人”,hidden=true) // @Column(columnDefinition = “varchar(100) COMMENT ‘更新人’”) // private String updateBy;

}

数据库数据

没使用 @MappedSuperclass 但是都用了 @DynamicInsert @DynamicUpdate

INSERT INTO test.test_demo (id, uuid, name, sex, create_time, create_by, update_time, update_by) VALUES (‘6’, NULL, ‘ada’, NULL, ‘2020-10-02 15:17:25’, NULL, ‘2020-10-02 15:17:25’, NULL);

使用 @MappedSuperclass 但是继承类没有使用@DynamicInsert @DynamicUpdate

INSERT INTO test.test_demo (id, uuid, name, sex, create_time, create_by, update_time, update_by) VALUES (‘8’, NULL, ‘ada’, NULL, NULL, NULL, NULL, NULL);

使用 @MappedSuperclass 但是继承类使用@DynamicInsert @DynamicUpdate

INSERT INTO test.test_demo (id, uuid, name, sex, create_time, create_by, update_time, update_by) VALUES (‘9’, NULL, ‘ada’, ‘男’, ‘2020-10-02 15:24:17’, NULL, ‘2020-10-02 15:24:17’, NULL);

下面是数据库截图

  1. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1642320/1601623938091-bc4417e1-7981-4792-843f-8768bf89b4fd.png#align=left&display=inline&height=114&margin=%5Bobject%20Object%5D&name=image.png&originHeight=114&originWidth=1506&size=17315&status=done&style=none&width=1506)
  2. 4. 修改的时候,千万不要以为这两个注解不会为字段值为null的字段生成sql,如果前端传进来一个实体对象,部分字段没有传,这时候如果使用xxxRepository.save(entity) 方法,他会把null的字段设置为空,而不是不生成sql,详情看↓下面我的测试
  3. <a name="RjWi1"></a>
  4. ## bean代码
  5. ```java
  6. package com.databstech.demo.standalone.jpa.bean;
  7. import com.databstech.cache.jpa.entity.mysql.UuidEntity;
  8. import io.swagger.annotations.ApiModelProperty;
  9. import lombok.Getter;
  10. import lombok.Setter;
  11. import lombok.experimental.Accessors;
  12. import org.hibernate.annotations.DynamicInsert;
  13. import org.hibernate.annotations.DynamicUpdate;
  14. import org.hibernate.annotations.SelectBeforeUpdate;
  15. import javax.persistence.*;
  16. /**
  17. * @author tn
  18. * @version 1
  19. * @ClassName TestDemo
  20. * @description 测试
  21. * @date 2020/10/2 10:16
  22. */
  23. @Entity
  24. @Table(name ="test_demo",schema = "test")
  25. @org.hibernate.annotations.Table(appliesTo = "test_demo",comment = "test_demo")
  26. @Getter
  27. @Setter
  28. @Accessors(chain = true)
  29. @DynamicInsert //动态插入
  30. @DynamicUpdate //动态赋值
  31. @SelectBeforeUpdate
  32. public class TestDemo extends UuidEntity<TestDemo> {
  33. @Id
  34. @GeneratedValue(strategy = GenerationType.IDENTITY)
  35. @Column(columnDefinition="int COMMENT '主键,自动生成'")
  36. @ApiModelProperty(value = "id")
  37. private Integer id;
  38. @Column(columnDefinition = " varchar(100) not null comment '名字'" )
  39. private String name;
  40. @Column(name = "sex",columnDefinition="varchar(100) default '男' COMMENT '字典名'")
  41. private String sex;
  42. /**
  43. * 表示该字段为创建时间字段,在这个实体被insert的时候,会自动为其赋值
  44. */
  45. @ApiModelProperty(value = "创建时间",hidden=true)
  46. @Column(columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期' ")
  47. private String createTime;
  48. /**
  49. * 表示该字段为创建人,在这个实体被insert的时候,会自动为其赋值
  50. */
  51. @ApiModelProperty(value = "创建人",hidden=true)
  52. @Column(columnDefinition = "varchar(100) COMMENT '创建人'")
  53. private String createBy;
  54. /**
  55. * 表示该字段为修改时间字段,在这个实体被update的时候,会自动为其赋值
  56. */
  57. @ApiModelProperty(value = "修改时间",hidden=true)
  58. @Column(columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新日期'")
  59. private String updateTime;
  60. /**
  61. * 表示该字段为修改人,在这个实体被update的时候,会自动为其赋值
  62. */
  63. @ApiModelProperty(value = "修改人",hidden=true)
  64. @Column(columnDefinition = "varchar(100) COMMENT '更新人'")
  65. private String updateBy;
  66. }

我测试:

  1. 插入
    1. 没加注解时:
      1. 只传一个参数,其他为空,sql为:insert into test_demo (uuid, name, sex, create_time, create_by, update_time, update_by) values (?, ?, ?, ?, ?, ?, ?)
    2. 加了注解时:
      1. 只传一个参数,其他为空,sql为: insert into test_demo (name) values (?)
  2. 修改不起作用还是会置空原来的属性
    1. 加了注解: update test_demo set name=?, sex=?, create_time=?, update_time=? where id=?
      1. 数据库跟查询的结果相同时则不带上该条数据
    2. 没加注解:update test_demo set uuid=?, name=?, sex=?, create_time=?, create_by=?, update_time=?, update_by=? where id=?
      1. 不判断数据是否相等强行为新的为准
    3. 没有起到 更新是空字段不跟新的作用