注解
注解:描述数据的数据;
可以用来生成文档,检查代码间的依赖关系,帮助编译器做语法检查等。
@Deprecated,表示一个已经过时的方法;
@Retention(RetentionPolicy.RunTime)
public @interface MyTable{
方法:
}
Hibernate上的注解
放在类上的,
@Entity
@table(
name:表名
)
放在属性上的:
对于ID
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
//主键生成器:Auto--主键由程序控制
table--使用一个特定的数据库表来保持主键
sequence主键由数据库序列生成(Oracle),与generator一起使用
@Transient 注释的字段不会被持久化
@genericGenerator(name="hbincrement",strtegy=increment(用hibernate本身的注解包,))不建议使用
@Column(name="pk_id")
对于其他属性,这些注解还可以写在对应的属性的get方法上面
@Column(name="对应的表名",columnDefinition="类型")
@Temporal(TemporalType.DATE)
日期类型的注解,只能用在util.Date类的日期中
乐观锁(先查询再修改)
@Version
基于注解关系映射(一对多)
/**
*一对多和多对一,一方有多方的Set集合
*/
@OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL,targetEntity=Order.class)
@JoinColumn(name="fk_customer_id")
fetch表示加载方式,EAGER表示立即加载,LAZY表示延迟加载
cascade表示级联操作,注解中默认由多方维护外键;
targetEntity:多方的类字节码(可选字段)
JoinColumn(name="一方在多方表中代表的表名")
多方的注解
@ManyToOne(fetch = FetchType.LAZY)//属性可以不定义
@JoinColumn(name="fk_customer_id")
@option (指定关联方是否为空null).
a)false:外键不允许为空
b)true:可以为空
多方不用指明1方的类字节码
多方只需要设定加载方式,以及一方在多方表中的列名
@mappedBy="user":定义类之间的双向关系,该属性值为被关联类中指向自己的属性;只有双向关系才需要定义这个属性(相当于inverse)
一对一注解
/**
注意:一对一关联不能用一方的主键做另一方的主键。在注解模式中。
单向一对一。
被关联的一方不需要设置@OnetoOne,
关联的一方才设置
*/
@OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="外键列名",referencedColumnName="参考的另一个表中的哪一列",unique=true)
/**
双向一对一,就是用主键关联。
被关联的一方不需要设置@OnetoOne,
关联的一方才设置
其余属性照常
*/
/**
无外键关联方
一般外键维护是交给有外键的关联方
并且这边就不需要些joinColumn了
*/
@OneToOne(mappedBy="另一方中关联本方的属性名,将外键维护交给对方",cascade=CascadeType.ALL)
/**
有外键的关联方
*/
@OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="外键列名",referencedColumnName="参考的另一个表中的哪一列(可不写)",unique=true)//表示唯一性
多对多注解(因为外联的是中间表,一般级联操作都是all,就算是删除也是删除中间表中的属性)
例如学生对课程,这边是学生。
@ManyToMany(mappedBy="另一方该对象的属性名",cascade="一般是All")
关系维护方
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(
name="t_course_stu",
joinColumns=@JoinColumn(name="pk_fk_cid"),
inverseJoinColumns=@JoinColumn(name="pk_fk_sid")
)
继承关系的注解
所有类都在一张表)
#####父类
//写在类上,
@Entity
@Table(name="表名")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE (这个是父类和所有子类都在一张表))
@DiscriminatorColumn(name="描述子类的列,可以是数字,字母,单词等")
@DiscriminatorValue("父类在上面表示的列中代表的符号")
#####子类
写在类上
@DiscriminatorValue("该子类描述符")
写在特有属性上
@Column(name="对应的列名")//可以不用写
子类的属性放在子类表中,父类的属性(通用的属性)放在父类表中 Join方式)
父类
//写在类上
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
子类
//写在类上
@PrimaryKeyJoinColumn(name="子类id")
多表查询
fetch关键字强制Hibernate进行集合填充操作
如:from TUser user inner join fetch user.addresses
这里的”fetch”关键字表明TAddress对象读出以后立即填充到对应的TUser对象
(addresses集合属性)中。
join,跟sql 的链表并没有多大区别
以上的表在sql里面类似这样
select * from TUser user inner join TAddresses addresses;
如以上这样查询,会同时查到两种对象,User和Address对象,address属于User,所以我们添加一个关键字,fetch,这样将查到的每个address自动填充到对应的User中,就会返回一个··List··给我们
没有的话,就会返回一个对象数组给我们(),其中可能包含了User对象和address 对象,我们想要阅读的话,可以使用一个for循环加instance of判断
for(int i = 0 ;i < list.length ; i++){
if(rs[i] instanceof User){
(User)rs[i].getUserName()
}
else{
(Address) rs[i].getAddressPlace();
}
}
左链接
显示 left join 左侧表中的所有行, 即使有些行对应的右侧的表在右侧表中的的值是 null ,因为链表会有个t1.fk = t2.xx;因此,假如在 t2.xx为null,t1.fk引用不到,也会在查询结果中显示 这行结果记录,否则不会显示。
映射查询,其实就是查询一条记录的某一个列或多个列。
每个实体类一张表)
//写在类上
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
子类
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)