Hibernate基础.docx
- 文档编号:24413731
- 上传时间:2023-05-27
- 格式:DOCX
- 页数:44
- 大小:3.28MB
Hibernate基础.docx
《Hibernate基础.docx》由会员分享,可在线阅读,更多相关《Hibernate基础.docx(44页珍藏版)》请在冰豆网上搜索。
Hibernate基础
准备Hibernate:
hibernate-distribution-3.5.0-Final-dist.zip包含了Annotation文件
虽然自带了slf4j.jar但是,只是类似借口,并没有实现,所以要单独下载。
部署:
最原始的hibernate(8个包,用到Annotation还要加3个包,下面讲)
需要hibernate-distribution-3.5.0-Final-dist.zip\lib\require下的6个包
+slf4j.jar+hibernate3.jar(记住连接数据库要jar包也要)
注意:
hibernate自带的是:
而需要的是:
nop:
nodependent。
如图:
准备Annotation:
引入如下包:
(Hibernate3.5集成了annotation所以只要引入
,位于
hibernate-distribution-3.5.0-Final-dist.zip\lib\jpa下)
配置1:
xml version='1.0' encoding='utf-8'?
>
DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"
-- Database connection setting配置数据库连接 -->
>com.jdbc.mysql.Driver
>jdbc: mysql: //localhost/hibernate
>root
>1311
-- JDBC connection pool (use the built-in)一般都用web服务器的连接池,所以将它注释 -->
-- >1
-- SQL dialect,方言,各个数据库之间语句是有区别的,hibernate统一了调用各个数据库的查询时调用的方法,只要指明用哪种数据库,它就知道该针对数据库生成什么样的语句。
-->
>org.hibernate.dialect.MySQLDialect
-- Enable Hibernate's automatic session context management -->
>thread
-- Disable the second-level cache -->
>org.hibernate.cache.NoCacheProvider
-- Echo all executed SQL to stdout -->
>true
-- Drop and re-create the database schema on startup
hbm:
是hibernatemapping,2:
to,ddl:
datadefinedlanguage,数据定义语言。
也就是建表语句,有四个值,create,create-drop,update和validate,create就是如果这张表不存在就创建,update,如果表结构不同,自动增删。
Create-drop就是显示关闭sessonFactory的时候,就drop表,validate就是每次操作数据的时候,都会检查数据库中表和程序中的表是否相同,或者是配置中的表是否和数据库的一致。
-->
>update
—mapping文件的位置,注意是/不是点-->
>
保存成hibernate.cfg.xml放于classpath下,src下(cfg就是configuration)
Xml配置2映射文件:
配置实体的mapping文件,记住,hibernate要求这个配置文件和实体放在一起。
比如:
Student.hbm.xml.
—这个package是指明你要映射哪个包里面的类-->
—这里可以只写name,只指定类名,hb会自动找同名的表,数据库中表不区分大小写-->
—id就是primarykey-->
—当然你也可以只指定name属性,因为我们一般都是类的属性和表里面的字段是同名的,只要写一个hb会自动这样认为。
如:
—property就是非主键之外的,和上面一样,只指定name就默认表字段的和类的属性同名-->
>
Mapping文件实例:
假设:
类Student有id,name,age属性。
>
Ok!
使用语句:
使用Annotation
Id就是key标注在id变量的getter方法上面。
配置文件:
注意是点。
不是正斜线
使用语句:
注意,这次的Configuration是AnnotationConfiguration。
让Hibernate记录日志。
Hibernate使用的是slf4j,Slf4j只是一个接口,是一种标准,只要实现这个标准的类,都可以在heibernate里面记录日志。
可以有如下的日志记录类来实现此接口:
其中slf4j也有自己的实现类。
其中slf4j-api-1.5.8.jar,就是slf4j的接口api。
slf4j-nop-1.5.8.jar就是它的实现类。
(nop:
nodependent)
开始实现:
首先,去除slf4j-nop-1.5.8.jar引入log4j.xxx.xx.jar
但是,它们不能够对应的起,还需要引入slf4j-log4j12-1.5.8.jar的转换类。
如下图:
但是log4j还需要一个log4j的properties的文件,这个文件可以去hibernate包里面搜索。
完成。
搭建junit的环境
1.要引入junit的包(注意,如果是建立userlibrary,不要建立叫juint的,因为会和eclipse自带的junit会有重名。
如果还用到hamcrest,记得引入)
2.要进行测试的时候,自己新建一个资源包来存放测试类,包名和测试的报名一致。
3.注意bug。
junit会有一个bug,就是在配置文件错误的时候,不报错,解决方法:
将生成sessionfactory的时候,用trycatch包围即可。
或者用一个main方法,将@beforeClass所在的方法,写在main方法里面,然后用application方式启动调试。
show_sul和format_sql
show_sql是否让slq在终端输出。
format_sql就是让sql语句更美观。
)(不再是一行)
表名和类名不同解决
在上面加@Table(name=”表名”)
注意@Table是在:
包当中的,否则会有很多错误。
属性名和字段名不同。
如果属性名和字段名不同,需要在属性名上面指定字段名:
注意:
用注解方式的类的属性,默认的getter方法上都有@Basic注解,不写默认也是@Basic,而配置文件方式的字段如果不指定,那么表中就会没有,而注解方式类中的属性就是字段。
指明字段方式:
getter上写@Column(name=”字段名”);
注意,这个的包也是
不需要持久的属性
@Transient意思是:
短暂的,就是不需要持久了。
这样数据库中就没有相应的字段了
在xml配置中不写属性就是不参加持久化了,就没有字段了
日期定制
如果属性的类型是:
Date类型的,则数据库在字段中是:
DateTime类型的对应
这样会记录下日期和时间。
如果只想记录日期或者只想记录时间的话需要在响应的字段上面写上:
注意:
如果完整写的话:
@Temporal(value=TemporalType.DATE);
但是如果是只有value这个属性的话可以省略,所以变成:
@Temporal(TemporalType.DATE);这样就只记录日期,同时数据库的字段也成Date了(默认是TemporalType.TIMESAMP记录时间和日期)
在xml配置里:
或者:
枚举类型映射
在xml中配置枚举十分麻烦,此处不讲。
用Annotation来映射枚举的属性。
。
例如:
你的枚举类是:
pulbicenumTeacher(){
A,B,C}
如果设置的是:
privateTeacherteacher;
Teacher.setTeacher(Teacher.A)
如果是EnumType.STRING那么,数据库中存放是的这个值的名字A,字段是Varchar类型的。
如果是用EnumType.
则存放的是对应顺序的数字。
字段也是int类型的
ID生成策略
Xml的配置的id生成器的配置:
如果是uuid则要求主键id是Strring类型的
如果是native则要求是int的类型的。
Annotation的声明id生成策略的方式:
如果是Identity的话,支持mysql和sqlserver,不支持oracle
要支持Oracle用的sequence的
但是它要多一个生成器,并指定生成器的名字。
生成器在class位置指定。
Name是这个生成器的名字,id上的生成器generator就是根据这个来匹配的。
sequenceName:
指的是数据库中的生成器的名字。
联合主键
Xml配置的联合主键的设置:
联合主键就是:
当多个字段才能唯一确定一条元组的时候,这多个字段就是联合主键。
例如:
有student,idnameage等属性,现在我们假设id和name才能唯一确定一条记录(其实id就可以,这里为了试验假设id和name)
那么这个student的类就可以新建一个类来包容这2个字段,来作为这个student类的主键。
例如:
ClassStudent_key{
Pirvateintid;
PrivateStringname;
….它们的getter和setter
}
这样Student就成为了:
ClassStudent{
PrivateStudent_keykey;
Privateintage;
….其他getter和setter.
}
然后在xml中配置:
不是原来的:
这样就配置好了,但是Student_key要实现hashcode,来实现快速定位查找,然后用equals来分辨是否先等,和serializable接口(没有实现什么方法,是一个标记接口。
)
对于为什么要实现接口的说明:
如果将多个对象student放入内存的hashTable中,那么先算出他们的hashcode才知道放在那里,相同的hashcode的对象放在一起。
如图
相同的hashCode的student对象被放在一个hashcode表中,当要取的时候,先算出那个要去的hashcode的范围,就快速定位某个hashcode的范围了。
然后根据equals方法来取得(注意:
hashcode当然是根据key例如:
Student_key来计算出来的,所以联合主键要实现hashcode和equals方法。
)
Annotation方式来声明联合主键:
方式1:
与上例一致,要写出一个类,作为联合主键:
在这个类上写上@Embeddable可被嵌入的
然后在类中引用这个复合的主键:
Annotation方式来声明联合主键:
方式2:
这个方式更加方便,减少了在复合类上的声明语句@Embeddable,直接在复合主键类的引用处写上
就可。
Annotation方式来声明联合主键:
方式3:
直接在原来的Student类中设置id和name的@id声明
然后在Student类上指定这2个属性所构成的类名
要写这个类名的原因:
由于我们要面向对象编程,虽然我们写入数据库时不要利用的TeacherPk这个类,但是,我们从数据库取得数据的时候,要用到它,直接在内存中接到一个TeacherPk对象。
常用类的介绍
Configuration和AnnotationConfiguration
其中Configuration是xml配置文件时候用的,annotationConfiguration是Annotation时候用的。
例子:
Configurationconfiguration=AnnotationConfiguration.config(“hibernate.xml”);
//这里用注解方式获取configuration
//如果配置文件在src下不叫hibernate.cfg.xml时候config加上参数
//config这个方法一调用,hibernate就会去解析hibernate.cfg.xml文件。
SessionFatorysessionFactory=configuration.getSessionFactory();
Sessionsession=sessionFactory.getCurrentSession();
//Sessionsession=sessionFactory.openSession();
//注意2种方法获得session的不同,
//getCurrentSession是获取当前的session,如果有就直接拿,没有再创建,
//而openSession是每次都创建!
建议用getCurretnSession方法。
session.beginTransaction();
session.save();
session.getTmit();
注意:
如果是getCurrentSession不用调用close方法来关闭session,而是commit的时候就自动关闭了session。
但是openSession必须调用close方法类关闭session,
Hibernate对象的3种状态。
分别是:
Transient:
水态
Persistent:
持久
Detached.:
脱管
首先:
对象new出来的时候,是没有id的。
此时:
状态:
Transient
对象id:
无
缓存中id:
无
数据库id:
无:
然后:
session调用save方法,对象生成了id,其实session中有一个HashMap,将对象的id作为了key,value存放了对象的引用,这样的缓存以便快速读取。
此时:
状态:
Persistent
对象id:
有
缓存中id:
有
数据库id:
无:
过程如图:
最后:
调用commit方法,将数据存入数据库。
Session自动关闭(指的是getCurrentSession),session自动释放,hashMap自然也没有了,
此时:
状态:
Detached
对象id:
有
缓存中id:
无
数据库id:
有:
Session
Session主要是帮助我们对数据库进行增删改查功能。
在session中可以进行一系列的增删改查,然后事务一提交,数据库就产生变化了。
增:
Session的save方法,上面提及,3种状态。
删:
Session的delete方法,简单,不用讲。
查:
Session的load,和get方法。
方法最后得到的对象是一样的,但是,load和get有着重大的区别。
首先,get方法是发起get这条语句,马上去数据库用sql语言得到
对象,就算session关闭了,对象继续可以使用。
但是load方法不是得到对象,而是产生对象的一个代理,只有使用到这个对象的时候才产生sql语句去数据库得到结果。
如果session关闭,则不能使用了。
改:
当一个对象load或者get到session中,成为了persistent状态的时候,如果在session中修改了对象,当commit,或者close的时候,session发现session中的对象和数据库中的对象不同了,发生修改了,这时候,数据同步,它会自动的帮你发出sql语句,update数据库中的对象。
(全部的字段都更新)
由于更新一个字段会更新所有字段的,这样非常没有效率,所以可以照一下方法让有的内容比较多的字段不用更新:
方法1:
在列这个属性上增加updatable=false就可以了,注意:
当设置了这个值,永远都不会更新了!
Xml的配置:
方法2:
只能在xml配置上使用部分自动不更新,动态的更新字段。
在class的标签中写上如上语句,哪条语句更新就只更新那条语句。
Session的saveOrUpdate()方法,是根据场合不同自动保存或者更新对象。
Session的clear方法,由于get和load方法都会先在缓存中查找,没有才去数据库中get或load,用clear可以清除在session的hashMap中的所有对象,这样就直接到数据库中查找。
Session的flush方法,flush就是强制让缓存和数据库中的内容进行同步。
Commit的时候,自动进行fulsh
flush的模式:
关系映射
1对1,单向外键关联(Annotation)
例子:
Husband和wife就是one2one
Husband定义:
其中包含了一个wife的引用。
并用@OneToOne来关联wife。
Wife定义:
这样hibernate就自动生成了2个表:
在husband中就自动有了wife的外键。
但是如果我们不喜欢它自己生成的这个wife_id的名字,可以用如下方法:
joinColumn的name就是代表的就是外键名。
1对1,单向外键关联(xml)
学生和学生卡。
(卡就不列出来了)
Xml中的配置:
注意:
虽然是1对1,但是用的是many-to–one的标签,只要写上unique=true就代表1对1
Name指的是映射的class的名字,column指的是外键的名字。
生成如图:
1对1,双向外键关联(Annotation)
在每个引用上加@OneToOne的Annotation。
Wife有husband的引用
Husband有wife的引用。
在数据库生成的表是:
就可以了。
但是,你会发现,2个表自个都有对方的外键,这个是冗余的数据,我们要去除其中一个,
那么我们去除wife中husband的引用。
(
)
在wife的husband的getter方法上改成:
这个@OneToOne的意思是:
主导的外键是,(getterHusband,得到husband,)husband中的wife(注意,wife它会在husband的getter方法中找getWife(),不是直接找变量wife),那么wife中的husband就无效了,得到的表是:
1对1,双向外键关联(xml)
联合主键的映射
当2个表中的某一个表的主键是联合主键(多于一个主键)时候的映射。
假设:
wife有id和name来作为主键:
那么wife的主键可以这样声明:
(3中方法中的一种,忘记了看上面的联合主键设置
,这种是设置@IdClass和属性的@id
2种是@Embeddable然后那个类嵌入在主键类中,并在getter上写@Id
3种是@EmbeddId,直接将id类嵌入在主键类中,并在id类getter方法上标注@EmbeddId即可)
注意:
wifePK。
cl
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Hibernate 基础