Hibernate3(学习)
1关于单元测试: 为了测试和应用方便,新建一个专测试的包。
l 编写JUINT 类需要extend TestCase 如:
l public void testHello()
l {
l System.out.println();
l 方法名前缀必有test (这是单元测试规定)
}
2 延时加载:当属性真正调用的时候,才会去调用其方法。比如:Hhibenate 中的 Load 方法。因为load支持laze。laze是Hibernate的重要特性
session.get() 和session.load() 区别:load支持laze。(延时加载)当数据库中没有相应记录时会抛出异常,而session.get()不支持延时加载(laze)当数据库没有相应记录时会抛出异常。
3 多对一(more –to- one)配置:下面是斑级和斑级的学生关系例:
Student .hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
<class name="com.xinwei.hibernate.Student" table="T_student">
<id name="id">
<generator class="native" ></generator>//主键设置
</id>
<property name="username" />
<property name="password"/>
<property name="birthday"/>
<many-to-one name="group" column="groupid" cascade="all"/>//其为级联关系重要属性。
</class>
</hibernate-mapping>
Group.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
<class name="com.xinwei.hibernate.Group" table="T_Group">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" />
</class>
</hibernate-mapping>
4<one –to -one> 主键关联
(如一个人只有一个身份证)默认级联事例(以person 为维护对象)
IdCard.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
<class name="com.jilian.hibernate.IdCard" table="T_IdCard">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" />
</class>
</hibernate-mapping>
Person.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
<class name="com.jilian.hibernate.Person" table="T_Person">
<id name="id">
<generator class="foreign" >//外键标识
<param name="property">idCard</param>//property 是固定的
</generator>
</id>
<property name="name" />
<one-to-one name="idCard" 通过一个外键引用对主键进行约束。/>//映射
</class>
</hibernate-mapping>
双向关联(还以上例为事例)(one-to-one)
只需在idCare.hbm.xml中加上<one-to-one name=”person”/>在idCare.java 中加上private Person person;
<one-to-one> 唯一外键关联映射(多对一的一个特例只是加了unique(唯一))
多对一:在“多”的一端添加一个外键指向“一‘的一端,它维护的关系是多对一的关系。
一对多:在“多”的一端添加一个外键指向“一‘的一端,它维护的关系是一对多的关系。(多采用双项关链)
多对多关联映射:适用于用户和角色(一个人有多重角色)(单项关联)
如以User….roles表为例:(维护是在user表)配置完会有一个关天于(user…roles表的关系表)
先说 user.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
<class name="com.manytomany.hiberate.User" table="T_User">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" />
<set name="roles" table="t_User_Roles">//
<key column="userId"></key>
<many-to-many class="com.manytomany.hiberate.Roles" column="rolesId"></many-to-many>
</set>
</class>
</hibernate-mapping>
Roles.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
<class name="com.manytomany.hiberate.Roles" table="T_Roles">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" />
</class>
</hibernate-mapping>
多对多双项关联(还以user…roles 表为例)
在Roles.hbm.xml 中加
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
<class name="com.manytomany.hiberate.Roles" table="T_Roles">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" />
<set name=”User”>
<key colum=” rolesId” table=” t_User_Roles”>
<many-to-many class=”com.manytomany.hibernate.User” colum=” userId”/>
</set>
</class>
</hibernate-mapping>
5 laze 策略用于:单项关联<one-to-one>//<many -to-one >
Laze 属性设置:laze 是hibernate中的重要属性:当真正用的时候才去调用(如sql 语句)
Laze 的有效期 :只有在session 在打开的时候才会有效,当session close 的时候就不会起作用了
Laze 作用:是否在真正调用时发出sql 语句
6子hibernate 中的flush
注:session在什么情况下清理内存:默认情况下,* 当应用程序提交事务,Tracsaction.commit();
l 当session.flush()被调用的时候
l 在执行查询的时候如(Itertor)
7session.flush()主要做的有两件事
*清理缓存
* 执行sql
7 一般情况下sql 语句的执行顺序: insert ,update ,delete
用session.flush()可以调节其顺序。
8 单表继承:
以Animal 为抽象类(Pij 为一个子类///Birld为另一个子类)
只定义一个.xxx.hbm.xml
定义如下:<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
<class name="com.hibernate.classExtend.Animal">
<id name="id">
<generator class="native" ></generator>
</id>
<discriminator column="type" type="string"/>//指定属性
<property name="name"/>
//<subclass>标记的对这种映射的重要性
<subclass name="com.hibernate.classExtend.Birld" discriminator-value="b">//标识
<property name="height"></property>
</subclass>
<subclass name="com.hibernate.classExtend.Pij" discriminator-value="p">
<property name="weight"></property>
</subclass>
</class>
</hibernate-mapping>
使用此xxx.hbm.xml 会成为一个animal 表
9 多态查询:自动签别其的真正类型;
10 一些映射不想看了
11 悲观锁:是由数据库的机制来实现的,在整个处理过程中处理过程中处于锁定状态;
乐观锁:在数据库中加一个version 板本控制,并在.xml中加一个<version/>
rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml">
12 HQL (查对象的) hql 语句不区分大小写,但区分类和属性
13 查多个属性,查的是集合对象元素数组,数组的数据类型与原实体类型一致。
14 如果认为返回的数组不够面向对象,采用hql 动态实例化对象,如“select new Stu dent(id,name) from student” 默认返回对向数组集合而select name from student 返回的是集合列表。
15
16 需要在student的实体类中加一个public Student (id,
17 Name)
18 {
19 This.id=id;
20 This。Name=name;
21
22 }
23 再加一个空构造函数
24 Public student (){}
25 单一属性查询:默认返回集合列表,其数据类型与试题类型一至。
26 多个属性查询:默认返回对向数组集合,数组长度据定于试题属性个数;数组中元素类型决定于实体类型。
27 查询实体对象:可以忽略select 可直接(from Student ---它为对象类)
28 查询实体如果要加select 则必须(select s from Student s);
29 何为一级缓存?:session缓存
30 List查询只会向缓存里放,有几个list 就向内存里存几次
31 关于n +1 问题:在默认情况下使用query。Itertor()
32 条件查询:Hibernate 中 1 方法链编程:(select s。id,s。name from Student s where s。 name like ?)。setParameter(“0”,“%1%”).list();
2 。。。。。。。。。。。。。。。。。name like :myname)。setParameter(“myname”,”name”);
Hql 中同样支持sql 中的函数。
33 外置明明查询:把hql 语句放在 。xml 文件中
34 在<class/>下使用<query name=“search”>
35 <! [CDATA[ ……//放在这个区中就不会与其他标签冲突。(CDTATA 区)
36 Select s from Student s
37 ]]>
38 <query/>
39 把hql语句放在。Xml中:查询时就应该这样了:session。GetnameQuery()
40 Hibernate 同样支持原生sql语句;
41 分页设置:session。setFirstResult()起是记录,可以从0 开始
42 Session。setMaxResults()。每页显示的记录数。
43 对象导航查询:通过两表的关系来查询,例如:student &&class hql: select s from Student s where s.classes.name
44 Hql 连接查询使用导航 (前提是二表有关系 student class) select c。name,s.id from Student s.classes.name c
45 一级缓存: 如何避免一次性大批量数据插入:先sesssion。Flush ;
46 后session。Clear
47 二级缓存:也称二级缓存,又叫sessionFactory 它可以被所有的session共响,sessionFactory 可以管理二级缓存
首先启用二级缓存:在hibernate.cfg.xml 加入
<!-- 启用二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 指定提供商 -->
<property name="hibernate.connection.provider_class">org.hibernate.cache.EhcacheProvider</property>
二级缓存需指定类 :可以在相关类的.hbm.xml 中<cache usage="read-only"/>
也可在hibernate.cfg.xml : <class-cache class="com.gao.hibernate.Student" usage="read-only"/>
二级缓存也是缓存实体类的,
配置完之后,二级缓存的一些设置:session。SetCacheMode(cacheMode。GET)仅从二级缓存中读取数据,而不响二级缓存中存处数据session。SetCacheMode(cacheMode。put)
尽享缓存中写数据,而不响二级缓存中读数据session。SetCacheMode(cacheMode。normal)从二级缓存中读写数据
48 查询缓存:针对的是属性的,通常何二级缓存联合使用;
49 抓取查询:<many-to-one name="classes" fetch="join"/>
50 默认查询有关联系采用外联接。而且使用fetch="join"laze会失效。
51 Session不是线程安全的