尚学堂hibernate笔记_第1页
尚学堂hibernate笔记_第2页
尚学堂hibernate笔记_第3页
尚学堂hibernate笔记_第4页
尚学堂hibernate笔记_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1 新建项目2 学习建立user-library-hibernate,并加入相应的jar包 a项目右键-build path-configure build path-add library b选择user-library,在其中新建library,命命为hibernate c 在该library中加入hibernate所需要的jar包hibernate /hibernate3.jar/lib/required目录下的所有包 6个Sl4j-nop jar3 引入mysql的JDBC驱动包4 在MYSQL中建数据库和相应的表student(id,name,age) 参考文档中COPY,修改对应的

2、数据库连接,6 建立student类7 建立映射文件Student.hbm.xml 参考相应文档8 将映射文件加到hibernate-cfg.xml中搭建日志环境并配置显示DDL语句slf的实现:slf4j nodep ,log4j ,jdk logging api ,apache common-log.slf4j.nop.jar是slf-api.jar其相应的接口实现把slf的接口对到log4j的实现,在user library中hibernate,把slf的实现slf4j-nop-.jar去掉,添加log4j的实现log4j-1.2.15.jar,再添加一个slf-api和log4j转换器

3、slf4j-log4j12-1.5.8.jar.把slf的接口转换成log4j的接口.最后添加一个log4j的配置文件perties利用HIBERNATE导出数据库建表Configuration cfg=new AnnotationConfiguration().configure();(有注解时使用AnnotationConfiguration),configure()可以手动指定配置文件名称.Configuration cfg=new Configuration(),会默认读取perties文件/创建schemaExport对象importddl

4、.SchemaExport;SchemaExport export=new SchemaExport(cfg);/创建数据库表export.create(true, true);对象映射(采用Annotation注解方式)1 建表 Create table teacher(id int primary key,name varchar(20),title varchar(20);2 创建teacher类,并进行注解importy;import ;在bean中加注解 Entity,Id(加在getId()上面)3 在hibernate中加入annotation相应的jar包hibernate-a

5、nnotations.jar/lib目录下加入相应的包ejb3-persistence.jar, hibernate-commons-annotations.jar注意:annotation文档中并没有提到hibernate-annotations.jar包4 参考annotation文档建立对应的注解5 在hibernate.cfg.xml中建立映射 6 示例/AnnotationConfiguration;Configuration cfg=new AnnotationConfiguration();SessionFactory sf=cfg.configure().buildSessio

6、nFactory();Session session=sf.openSession();session.beginTransaction();session.save(t);/session.getTransaction().commit();session.close();sf.close();对象映射(采用配置文件方式)1 在相应的类中建立对应的配置文件. 例如Student类对应的配置文件2 在hibernate.cfg.xml中添加该映射文件即可 注意包名的写法3 示例Configuration cfg=new Configuration().configure();/创建Sessio

7、nFactorySessionFactory sf=cfg.configure().buildSessionFactory();/创建sessionSession session=sf.openSession();session.beginTransaction();session.save(s);session.getTransaction().commit();session.close();sf.close();hibernate.cfg.xml配置hibernate.hbm2ddl.auto属性取值: validate | update | create | create-drop在s

8、essionfactory创建时,自动检查数据结构,或者将数据库schema(表)的DDL导出到数据库,使用create-drop时,在显式关闭sessionfactory时,将drop掉数据库schema.validate 加载hibernate时,验证创建数据库表结构 create 每次加载hibernate,重新创建数据库表结构 create-drop 加载hibernate时创建,退出是删除表结构 update 加载hibernate自动更新数据库结构表名和类名不同的情况时,对表名进行配置1 在注解中import javax.persistence.Table;Table(name=”

9、TableName”)2 在XML文件中 配置对应的table属性为相应的表名字段名和属性名相同,默认为对于annotation,如果什么注解都不写的话,相当于加了注解Basic实体bean中所有的非static非transient的属性都可以被持久化, 除非你将其注解为Transient.所有没有定义注解的属性等价于在其上面添加了Basic注解. 通过 Basic注解可以声明属性的获取策略(fetch strategy):对于XML文件中不用写column.字段名和属性名不同时Annotation:column(name=”column_name”)加上相应的getXXX()方法上XML:c

10、olumn属性不需要persistence的字段import javax.persistence.Transient; Transient 意思是说这个属性是透明的,不进行持久化,存储的时候不存进去映射日期和时间类型,指定时间精度Annotation: import javax.persistence.Temporal;Temporal(TemporalType.TIME)XML:指定typetype=time或date枚举类型的转换Enumerated(EnumType.STRING)字段映射的位置推荐写在gexXXX方法上Hibernate映射类型Hibernate 映射类型 Java 类

11、型 标准 SQL 类型 大小和取值范围 integer 或者 int int 或者 eger INTEGER 4 字节 long long Long BIGINT 8 字节 short short Short SMALLINT 2 字节 byte byte Byte TINYINT 1 字节 float float Float FLOAT 4 字节 double double Double DOUBLE 8 字节 big_decimal NUMERIC NUMERIC(8,2)8 位 character char Character String CHAR(1) 定长字符 string Str

12、ing VARCHAR 变长字符串 boolean boolean Boolean BIT 布尔类型 yes_no boolean Boolean CHAR(1) (Y-N) 布尔类型 true_false boolean Boolean CHAR(1) (T-F) 布尔类型 2 、 Java 时间和日期类型的 Hibernate 映射 映射类型 Java 类型 标准 SQL 类型 描述 date util.Date 或者 sql.Date DATE YYYY-MM-DD time Date Time TIME HH:MM:SS timestamp Date Timestamp TIMESTA

13、MP YYYYMMDDHHMMSS calendar calendar TIMESTAMP YYYYMMDDHHMMSS calendar_date calendar DATE YYYY-MM-DD 3 、 Java 大对象类型的 Hibernate 映射类型 映射类型 Java 类型 标准 SQL 类型 MySQL 类型 Oracle 类型 binary byte VARBINARY( 或 BLOB) BLOB BLOB text String CLOB TEXT CLOB serializable Serializable 接口任意实现类 VARBINARY( 或 BLOB) BLOB B

14、LOB clob jav CLOB TEXT CLOB blob BLOB BLOB BLOB 在程序中通过 Hibernate 来保存 java.sql.Clob 或者 java.sql.Blob 实例时,必须包含两个步骤: 1 在一个数据库事务中先保存一个空的 Blob 或 Clob 实例。 2 接着锁定这条记录,更新上面保存的 Blob 或 Clob 实例,把二进制数据或文本数据写到 Blob 或 Clob 实例中 Hibernate SQL方言 (hibernate.dialect) RDBMS方言 DB2DB2 AS/400DB2 OS390PostgreSQLMySQL.MySQL

15、DialectMySQL with InnoDBMySQL with MyISAMOracle (any version)Oracle 9i/10gSybaseSybase AnywhereMicrosoft SQL ServerSAP DBInformixHypersonicSQLIngresProgressMckoi SQLInterbasePointbaseFrontBaseFirebirdID生成策略1.XML方式配置可选的子元素是一个Java类的名字, 用来为该持久化类的实例生成唯一的标识。如果这个生成器实例需要某些配置值或者初始化参数, 用元素来传递。 uid_table next

16、_hi_value_column 所有的生成器都实现org.hibernate.id.IdentifierGenerator接口。 这是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。当然, Hibernate提供了很多内置的实现。下面是一些内置生成器的快捷名字: l increment 用于为long, short或者int类型生成 唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。 l identity 对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。 返回的标识符是long

17、, short 或者int类型的。 l sequence 在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence), 而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。 l hilo 使用一个高/低位算法高效的生成long, short 或者 int类型的标识符。给定一个表和字段(默认分别是 hibernate_unique_key 和next_hi)作为高位值的来源。 高/低位算法生成的标识符只在一个特定的数据库中是唯一的。 l seqhilo 使用一个高/低位算法来高效的生成l

18、ong, short 或者 int类型的标识符,给定一个数据库序列(sequence)的名字。 l uuid 用一个128-bit的UUID算法生成字符串类型的标识符, 这在一个网络中是唯一的(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。 l guid 在MS SQL Server 和 MySQL 中使用数据库生成的GUID字符串。 l native 根据底层数据库的能力选择identity, sequence 或者hilo中的一个。在mysql中默认的是auto_increment,SQLSERVER中是identity.l assigned 让应用程序在save()之

19、前为对象分配一个标示符。这是 元素没有指定时的默认生成策略。 l select 通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。 l foreign 使用另外一个相关联的对象的标识符。通常和联合起来使用。 l sequence-identity 一种特别的序列生成策略,使用数据库序列来生成实际值,但将它和JDBC3的getGeneratedKeys结合在一起,使得在插入语句执行的时候就返回生成的值。目前为止只有面向JDK 1.4的Oracle 10g驱动支持这一策略。注意,因为Oracle驱动程序的一个bug,这些插入语句的注释被关闭了。(原文:Note comments on

20、 these insert statements are disabled due to a bug in the Oracle drivers.) 2 annotation中配置id生成策略使用Id注解可以将实体bean中的某个属性定义为标识符(identifier). 该属性的值可以通过应用自身进行设置, 也可以通过Hiberante生成(推荐). 使用 GeneratedValue注解可以定义该标识符的生成策略: 有四种策略l AUTO -默认值.可以是identity column类型,或者sequence类型或者table类型,取决于不同的底层数据库.对于MYSQL,是auto_in

21、crement,对于Oracle是hibernate-sequence.l TABLE - 使用表保存id值 (了解)l IDENTITY - identity column l SEQUENCE - SequenceGeneratorGeneratedValue(strategy=GenerationType.XXXX)XXXX取值为Type.SEQUENCE|TABLE|AUTO|IDENTITY不同的数据库对应着不同的生成策略.例1实体类注解Entity主键进行注解IdGeneratedValue 默认值是GeneratedValue(strategy=GenerationType.AU

22、TO)例2使用SequenceGeneratorEntitySequenceGenerator(name=teacher_SEQUENCE,sequenceName=teacher_SEQUENCE_DB)name是用户自定义的generator生成器的名字, sequenceName是生成到数据库后sequence对象的名字.在实体中注解好后,就可以在id注解上写上对应的IdGeneratedValue(strategy=GenerationType.IDENTITY,generator=teacher_SEQUENCE)例3表生成器(了解),这种方式会另外生成一个表.实体类注解Entity

23、javax.persistence.TableGenerator(/了解,更适合用于跨平台跨数据库. name=TEACHER_GEN, /生成器generator的名字 table=GENERATOR_TABLE,/生成的表名 pkColumnName = pk_key,/生成的表的字段名 valueColumnName = pk_value,/生成的表的字段的值 pkColumnValue=teacher,/ pk_key字段的值 allocationSize=1/自增变量)主键注解IdGeneratedValue(strategy=GenerationType.TABLE,generat

24、or=TEACHER_GEN)l 联合主键生成策略一般采用这种方式,比如有一个类Student(id,name,age),为了产生联合主键,把id和name分离出来.Student(pk,age) StudentPk(id,name)StudentPk类必需实现序列化接口implements.StudentPk类必需重写boolean equals() ,int hasCode()方法Overridepublic boolean equals(Object o) if(o instanceof StudentPk) StudentPk pk = (StudentPk)o;if(this.id

25、= pk.getId() & .equals(pk.getName() return true;return false;Overridepublic int hashCode() return .hashCode();联合主键生成策略XML配置方法联合主键生成策略annotation配置方法定义组合主键的三种方式:l (少用)将组件类注解为Embeddable,并将组件的属性注解为Id.实体模型Teacher(teacherPK,age) TeacherPk(id,name)在TeacherPk(id,name)中把类注解Embeddable在Teache

26、r(teacherPK,age)中把组件属性teacherPK注解Idl 将组件的属性注解为EmbeddedId. 实体模型Teacher(teacherPK,age) TeacherPk(id,name)只需要在Teacher(teacherPK,age)中把组件属性teacherPK注解EmbeddedIdl (推荐使用)将类注解为IdClass,并将该实体中所有属于主键的属性都注解为Id. 实体模型Teacher(id,name,age) TeacherPk(id,name)在Teacher(id,name,age)中把类注解IdClass(value=”TeacherPk.Class”

27、),在主键属性id,name上注解Id即可.当IdClass()中只有一个属性默认写成IdClass(TeacherPk.Class).也就是说Teacher里面的组件属性id,name,合起来刚好是类TeacherPk.对象的三种状态三种状态的区别在于:有没有ID,ID在数据库中有没有,在内存中有没有(session缓存)三种状态Transient:内存中的一个对象,没有ID,缓存中也没有Persistent:内存中有,缓存中有,数据库中有IDDetached:内存中有,缓存中没有,数据库有ID核心接口开发介绍Configuration1 AnnotationConfiguration2 进

28、行配置信息的管理3 用来产生SessionFactory:buildSessionFactory()4 可以在configure()方法中指定hibernate配置文件SchemaExport可以在程序中控制生成建表语名.位于包import org.hibernate.tool.hbm2ddl.SchemaExport;create(booleanscript,booleanexport)script - print the DDL to the console export - export the script to the databaseConfiguration cfg=new An

29、notationConfiguration().configure();SchemaExport export=new SchemaExport(cfg);export.create(true, true);或者new SchemaExport(new AnnotationConfiguration().configure().create(false, true);SessionFactory1 用来产生和管理sesssion2 通常情况下,每个应用只需要一个SessionFactory,除非要访问多个数据库的情况3 openSession()与openSession()l openSess

30、ion()总是创建新的session,需要手动close().l getCurrentSession()事务自动提交并且自动关闭.从上下文环境中获得session,如果当时环境中不存就创建新的.如果环境中存在就使用环境中的,而且每次得到的都是同一个session(在session提交之前,提交之后就是新的了).用途:界定事务边界.l 所谓的上下文参见配置文件thread取值范围 jta | thread | managed | custom.Class JTA简介Session管理一个数据库的任务单元,即管理数据库中的增删改查操作,提交事务.方法CRUD:save(),delete(),upd

31、ate(),saveOrUpdate(),load(),get(),clear().session.beginTransaction();session.save(Object obj);session.getTransaction().commit();session.close();get()与load()的区别l 查找时,都会优先从session的缓存中查找.l 查找不存在对应记录时,表现不一样.load方法查找不到时不会报错,get查找不到时会报错.l Load返回的是代理对象,等到真正要用到对象的内容时才发起SQL语句.get直接发起SQL语句从数据库中取出,不会延迟.Update(

32、)方法1 用来更新detached对象,更新完成之后成为persistent.2 更新transient对象会报错. 更新自己设定id(前提是id在数据库中存在)的transient对象可以.3 持久化的对象只要设定不同字段就会发生更新4 更新部分更改的字段(三种方法)l XML设定property标签的update=true|false属性,annotation设定Column(updatable=false)属性,这种方式少用,不灵活.l XML设定class标签的dynamic-update=”true”属性,同一个session中可以,跨session不行.跨session时的实现方法

33、不过可以用session的merge().merge方法会先从数据库load,将得到的和数据库中的进行对比,再update更改过的字段.JPA1.0 Annotation没有对应的属性,Hibernatel 使用HQL(EJBQL)(建议使用)clear()方法:清除session中的缓存.调用clear()方法会强制清除session缓存.不会与数据库打交道.flush()方法:当session的事务提交后,会强制进行从内存(session缓存)到数据库的同步.默认情况下是session的事务提交时才同步.不常用.Query接口关系映射这里的关系映射指的是对象之间的关系,并不是指数据库的关系

34、. 关系映射解决的问题是,当对象处于各种关系时,数据库表该如何映射,编程时如何处理.一对一:单向(主键,外键),双向(主键,外键)一对多:单向,双向(和多对一双向相同)多对一:单向,双向(一对多双向和多对一双向是一样的)多对多:单向,双向(一对一单/双向主键关联映射,只作了解)集合映射:list ,map,set继承映射(了解):单表,多表,一张主表多张子表组件映射:Embeddable,Embedded一对一(one to one) 单向关联映射两个对象是一对一的的关系.有两种策略可以实现一对一的关联映射l 主键关联:即让两个对象具有相同的主键值,以表明他们之间的一对一的对应关系;数据库表不

35、会有额外的字段来维护他们之间的关系,仅通过表的主键关系来维护.一对一主键关联映射默认了级联属性,其关联对象会同时存储.所以不会抛出TransientObjectException异常.l 唯一外键关联:外键关联,本来是用于多对一的配置,但是如果加上唯一的限制之后,也可以表示一对一的关联关系. unique=true.单向关联,如Person-person_id;加载person信息时能关联对应的person_id信息双向关系,加载任何一方,都能关联出别一方的信息.注意id的主键生成策略,foreign使用另外一个相关联的对象的标识符。通常和联合起来使用。类Person(id,name,idCa

36、rd), 类IdCard(id,cardNo)一对一(单向)基于主键关联映射(了解)XML配置方法一对一单向主键关联通常使用一个特定的id生成器。 idCard one-to-one不会加载字段,它告诉HIBERNATE怎样加载其引用对象.如何加载呢,默认根据主键加载其引用对象.如在t_person中查到id=2,自动加载t_idCard中id=2的对象信息. constrained=true,表明person主键是个外键,表示当前主键上存在着idCard约束,当前主键id作为外键,参照了idCard.idCard表明person中的id来源于idCard,也就是共享idCard的主键.Ann

37、otation配置一对一(单向)主键关联映射.(BUG)OneToOnePrimaryKeyJoinColumn有BUG,系统不会生成主键映射.推荐使用XML配置方法.一对一(单向)基于外键关联映射和单向多对一关联几乎是一样的。唯一不同的就是单向一对一关联中的外键字段具有唯一性约束。这种方法会在表中生成一个新的外键字段.如果不限制外字段的唯一性约束,就会导致产生多对一的关联. 指定多的一端unique=true,这样就限制了多的一端的多重性为一. 这种状态注意TransientObjectException异常.在保存时就先保存外键idCard,再保存Person类.一对一单向外键关联Anno

38、tation配置OneToOneJoinColumn(name=指定生成的外键字段名字)一对一(双向)主键关联映射(了解)PersonIdCard.在另一端也加上一个一对一的单向关联映射.模型对象Person(id,name,idCard) IdCard(id,cardNo,person)中,双方都持有对方的属性引用.一对一(双向)主键关联映射XML配置方式在IdCard配置中建立映射,指示Hibernate如何加载,默认情况下根据主键加载.也就是在基于单向一对一的映射中, 在另一端也加上一个单向一对一的主键关联映射.在Person一端配置 idCard 在另一端IdCard配置 一对一(双向

39、)主键关联映射Annotation(有BUG)在两端各自的引用属性上加上OneToOnePrimaryKeyJoinColumn一对一(双向)唯一外键关联映射Person-IdCard.在另一端也加上一个一对一的单向关联映射.在模型对象Person(id,name,idCard) IdCard(id,cardNo,person),双方都持有对方的属性引用.需要在另一端加上,指示hibernate如何加载,默认情况下根据主键加载person;因为外键关联映射中,两个实体的关系是由person的外键idCard来维护的,所以不能指定person的主键来加载person,而应根据person的外键i

40、dCard来加载person对象.一对一双向外键关联映射XML配置方式Person一端:用多对一配置外键唯一形成一对一的配置方式. IdCard一端:一对一,引用另一端外键 要想加载idCard,如果不加property-ref,默认根据person主键id来加载,property- ref=idCard就指示hibernate从person里面的idCard属性来加载.一对一双向外键关联映射Annotation配置方式双方互持对方的属性的引用关系模型Husband(id,name,wife) Wife(id,name,husband)在Husband一端的wife属性上注解OneToOne/

41、JoinColumn在Wife一端的husband加上注解,mappedByOneToOne(mappedBy=wife)引用属性加上mappedBy属性后就可以在wife这一端告知这个关联是在wife属性上设置的.就不用管理wife这一端生成的husband的设置.生成的wife表格不会有husband字段.规律:有双向关联时mappedBy通常必设.联合主键一对一单向外键关联映射对象模型Wife(id,name,age) WifePk(id,name)Husband(id,name,wife)1 在Wife中建立联合主键生成策略 IdClass(WifePk.Class) Id2 在Hus

42、band中添加个外键即可 OneToOne3自定义Husband中外键的名字 OneToOneJoinColumns(JoinColumn(name=wifeId, referencedColumnName=id),JoinColumn(name=wifeName, referencedColumnName=name)XML配置方式:略组件映射对象关系:一个对象是另一个对象的一部分数据库表:是一张表Annotation:Embeddable,EmbeddedXML:对象模型Husband(id,name,wife)Wife(wifeName,wifeAge)Annotation:在Husban

43、d的wife属性上建立注解Embedded 表明该对象是从别的位置嵌入过来的,是不需要单独映射的表.这种方式生成的表为husband(id,name,wifename,wifeage),不会生成wife表.AttributeOverride注解可以覆盖该属性对应的嵌入式对象的列映射:XML: 多对一(many to one)单向关联映射多对一的数据库设计原则:在多的那下端加外键/注意在创建实体类属性时应尽量避免与SQL语句中的关键字重名.多对一单向关联映射实体模型(User多对一Group)User(id,name,group)多Group(id,groupname)一Annotation配置

44、EntityTable(name=t_group)/注意表名与SQL中关键字重名只需要在多的一端User属性group进行注解配置ManyToOneJoinColumn(name=”groupId”)XML配置标签会在”多”的一端添加外键,相当于在数据库中添加外键生成的表为user(id,name,groupid),t_group(id,groupname)属性cascade取值all,none,save-update,delete,对象间的级联操作,只对增删改起作用.在存储时User时,设置了cascade=all会自动存储相应的t_group.而不用管user关联的对象(通常情况下会优先存储关联的对象,然后再存储user).一对多(one to many)单向关联映射模型(group一对多user)Group(id,name,users)一User(id,name)多设计时在一的这一端存在着多的集合,生成的数据库表通常是在多的一端生成外键.Set users=new HashSet()一对多单向外键关联映射在一的这一端Group端users属性上进行注解配置O

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论