hibernater 复习,总结

来源:互联网 发布:怎么去掉知乎标题 编辑:程序博客网 时间:2024/06/05 04:01
hibernater 注解总结

@Entity
@Table               
@Id

@GeneratedValue (主键策略)
@Access 访问策略.不直接访问属性(不用设置)
@Proxy (proxyClass 指定接口,延迟加载)
@DynamicInsert 指定insert 动态插入,一般不开启,费时间
@DynamicUpdate 同上(可以指定乐观锁策略 p401)
SelectBeforeUpdate 先更新,在select    这个不是很懂
@Polymorphism 隐式查询
@Where 过滤条件
@BachSize 抓取是的个数.支持延迟加载
@OptimisticLock 乐观锁
@Check
@Subselect 只读实体 有点像mybaits构成实体  有用
@Column (length nuable name)

@Formula 只读表达式     (数据库的max那些函数)
@Generated 指定数据列的值是否有数据库生成 p402  自动生成时间(感觉有点用,但是需要数据库脚本支持)
@Transient 不保存的属性
@Enumerated 枚举,有保存序号,和保存名称两种

@Basic  大数据 byte[]  对于大数据要延迟加载
@Lob char[]

@Temporal 时间

@SequenceGenerator()   主键生成器  oracle   还是GeneratedValue 简单
@TableGenerator

@ElementCollection   集合属性

@CollectionTable     

@JoinColumn   外键 常用属性 unable unique(为该列指定唯一约束) referecceedName 该列所参照的主键的列名字
对于nuable 如果持久化对象能过管得到,则nuable true,对于外键.则可以为false

List Map
@OrderColumn  list 集合索引

@MapKeyColumn  map 集合索引

Set 无序,不用索引


eg:
    @ElementCollection(targetClass = String.class)
    @CollectionTable(name = "school_inf",joinColumns = @JoinColumn(name = "person_id",nullable = false))
    @Column(name = "school_name")
    @OrderColumn(name = "list_order")
    private List<String> schools = new ArrayList<>();

//OrderColumn  索引的column,采用默认的Cascady.ALL  采用联合主键 person_id  list_order


对于数组也是一样的
eg:
    @ElementCollection(targetClass = String.class)
    @CollectionTable(name = "school_inf",joinColumns = @JoinColumn(name = "person_id",nullable = false))
    @Column(name = "school_name")
    @OrderColumn(name = "list_order")
    private String[] schools;

对于Set  因为是无序的所以不用 OrderColumn  采用的外键,和 school_name 作为联合主键
    @ElementCollection(targetClass = String.class)
    @CollectionTable(name = "school_inf",joinColumns = @JoinColumn(name = "person_id",nullable = false))
    @Column(name = "school_name")
    private Set<String> schools = new HashSet<>();

对于Map  采用key 和外键作为主键  延迟加载
        @ElementCollection(targetClass = Float.class,fetch = FetchType.EAGER)
        @CollectionTable(name = "school_inf",
           joinColumns = @JoinColumn(name = "scrop_inf",nullable = false))
        @MapKeyColumn(name = "subject_name")
        @MapKeyClass(String.class)
        @Column(name = "mark")
        private Map<String,Float> scores = new HashMap<>();


什么时候有那个list map set

在1 n 的时候,控制映射关系,在n 时候,则采用set,反向集合

hibernater  对于TreeSet  TreeMap
    @SortNatural
    @SortComparator()

eg:TreeSet
    @ElementCollection(targetClass = String.class,fetch = FetchType.EAGER)
    @CollectionTable(name = "training_inf",
           joinColumns = @JoinColumn(name = "person_id",nullable = false))
    @Column(name = "training_name",nullable = false)
    @SortNatural
    private SortedSet<String> trainings = new TreeSet<>();

@OrderBy  对排序 的支持
    @ElementCollection(targetClass = String.class,fetch = FetchType.EAGER)
    @CollectionTable(name = "training_inf",
           joinColumns = @JoinColumn(name = "person_id",nullable = false))
    @Column(name = "training_name",nullable = false)
    @OrderBy("training_name desc")
    private Set<String> trainings = new HashSet<>();

映射组件 在组件端,添加注释,使之为 组件
Perosn 端
 privater Name name;   //直接声明

Name 端
对于组件,他是附件在主表上面的
@Embeddable Name{
    ....
    @Parent
    privater Person owner;
}



hibernater 提供的另外的一种组件
直接在Perosn 里面添加

 @Embedded
    @AttributeOverrides({
            @AssociationOverride(name="first",column = @Column(name="person_firstname")),
            @AssociationOverride(name="last",column = @Column(name="person_lastname"))
    })

不需要在Name 添加什么东西(感觉还不如直接申明为属性)








集合属性的元素作为组件

    @ElementCollection(targetClass = Scrore.clasa)
    @CollectionTable(name = "score_inf",joinColumns = @JoinColumn(name = "person_id",nullable = false))
    @MapKeyColumn(name = "subject_name")
    @MapKeyClass(String.class)
    private Map<String,Score> scores = new HashMap<>();

    @ElementCollection(targetClass = Name.class)
    @CollectionTable(name = "nick_inf",joinColumns = @JoinColumn(name = "person_id",nullable = false))
    @OrderColumn(name = "list_order")
    private List<Name> nicks = new ArrayList<>();

比较之前的list 他没有 @Column(name = "school_name")
它会默认采取list 的属性名称  就更一把的一样,其实这个,就是吧组件的两个属性
默认添加到附表的结构中   这是组件的一种性质吧



将组件作为map key

    @ElementCollection(targetClass = Integer.class)
    @CollectionTable(name = "nick_power_inf",
            joinColumns = @JoinColumn(name = "person_id",nullable = false))
    @Column(name = "nick_power",nullable = false)
    @MapKeyClass(Name.class)
    
    private Map<Name,Integer> nicjPower = new HashMap<>();


对于Name 要复写hashcode 和equals 方法.并且,要将Name 声明为 @Embedable
还是一样.组件,作为附表的一部分 p430

组件作为复合主键

 @EmbeddedId
    @AttributeOverrides({
           @AttributeOverride(name = "frist",column = @Column(name = "person_firstName")),
           @AttributeOverride(name = "last",column = @Column(name = "person_lastName"))
    })
    private Name name;


// @EmbeddedId 声明为主键.对于这种,就不需要在Name 上面做任何操作,只需要复写hashcode 和 equals
对于这种,组件的属性直接被添加到主表里面

----------------------------------------------------
hibernater 深入
@ManyToOne  cascade fetch

无连接表的 n  - 1  在n 端添加关系

多个人对应一个地址,只需要通过人找到地址就行,这是在 person 端,在地址端,不做任何操作
    @ManyToOne(targetEntity = Address.class,cascade = CascadeType.ALL)
    @JoinColumn(name = "address_id",nullable = false)
    private Address address;

对于cascade.all ,只需要,在person 端,设置address 直接保存person.后,address,自动级连保存,先插入从表,在保存主表

有连接表的 n - 1  person 端

    @ManyToOne(targetEntity = Address.class,cascade = CascadeType.ALL)
    @JoinTable(name = "person_address",
        joinColumns = @JoinColumn(name = "person_id",referencedColumnName = "person_id",unique = true),
        inverseJoinColumns = @JoinColumn(name = "address_id",referencedColumnName = "address_id"))
    private Address address;

对于   joinColumns 都是映射的主键和外建  unique 以perosn_id 作为唯一性列的参考   只许表中只有一个person id


单向的 1 1 的映射

    @OneToOne(targetEntity = Address.class)
    @JoinColumn(name = "address_id",referencedColumnName = "address_id",unique = true)
    private Address address;

使用unquie 控制唯一性关系

对于mappedBy  表示不控制关系  orphanRemoval  删除孤儿实体  和cascade 两者存在一个就行



无连接表 单项 1 n 在n 端控制 信息.默认的在n 端添加外键

    @OneToMany(targetEntity = Address.class)
    @JoinColumn(name = "person_id",referencedColumnName = "person_id")
    private Set<Address> addresses = new HashSet<>();


对于无连接表中,都已吧控制信息写在n 端,然后在 1 端,接受数据   referencedColumnName  映射到外面去的
对于这样的信息,没有cascade.all 所 (此外必须要先通过先实例化address_inf 才行)insert 外键为空address_inf ,然后在update address_inf 将person 的主键作为
address_inf 的外键.出现这样的原因,是应为 address_inf 不知 perosn_inf ,一直,没有将 person_id 作为自己的属性

可以通过双向的 1 n 链接解决问题   但是 1 端会 多出一条update 性能要比 n端低  p 447 (有点懵逼)


有链接表的单向 1 n 关联 person  unique = true.address 关联一个address 地址,但是person 可以关联多个address
没有cascade 但是应为出现链接表,所以,无论实例化那个都可以   就是会不会出现幽灵数据,可以通过 cascade.all
来阻止这种情况发生  解决,以为有链接表,所以先实例哪一个对象,都可以,对于one 端 cascade.all 写不写,都是要删除附加表的信息
如果,要实现附表的删除,则需要手动删除
 


    @OneToMany(targetEntity = Address.class)
    @JoinTable(name = "person_address",
        joinColumns = @JoinColumn(name = "person_id",referencedColumnName = "person_id"),
        inverseJoinColumns = @JoinColumn(name = "address_id",
                referencedColumnName = "address_id",unique = true))
    private Set<Address> addresses = new HashSet<>();

对于单项的  n n ,必须使用连接表  不能使用 unquie ,如果使用 unquie 则变为 形式上变为 one to many
    @ManyToMany(targetEntity = Address.class)
    @JoinTable(name = "person_address",
        joinColumns = @JoinColumn(name = "person_id",referencedColumnName = "person_id"),
        inverseJoinColumns = @JoinColumn(name = "adress_id",referencedColumnName = "address_id"))
    
    private Set<Address> addresses = new HashSet<>();

对于有链接表的,级连操作,都是第三张表


无连接表的双向1 n 连接
一般采用这种方式 mappedBy 放弃映射关系,可以直接使用

  Peron
    @OneToMany(targetEntity = Address.class,mappedBy = "person")
    private Set<Address> addresses  = new HashSet<>();


Address   n 端控制关系 先持久化 person ,在持久化 address 这样可以保证效率
如果先持久化address 再持久化 person 所以,会产生三条语句,insert address insert person update address

    @ManyToOne(targetEntity = Person.class)
    @JoinColumn(name = "person_id",referencedColumnName = "person_id",nullable = false)
    private Person person;



有链接表的双向 1  n


  Peron
    @OneToMany(targetEntity = Address.class,mappedBy = "person")
    private Set<Address> addresses  = new HashSet<>();

address
    
    @ManyToOne(targetEntity = Person.class)
    @JoinTable(name = "person_address",
        joinColumns = @JoinColumn(name = "address_id",referencedColumnName = "address_id",unique = true),
        inverseJoinColumns = @JoinColumn(name = "person_id",referencedColumnName = "person_id"))
    private Perosn person;

address_id和 person_id 作为主列键  对于有三表,一般都可以吧

看来joinColumns 有多种意思   我觉得这里不应该unique = true  ,这里是正确的   

就是对于多个属性的限制,只是在入库的时候,更加严格,

双向 n n 关联 因为是 n n 所以不能用 unquie

这里的 person_id 和address_id 都是主列键,谁先谁后,都一样,只是,按照一样的顺序,可以少写代码

    
    @ManyToMany(targetEntity = Address.class)
    @JoinTable(name = "person_address",
        joinColumns = @JoinColumn(name = "person_id",referencedColumnName = "id"),
        inverseJoinColumns = @JoinColumn(name = "address_id",referencedColumnName = "id"))
    private Set<Address> addresses = new HashSet<>();


    @ManyToMany(targetEntity = Person.class)
    @JoinTable(name = "person_address",
            joinColumns = @JoinColumn(name = "person_id",referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "address_id",referencedColumnName = "id"))
    private Set<Person> Person = new HashSet<>();


 双向 1 1 对于主表,一端,应该放弃控制关系,要不然,会造成update的性能下降

 
 
    peroson

    @OneToOne(targetEntity = Address.class,mappedBy = "person")
    private Address address;
    
    
    
    address    
    @OneToOne(targetEntity = Person.class)
    @JoinColumn(name = "person_id",referencedColumnName = "id",unique = true);
    private Person person;


https://www.cnblogs.com/SpringSmallGrass/archive/2013/04/06/3002199.html

对于mapped 复习,双边关系,只需要一端维护就可以,拥有段,不用维护,被拥有段需要维护,  在被拥有段建立外键

one one   many many   one many 都可以建立  但是  many to one (控制关系都是n 端维护,)  没有这个属性,,这样的好处是,减少一条的update 语句.性能更好
对于这种级联删除,在拥有段控制关系,对于孤儿,可以通过one to many     one to one  ,启动级联.也就是主表

从表的生命周期完全在主表类可以采用  CascadeTpye.ALL  加 orphanRemoval =true





多主键,多外键,控制关系


 Person
    @Id
    private String firstName;
    
    @Id
    private String lastName;
    
    
    @OneToMany(targetEntity = Address,mappedBy = "person",cascade = CascadeType.ALL)
    
    private Set<Address> addresses = new HashSet<>();
    
Address
    
    @ManyToOne(targetEntity = Person.class)
    @JoinColumns({
            @JoinColumn(name = "person_first",referencedColumnName = "firstName",nullable = false),
            @JoinColumn(name = "person_last",referencedColumnName = "lastName",nullable = false)
    })
    
    private Person perosn;




将成员为主键

原创粉丝点击