参考文章

主键生成策略

简介

  • Hibernate是一个开放源代码的对象关系映射框架,它对jdbc进行了非常轻量级的对象封装,它将pojo与数据库表建立映关系,是一个全自动的orm(对象关系记录)框架。
  • 也就是说,我们可以用Hibernate来完成原来我们使用jdbc完成的操作。

    hibernate方言

  • hibernate方言是为了实现HQL(面向对象查询,是hibernate的数据库查询语言,对应于面向数据库查询的sql)语句向不同数据库的sql语句转换时,解决不同数据库之间的差异而制定的一套规范。

    @Entity和@Table注解

  • 将pojo映射到数据库,使得创建该pojo对象数据库即即新建一条记录,删除则数据库跟着删除一条记录,修改则数据库会根据此pojo对象的状态同步。
  • @Entity:被标注的类,其类名即为数据库中的表名,它的属性即为表中的字段。
  • @Table:标注在类前。属性:
    • name:表示映射的表名,不指定的话默认和类同名,但一般我们不希望表名以大写字母开头
  • @Column:标注在属性或其getter方法前。属性:
    • name:表示属性映射的字段名
    • nullable:true或false决定字段支不支持null值。
    • columnDefinition:指定类型;很多java类型都有默认的sql类型,但是Date类对应的sql类型有Datetime(精确到秒)和Date(精确到日),columnDefinition=”DATE”可以指定类型为Date
  • @Basic:即使不写也是属性的默认注解,作用是将没有加@Column注解的属性也映射到数据库。一般不需要加上用到,默认就好。
    • fetch:值为FetchType.LAZY或FetchType.EAGER,延迟加载或者及时加载,前者获取数据时不获取该字段,用时再获取;后者直接获取,默认值
    • optional:boolean,定义字段值是否允许为null,默认true
  • @Transient:该字段不映射
  • @ManyToOne:表示一个多对一的映射,被标注的属性通常是数据库表的外键
    • optional:是否允许为null,默认为true
    • fetch:表示抓取策略,默认为FetchType.EAGER
    • cascade:级联策略。
      • CascadeType.PRESIST:级联持久化,持久保存实体时,也会持久保存该实体的所有关联数据;
      • CascadeType.REMOVE:级联删除,删除一个实体时也会删除该实体的关联数据;
      • CascadeType.MERGE:级联更新,Merge对实体进行操作时,会区分这个实体的状态,假如这个实体处于托管状态,就应该使用merge,否则会报异常..同样,做级联的时候执行merge操作,CasCadeType.Merge也会对关联实体生效。额不是很懂;
      • CascadeType.REFRESH:级联刷新,假如A、B两对象同时引用同一条数据,B修改某属性后提交,之后A修改另一属性后要提交时,entityManager中的持久化实体没有更新为B修改后的样子,此时执行一次Refresh操作,就会将该实体更新为数据库中的最新记录,最后再进行提交。那么加了CascadeType.REFRESH就会在执行Refresh时也对关联的实体类进行刷新操作。
      • CascadeType.ALL:包含以上所有级联操作。
      • 具体使用方法参见笔记:@JoinColumn建立外键
  • @MappedSuperclass:要映射的类继承自不需映射的超类,需要在超类加上此注解,在要映射的类加上@Entity注解。

    @MappedSuperclass //指定映射超类(映射超类不会生成单独的表,它的映射信息作用于继承它的实体类)
    public class Resource {
    
        @Id
        @GeneratedValue
        private int id;
        //会议名称
        private String title;
        //搜索日期
        @Column(columnDefinition = "DATE")
        private Date createDate;
        //会议类型
        private String type;
        //组别
        private String model;
        //上传者
        private String author;
        //上传者id
        private int authorId;
    }
    
    @Entity
    @Table(name="image")
    public class Image extends Resource{
    
        //继承映射超类的属性
    }
    
  • 实体类必须拥有一个public或protected的无参构造函数。
  • 实体类必须是一个顶级类,枚举或者接口不能被注解为一个实体。
  • 实体类不能是final类型的,也不能有final类型的方法

    @GeneratedValue

  • 用于标注主键的生成策略,通过strategy属性指定。默认情况下,jpa自动选择一个最适合数据库库的主键生成策略:sql对应identity(像MySQL的identity是auto increment)。

    @GenericGenerator(name="_native",strategy="native") //定义生成策略,native对应自增长
    @GeneriateValue(generator="_native") //使用生成策略
    
  • 一般都是直接加个@GeneratedValue这样就好了,默认native
  • 主键生成策略:
    • increment:由hibernate自动以递增的方式生成主键(插入数据前查询最大主键并自动加一)
    • identity:由底层数据库自动生成标识符(MySQL是自增)
    • native:根据底层数据库自动选择以上方式(sql是identity)

      @Embedded

  • 当一个类存在属性为另一个类时,可以用这个注解来标注该属性

    @Entity
    @Table(name="paople") //命名,否则为大写
    public class People {
        @Id
        @GeneratedValue
        private int id;
    
        private String name;
    
        @Embedded
        private Address address;
    }
    
  • 被引用的类用@Embeddable注释

    @Embeddable
    public class Address {
        private String city;
        private String street;
        private String zip;
    }
    
  • 如此,数据库建立的people表address字段会被替换成Address类的三个属性