hibernate总结
2008-12-27 向先函 制作
2009-2-19 结束
1、读取配置文件的方法:
Configuration cfg= new configuration().configure();读取---.cfg.xml;去掉.configure者只读取.priperpties
创建sessionfanction
SessionFactory factory=cfg.buildSessionFactory();然后再调用Session方法操作数据库
2、创建表的做法
Configuration cfg=new Configuration().configure();
SchemaExport export=new SchemaExport(cfg);
export.create(true,true);
同时还要设置hibernate。Cfg。xml的属性
<property name=”hibernate.hbm2ddl.auto”>update</property>
当没有表的时候就创建,有表的时候就不用创建,更新就可以
3、测试类的调用
/**
* 测试类的调用
* @author Administrator
*
*/
public class SessionTest extends TestCase {
public void testHello1(){
System.out.println("------------SessionTest.testHello1------------------");
}
public void testHello2(){
System.out.println("------------SessionTest.testHello2------------------");
}
@Override
/**
* 只调用一次作为初始化
*/
protected void setUp() throws Exception {
// TODO Auto-generated method stub
super.setUp();
}
@Override
/**
* 作为析构调用
*/
protected void tearDown() throws Exception {
// TODO Auto-generated method stub
super.tearDown();
}
//get 如果查询没有数据着返回NULL对象
//load找不到数据就抛出ObjectNotFind异常
初始化SessionFactory 只调用一次
/**
* 初始化SessionFactory
* 只调用一次 在hibernateSessinFactory当中已经封装好了
* @author Administrator
*
*/
public class HibernateUtils {
private static SessionFactory factory;
static{
try {
Configuration cfg=new Configuration().configure();
factory=cfg.buildSessionFactory();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static SessionFactory getSessionFactory(){
return factory;
}
public static Session getSession(){
return factory.openSession();
}
public static void closeSession(Session session){
if(session!=null){
if(session.isOpen()){
session.close();
}
}
}
4、了解get和load的区别?
* get不支持lazy,load支持lazy
* 采用get加载数据,如果没有匹配的数据,返回null,而load则抛出异常
transient状态的特征?
* 在数据库中没有与之匹配的数据
* 没有纳入session的管理
persistent状态的特征?
* persistent状态的对象在数据库中有与之匹配的数据
* 纳入了session的管理
* 在清理缓存(脏数据检查)的时候,会和数据库同步
detached状态的特征?
* 在数据库中有与之匹配的数据
* 没有纳入session的管理
5、分页,用下面的方式
query.setFirstResult(2);
query.setMaxResult(2);
主键生成策略
Uuid ,native assigned
//注意persisent状态不能引用transient状态的值会抛出transientObjectException
必须先保存临时状态的对象
解决上面的问题可以采用属性级联的方式处理,不提倡这种方式,最好先保存前面的对象在保存后面的对象
<many-to-one name="users" class="com.yourcompany.hiber.Users" fetch="select" cascade="save-update">
<column name="ID" />
</many-to-one>
Cascade可以设置成为all或save-update默认问none
级联(对象之间的连锁操作)只与增加删除修改有关系,与查询没关系
CREATE TABLE `test`.`NoId`(`name` VARCHAR(45),`age` INTEGER)ENGINE = InnoDB;
那么对应的POJO写成
public class NoId implements Serializable {
private String name = null;
private Long age = null;
// 构造子和getter setter
......
// 注意这种情况下我们需要重写equals和hashCode
public boolean equals(Object object) {
......
}
public int hashCode() {
......
}
}
然后对应的映射文件如下
<hibernate-mapping>
<class name="fox.math.kmust.NoId" table="noid" lazy="true">
<!-- 这里是将表的所有属性作为联合主键 -->
<composite-id>
<key-property name="name"/>
<key-property name="age"/>
</composite-id>
</class>
</hibernate-mapping>
6、多对一的做法
在多的一方
public class User {
private int id;
private String name;
private Group group;
<class name="User" table="t_user">
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
<many-to-one name="group" column="groupid"/>
</class>
在单的一方
public class Group {
private int id;
private String name;
<hibernate-mapping package="com.gxcme.hibernate">
<class name="Group" table="t_group">
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
</class>
</hibernate-mapping>
使用
Group group=new Group();
group.setName("zhangsan");
User user=new User();
user.setName("菜10");
user.setGroup(group);
7、一对一
主键关联(依赖的一方)单项的一方
<hibernate-mapping package="com.gxcme.hibernate">
<class name="Person" table="t_Person">
<id name="id">
<generator class="foreign">
<param name="property">cardid</param>
</generator>
</id>
<property name="name"/>
<one-to-one name="cardid" constrained="true"/>
</class>
</hibernate-mapping>
另一方
<hibernate-mapping package="com.gxcme.hibernate">
<class name="IdCard" table="t_IdCard">
<id name="id">
<generator class="native" />
</id>
<property name="cardNo"/>
</class>
</hibernate-mapping>
双向主键关联
只要在上面的基础上修改另一方
<hibernate-mapping package="com.gxcme.hibernate">
<class name="IdCard" table="t_IdCard">
<id name="id">
<generator class="native" />
</id>
<property name="cardNo"/>
<one-to-one name="person"/>
</class>
</hibernate-mapping>
一对一唯一外键关联单向关联
只要在多的一方改为改;是多对一的特例
<hibernate-mapping package="com.gxcme.hibernate">
<class name="Person" table="t_Person">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="cardid" unique="true"/>
</class>
理解many-to-one:加入外键在多的一端,指向一的一端;
理解 one-to-one:指示hibernate如何加载其关联对象;默认根据主键关联;
一对一唯一外键关联双向关联
<class name="IdCard" table="t_IdCard">
<id name="id">
<generator class="native" />
</id>
<property name="cardNo"/>
<one-to-one name="person" property-ref="cardid"/>
</class>
Uuid调用完save后只是将user纳入session管理,不会发出insert语句,但id已经生成;flush后默认没有在数据库里面显示,与隔离级别有关native不同;
对象模型到关系模型hbm2ddl
一对多单向:
一的一端
public class Stutent {
private int id;
private String name;
<class name="Stutent" table="t_stutent">
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
</class>
多的一端
public class Classes {
private int id;
private String name;
private Set stutent;
<class name="Classes" table="t_classes">
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
<set name="stutent">
<key column="classesid"/>
<one-to-many class="Stutent"/>
</set>
</class>
使用:增加:有缺点就是不能设置set为非空,而且还发出多余的update
Stutent stutent1=new Stutent();
stutent1.setName("菜10");
session.save(stutent1);
Stutent stutent2=new Stutent();
stutent2.setName("rongzhuer");
session.save(stutent2);
Set stutent=new HashSet();
stutent.add(stutent1);
stutent.add(stutent2);
Classes classes=new Classes();
classes.setName("guangxijidian");
classes.setStutent(stutent);
session.save(classes);
加载:
Classes classes=(Classes)session.load(Classes.class, 1);
System.out.println(classes.getName());
Set set=classes.getStutent();
Iterator iter=set.iterator();
while(iter.hasNext()){
Stutent stutent=(Stutent)iter.next();
System.out.println(stutent.getName());
多对多单向
在读取的一端
<class name="User" table="t_user">
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
<set name="role" table="t_user_role">
<key column="userid"/>
<many-to-many class="Role" column="roleid"/>
</set>
</class>
另一端
<class name="Role" table="t_role">
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
</class>
使用
Role role1=new Role();
role1.setName("guangliyuan");
session.save(role1);
User user2=new User();
user2.setName("zhuer");
Set u2role=new HashSet();
u2role.add(role2);
u2role.add(role3);
user2.setRole(u2role);
加载
User user=(User)session.get(User.class, 5);
System.out.println(user.getName());
for(Iterator iter=user.getRole().iterator();iter.hasNext();){
Role role=(Role)iter.next();
System.out.println(role.getName());
}