Hibernate完全学习文档

1.Hibernate引用jar文件,建立hibernate.cfg.xml,并配置好改文件.

2.方言:<propertyname="dialect">org.hibernate.dialect.MySQLDialect</property>

3.使用xml建立Helloworld!

(1)xml配置映射实体类:(Class.hbm.xml)

<classname="Class">

<idname="id"></id><!--主键-->

<propertyname="age"></property><!--属性-->

</class>

(2)在hibernate.cfg.xml中配置:<mappingresource="cn/bywei/model/Class.hbm.xml"/>

(3)使用Session

Configurationcfg=newConfiguration();

SessionFactorycf=cfg.configure().buildSessionFactory();

Sessionsession=sf.openSession();

session.beginTransaction();

session.save(model);

session.getTransaction().commit();

session.close();

sf.close();

4.使用Annotation建立HelloWorld!

jpa:javax.persistence.Entity;(JPA是一套非常好的标准)

(1)建立一个Model类,使用注解@Entity标识实体类@Id标识主键@GenertedValue标识自动增长列

(2)在hibernate.cfg.xml中配置:<mappingresource="cn.bywei.model.Class"/>

(3)使用Session:

Configurationcfg=newAnnotationConfiguration();

SessionFactorysf=cfg.configure().buildSessionFactory();

Sessionsession=sf.openSession();

session.beginTransaction();

session.save(Model);

session.getTransaction().commit();

session.close();

sf.close();

---------小技巧----------

1.使用注解@提示:设置contentAssist

-------------------------

5.O/RMapping面对对象的操作

Hibernate.cfg.xml基础配置

1.<propertyname="hbm2ddl.auto">create/update/create-drop/validate</property>自动创建表

2.显示sql语句<propertyname="show_sql">true</property>

3.格式化sql语句<propertyname="format_sql">true</property>

---------小技巧----------

1.搭建日志环境slfjlogfj

2.搭建测试环境@Test标识测试方法@BeforeClass执行前调用的方法@AfterClass

-------------------------

4.Annotation:在Model中指定实体类所对应的数据库Table:@Table(name="tableName")

Xml:<classname="table"table="".......

5.字段名和属性名不同时:Annotation:@Column(name="columnName")

6.指定不可存储到数据库中的属性:Aannotation:@Transient

7.格式化日期精度@Temporal(TemporalType.DATE)可以把日期或者日期和时间存储到数据库中

8.映射枚举类型:

publicenumTitle{

A,B,C

}

privateTitletitle;

@Enumerated(EnumType,STRING)//枚举

publicTitlegetTitle(){

******

}

9.ID的生成策略

xml:<idname="id">

<generatorclass="uuid"></generator>//class=uuid标识字符native设置(sqlserver)自动增长列,squence(Oracle中标识列),auto_increamt(mysql)

</id>

Annotation:@generatedValueauto(相当于xml中的active)

当不使用Oracle时,可以设置@GeneratedValue(startegy=GenerationType.IDENTITY)设置id的生成策略(sqlerver,mysql)

@sequenceGenerator(name="标识名字",sequencename="数据库中的sequence名字")指定Oracle生成的sequence名字

@TableGenerator生成主键策略

@TableGenerator(

name="",

table="GENERATOR_TABLE",

pkColumnname="key",

valueColumnNamne="",

pkClumnValue="",

allocationSize=1

)

10.联合主键(id,name)作为联合主键

在类中:

publicclasspkimplementsSerializable{

privateintid;

privateStringname;

}

//@Overrideequals和hashcode

//关系到虚拟内存所以需要序列化

//为了判断id和name和传递过来的是相等的,所以需要@Overrideequals

publicclasslianhe{

privatepkpk;

}

(1)xml中配置:

<composite-idname="pk"class="****">

<key-propertyname=""/>

<key-propertyname=""/>

</composite-id>

(2)Annotation的配置:

-把主键类(pk)注解为@Embeddable,并且把主键的属性注解为@Id

-把主键的属性注解为@EmbeddedId表示嵌入的主键id

-直接在Entity上注解@IdClass(PK.class)并在主键id,name上注解@Id

核心开发接口

1.读取配置:

SessionFactorysf=newAnnotationConfiguration().configure("hibernate.cfg.xml").buildSessionFactory();

Sessionsession=sf.getCurrentSession();//从上下文(在配置文件中设置current_session_context_class--取值:jta,thread,managed,custom.Class)查找,如果有就获取Session,没有就创建新的Session.

//-用于事务的边界-事务提交时自动Close

//Sessionsession=sf.openSession();//永远是创建一个新Session

session.beginTransaction();

session.save(Entity);

session.getTransaction().commit();

2.对象的三种状态

(1)Transient刚刚new出来,内存中有对象,但无id

(2)Persistent内存中有id,在于Session中,数据库中也存在id

(3)DetachedSession已经Close没有了Id,数据库中存在id

3.Hibernate的CRUD

(1)save()对象的三种状态

(2)delete()

(3)load()和get()

-load()生成一个对象代理,需要用到的时候才会调用,

-get()直接读取数据

(4)update()//设置部分字段不更新@Column(updatable=false)

(5)saveOrUpdate()

(6)clear()清除Session

(7)flush()让缓存与数据同步session.setFlushMode(FlushMode.COMMIT)设置flush的同步时间

4.自动建表

(1)使用hibernate.cfg.xml中的配置自动建表

(2)使用程序控制:newSchemaExport(newAnnotationConfiguration().configure()).create(显示sql-true/false,是否执行到数据库-true/false);

关系映射:

1.一对一

a)单向一对一单向外键关联:在一方设置另一方的引用(数据库表中设置为外键关联)

Annotation:在引用上注解:@OneToOne@JoinColumn(name="pk_id")设置引用的外键id名称

xml:<many-to-onename=""column=""unique="true"/>

一对一单向主键关联:

Annotation:在引用上设置@PramaryKeyJoinColumn(hibernate3.2好像有点小bug)

xml:****

b)双向一对一双向外键关联:在两方都有对方的引用,双方都设置:@OneToOne,其中一方还需设置@OneToOne(mappedBy="另一方的引用名称")

一对一双向主键关联:@OneToOne@PrimaryKeyJoinColumn

xml:****

c)联合主键:@JoinColumns

d)组件映射:在数据库中配置为一张表,把一方设置为另一方的一部分,在引用上设置:@Embedded(表示作为这张表的一部分嵌入到)

2.一对多多对一

a)多对一的单向:

Annotation:多指向一(@ManyToOne)

xml:<many-to-onename="属性名"column="生成的外键关系名"/>

b)多对一的双向:

Annotation:在多指向一设置@ManyToOne,在一指向多设置@OneToMany(mappedBy="多的一方的关系名称")

xml:一<one-to-manyclass=""column="和多的一致"/>多<many-to-onename=""column="和一的一致"/>

3.多对多

a)多对多的单向关联

privateSet<**>**=newHashSet<**>();//设置对方的引用

Annotation:一方@ManyToMany@JoinTable(name="中间表名",joinColumns={@JoinColumn(name="对应自己的表的关系名称")}inverseJoinColumns={,@JoinColumn(name="另外一张表的关系名称")})

xml:一方

<setname="属性名"table="数据库中间表名">

<keycolumn="指向自己的表的关系名"/>

<many-to-manyclass=""column="指向另外一张表的关系名"/>

</set>

b)多对多的双向关联

privateSet<**>**=newHashSet<**>();

//做好单向关联后

Annotation:使用注解@ManyToMany(mapedBy="另外一类(多)中的引用名称")

xml:在另一方设置<many-to-manyclass=""column=""/>

4.关联关系中的CRUD

(1)保存时注意关联

使用Annotation设置级联操作:在指向另一类的@关系上设置(cascade={casadeType.ALL})//表示对所有的CRUD都进行级联操作

在双向关系中需要设置好双向关联

(2)加载数据fetch主要影响get/load

(cascade={casadeType.ALL},fetch=FetchType.EAGER)//FetchType取值(EAGER,LAZY)

(3)更新数据时先做load,再设值

(4)删除数据时注意casade的设置问题,建议使EJBQL,HQL

5.集合映射(了解)

Set参考多对多关系映射中(常用)

List雷同Set(指定排序时@OrderBy("默认Id或者属性asc/desc"))

Map在设置Set的基础上设置@MapKey(name="map中使用哪个字段作为key")

//里面不能装载基础类型

6.继承映射(了解)

(1)设计为一张表(父类和子类放在一张表中,使用一个标识列标识是哪个对象(type))

(2)设计为多张表(父类一张,子类设计为分表)

(3)设计一张共有的属性,子类保存特有属性

//实现方式可以查找

7.树状映射(重要)

实体类设计:(parent表示父项)

id,name,Set<parent>,parent

在parent上@ManyToOne@JoinColumn(name="parent_id")

在Set上@OneToMany(mappedBy="parent")

--树状结构的打印

查询语言:NativeSQL(本地的sql语言)>HQL(hibernatequerylanguage)>EJBQL(JPQL1.0)>QBC(QueryByCretira)>QBE(QueryByExample)

HQL和EJBQL

session.createQuery("查询语句");

注明:category

1.from类名

2.selectdistinctfrom类名

3.from类名whereid>:minandid<max

Query.setInteger("min",2);

Query.setInteger("max",2);

Query.setParameter("max",3);

Query.setMaxResults(4);//最大结果集

Query.setFirstResult(1);//读取的起点

Query.uniqueResult();

4.导航

fromtopictwheret.category.id=1

join//联合查询

selectt.tilte,c.namefromtopictjoint.categoryc

isnotnull//不为空

isempty//为空

like'%_'//模糊查询

5.函数

lower()

upper()

trim()

concat()

length()

(不常用)

abs()

sqrt()

mod()

6.current_date当前日期current_time当前时间current_timestamp当前日期和时间

7.查询

count()

groupby

having

avg()

all()

exists()/notexists()//能用这个时就用这个

in()/notin()

8.session.getNameQuery("");

9.NativeQuery

SQLQueryq=session.createSQLQuery("本地sql语句").addEntity(类名.class);

10.QBE

Criteriac=session.createCriteria(类名.class).add(Restrictions.约束属性);

Hibernate性能优化

1.session.clear()分页时需要注意使用,打开了链接需要关闭

内存泄露,java语法上没有,而当加载许多的session时就会出现内存泄露

3.1+N问题(当取一张关联了其他表的数据时,将会加载其他的数据引发许多的sql语句)

取关联对象的值,将引发获取被关联的对象的值,这就是1+N问题

(1)@ManyToOne(fetch=FetchType.Lazy)//其他的被关联的对象语句将会在需要时发出

(2)@BatchSize(size=5)//只取五条数据,注解添加到被关联的对象上面

(3)joinfetch:session.createQuery("fromTopictleftjoinfetcht.categoryc");

//使用了外连接,只发一条sql语句

4.list和iterator的区别

(1)iterator先取id再取对象,重复使用时,先查找缓存,再查找数据库.

(2)list获取所有,不会查找seesion,但会先保存到session中去

5.二级缓存和查询缓存(查询的是一样的数据)

一级缓存:session级别的缓存

二级缓存:sessionFactory级别的缓存

load默认使用二级缓存,iterator默认使用二级缓存

list默认往二级缓存加数据,但查询时不先查询二级缓存

二级缓存需要在配置文件中打开

缓存算法:lru,lfu,fifo

6.事务并发处理

a)acid

b)事务的隔离级别

相关推荐