.../〉
6参考文裆进行测试(注意文裆中缺少configure()的小bug)
7FAQ:
@不给提示
a)配置eclipse属性信息contentassist-activation--加上@
WhatisandWhy0/RMapping
1JDBC操作数据库很繁琐
2Sql语句编写并不是面向对象的
3可以在对象和关系表之间建立关联来简化编程
40/RMapping简化编程
50/RMapping跨越数据库平台
6Hibernate_0200_OR_Mapping_Simulation
Hibernate基础配置——对应项目:
Hibernate_0300_BasicConfiguration
1介绍MSQL的图形化客户端
2hibernate.cfg.xml:
hbni2ddl.auto:
create、update。
。
。
。
a)先建表还是先建实体类—先建表
3搭建日志环境并配置显示DDL语句
a)slf4j与log4j的关系:
slf4j像是一个大管家,可以管理许多的日志框架,log4j是其中之一
b)加入slf4j-log4j.jar,加入log4j的jar包,去掉slf4-nop.jar
c)从hibernate/project/etc目录copylog4j.properties
d)査询hibernate文裆,日志部分,调整日志的输出策略
4搭建jUnit环境
a)需要注意jUnit的Bug
5hibernate.cfg.xml:
show_sql是否输出SQL语句
6hibernate.cfg.xml:
format_sql格式化SQL语句,美化SQL语句
--格式化显示输出sql-->
true
7表名和类名不同,对表名进行配置
a)Annotation:
@Table
b)xml:
自己査询
8字段名和属性相同
a)不用写@column与默认的@Basic效果一样
b)Xml中不用写column
9字段名和属性名不同
a)Annotation:
@Column
b)xml:
自己査询
10不需要psersistence的字段(不用列)
a)Annotation:
@Transient定义不写入数据库,属性透明
b)xml不写
11映射日期与时间类型,指定时间精度
a)Annotation:
@Temporal(参数)参数有3种只显示时间,只显示日期,时间日期都显示
//@Temporal(TemporalType.DATE)只显示日期
//@Temporal(TemporalType.TIME)只显示时间
//@Temporal(TemporalType.TIMESTAMP)显示日期与时间
b)xml:
指定type
12映射枚举类型(比较少用)
a)@Enumerated
@Enumerated(EnumType.ORDINAL)枚举类型按位置数,如:
0,1,2...存储
@Enumerated(EnumType.STRING)枚举类型按设定值存储
b)xml:
麻烦
13字段映射的位置(field或者get方法)
a)bestpractice:
保持field(变量定义)和getset方法的一致
14@Lob
15课外:
CLOBBLOB类型的数据存取
16课外:
Hibernate自定义数据类型
17hibernate类型
ID生成策略——对应项目:
hibernate_0400_ID
1注意:
a)我们观察hibernate生成表的结构并不是为了将来就用它生成,(可能还有自己的扩展,比如index等)而是为了明白我们应该建立什么样的表和实体类映射
2xml生成id
a)generator
b)常用四个:
nativeidentitysequenceuuid
3注解方式:
@GeneratedValue
a)自定义ID
b)AUTO(直接写@GeneratedValue相当如native)(@GeneratedValue(strategy=GenerationType.AUTO))
i.默认:
对MySQL,使用auto_increment
ii.对Oracle使用hibernate_sequence(名称固定)
c)IDENTITY(@GeneratedValue(strategy=GenerationType.IDENTITY))
d)SEQUENCE(@GeneratedValue(strategy=GenerationType.SEQUENCE))
i.@SequenceGenerator(可自定义在数据库生成指定的sequence名)
@Id
//在@GeneratedValue中增加generator="teacherSEQ"
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="teacherSEQ")
//"teacherSEQ"为@SequenceGenerator的标识名
//"teacherSEQ_DB"为指定到数据库生成的Sequence名
@SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB")
publicintgetId(){
returnid;
}
e)TABLE(可以忘记)
i.@TableGenerator
@TableGenerator(
name="teacherID",//被调用的TABLE名字
table="teacherID_DB",//数据库建立的表名
pkColumnName="key_value",
pkColumnValue="pk_value",
valueColumnName="teacher",//pkColumnValue对应类名
allocationSize=1//pkColumnValue对应类名
)
@GeneratedValue(strategy=GenerationType.TABLE,generator="teacherID")
注:
如果使用注解方式的uuid如下:
@Id
@GeneratedValue(generator="teacherUUID")
@GenericGenerator(name="teacherUUID",strategy="uuid")
4FAQ;
a)用Junit测试时HibernateSessionFactory初始化异常不提示.疑似一个bug
b)用main来做测试
5联合主键
a)Xml方式:
composite-id
i.将联合主键的属性提取出来,重新编写一个pojo类(原pojo类中的id,name要删除并新加入属性“StudentPK”)
publicclassStudentPKimplementsSerializable{
privateStringid;
privateStringname;
……
ii.新建pojo类必须实现java.io.Serializable序列化接口
iii.新pojo类要重写equals和hashCode方法
@Override
publicbooleanequals(Objecto){
if(oinstanceofStudentPk){
StudentPkpk=(StudentPk)o;
if(this.id==pk.getId()&&this.name.equals(pk.getName())){
returntrue;
}
}
returnfalse;
}
@Override
publicinthashCode(){
returnthis.name.hashCode();
}
iv.联合主键生成策略XML配置方法
b)Annotation
i.前三步与Xml方式前三步一样都要建立新pojo类都要实现Serializable接口重写equals和hashCode方法.
ii.方法1在新类前写@Embeddable,在原pojo类的新属性“TercherPK”的get方法前写@ld,如下
@Embeddable
publicclassTeacherPKimplementsSerializable{
privateStringid;
privateStringname;
……
@Entity
publicclassTeacher{
privateTeacherPKteacherPK;
@Id
publicTeacherPKgetTeacherPK(){
returnteacherPK;
}
……
iii.方法2:
@EmbeddedlD(*)新pojo类无需加注解,只需在原pojo类新属性“TercherPK”的get方法前写@EmbeddedlD即可
iv.方法3:
@Id@IdClass(*)新pojo类无需加注解,原pojo类的id,name属性保留不变,也无需新增“TercherPK”属性。
只在id,name的get方法前都加@Id,并在原pojo类前加“@IdClass(TeacherPK).class)”,如下
@Entity
@IdClass(TeacherPK.class)
publicclassTeacher{
privateStringid;
privateStringname;
@Id
publicStringgetId(){
returnid;
}
@Id
publicStringgetName(){
returnname;
}
......
核心幵发接口介绍——hibernate_0500_CoreAPI
1HibernateAPI文档需要单独下载
2Configuration
a)AnnotationConfiguration
b)进行配置信息的管理
c)用来产生SessionFactory
d)可以在configure方法中指定hibernate配置文件
e)只气关注一个方法即:
buildSessionFactory
3SessoinFactory
a)用来产生和管理Session
b)通常情况下每个应用只需要一个SessionFactory
c)除非要访间多个数据库的情况
d)关注两个方法即:
openSessiongetCurrentsession
i.opensession每次都是新的,需要close
ii.getCurrentsession从上下文找,如果有,用旧的,如果没有,建新的
1.用途,界定事务边界
2.事务提交自动close
3.上下文配置可参见xml文件中
thread
4.current_session_context_class(jta、thread常用managed、custom.Class少用)
a)thread使用connection但数据库连接管理事务
b)jta(全称javatransactionapi)-java分布式事务管理(多数据库访问)
jta由中间件提供(jbossWebLogic等,tomcat不支持)
4Session
a)管理一个数据库的任务单元(简单说就是增删改查)
b)方法(CRUD)
i.Save()session.save(对象);
ii.Deletesession.delete(对象);
iii.LoadStudents1=(Student)session.load(Student.class,1);
iv.GetStudents1=(Student)session.get(Student.class,1);
v.get与load的区别(面试重点,原理)
1.不存在对应记录时表现不一样
2.load返回的是代理对象,等到真正用到对象的内容时才发出sql语句
3.get直接从数据库加载,不会延迟
vi.updatessession.update(对象);
1.用来更新detached对象,更新完成后转为persistent状态
2.更新transient对象会报错
3.更新自己设定id的transient对象可以(数据库有对应记录)
4.persistent状态的对象只要设定(如:
t.setName…)不同字段就会发生更新
5.更新部分更改的字段
a)xml设定property标签的update属性,annotation设定@Column的updatable
属性,不过这种方式很少用,因为不灵活(忘记)
b)使用xml中的dynamic-update,JPA1.0Annotation没有对应的属性,hibernate扩
展?
i.同一个session可以,跨session不行,不过可以用merge()(不重要)
c)使用HQL(EjBQL)(建议)
vii.saveOrUpdate()session.saveOrUpdate(对象);
viii.clear方法session.clear();
1.无论是load还是get,都会首先査找缓存(一级缓存),如果没有,才会去数据库査找,调用
clear()方法可以强制清除session缓存
ix.flush()方法session.flush();
1.当session的事务提交后,会强制将内存(session缓存)与数据库同步.默认情况下是session的事务提交(commit)时才同步!
2.session的FlushMode设置,可以设定在什么时候同步缓存与数据库(很少用)
例如:
session.setFlushMode(FlushMode.AUTO)
x.find方法已经过时!
5SchemaExport(自动建表)
newSchemaExport(newAnnotationConfiguration().configure()).create(false,true);
6Query接口
a)参考Hibernate査询(HQLEJBQL)的内容
7Note:
a)Hibernate中涉及很多非常非常细节的区别,但在实际应用中用得极少,请大家先享受写项目的乐
趣,再来探讨这些细节问题
i.比如save和persist的区别
ii.merge、evict等方法
iii.比如refresh、lock等
b)建议的学习方法,动手实验
c)细节问题参考补充视频
1上一个project
2三种状态的区分关键在于
a)有没有ID
b)ID在数据库中有没有
c)在内存中有没有(session缓存)
3三种状态:
a)transient:
内存中一个对象,没ID,缓存中也没有
b)persistent:
内存中有,缓存中有,数据库有(ID)
c)detached:
内存有,缓存没有,数据库有,ID
4对这三种状态需要关注的问题是在该状态下如果进行数据库的操作会发生什么结果,比如改变属性的
值会不会发出update语句?
a)强烈建议动手实验
b)进行正常人的思考
c)绝对不要去背这些东西!
背过也并不代表你有多牛!
关系映射(重要)
对象之间的关系
1这里的关系映射指的是对象之间的关系,并不是指数据库的关系,本章解决的问题是当对象之间处于
下列关系之一时,数据库表该如何映射,编程上该如何对待(红色为重点中的重点)
2简化问题:
a)怎么写Annotation
b)增删改査CRUD怎么写
3—对一
a)单向(主键、外键)
b)双向(主键、外键)
c)中间表
4—对多
a)一张主表,多张子表
5组件映射
a)@Embeddable
b)@Embedded
一对一关联
1一对一单向外键关联
a)项目名称:
hibernate_0600_one2one_uni_fk
b)Annotation:
在被约束表字段的get方法上加@0ne20ne@JoinColumn
@OneToOne
@JoinColumn(name="wifeid")//指定生成的数据库字段名
publicWifegetWife(){
returnwife;
}
c)xml:
在被约束表的xml配置文件中加
unique="true"是保证生成的字段唯一,这样2一对一双向外键关联
a)项目名称:
hibernate_0700_one2one_bi_fk^
b)Annotation:
@0ne20ne(mappedBy=”另一个类里定义的属性名”)
规律:
凡是双向关联,必设mappedBy
在Wife类中写Husband对象属性并添加注解@OneToOne(mappedBy="wife")mappedBy作用
是指定这个一对一关联是被Husband类的wife属性(准确说是getWife方法)做的映射
@OneToOne(mappedBy="wife")
publicHusbandgetHusband(){
returnhusband;
}
在类中写Wife对象属性
@OneToOne
@JoinColumn(name="wifeid")//指定生成的数据库字段名
publicWifegetWife(){
returnwife;
}
此注释将由Husband表中生成wifeid字段作为fk外键,wife表中不生成额外的Husbandid字段
c)xml:
many-to-oneunique在Student类中写StuIdCard属性,StuIdCard类中写Student属性
StuIdCard.hbm.xml文件中加
Student.hbm.xml文件中加
其中,property-ref相当于mappedBy
此方式生成的StuIdCard表中包含studentid字段作为fk外键,Student表中不生成额外的字段
特别说明:
一对一单向外键关联与一对一双向外键关联在数据库的表的格式是一样的,区别在于
java程序中.双向外键关联可通过Hibernate在两个类间互相调用彼此,而单向外键关联只能单方向调用.
3一对一单向主键关联(不重要,忘记)
a)项目名称:
hibernate_0800_one2one_uni_pk
b)@primaryKeyJoinColumn
c)xml:
4一对一双向主键关联(不重要,忘记)
a)项目名称:
hibernate_0900_one2one_bi_pk
b)@primaryKeyJoinColumn(不常用,了解)
c)xml: