无线&移动互联网技术研发

换位思考·····
posts - 19, comments - 53, trackbacks - 0, articles - 283
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Hibernate 主要知识点的归纳

Posted on 2010-05-27 01:11 Gavin.lee 阅读(1307) 评论(0)  编辑  收藏 所属分类: SSH2 --Hibernate
 

一、HibernateORMObject Relation Mapping)对象关系映射框架

常用的ORM框架有:HibernateTopLinkOJB

Hibernate 框架完全是进行对象的操作,不再会有对字段、属性的操作。如Hibernate 删除则是删除一个对象,更新则是对某一个对象状态进行更新

小贴士:应用Hibernate开发时,可与JDBC相联想

二、开发流程:

1.Domain Object ----mapping -----db(官方推荐)

2.DB开始,用工具生成mappingDomain Object(使用较多)

3.由映射文件开始

Domain Object 限制:

1.默认的构造方法(必须的)

2.有无意义的标示符id(主键)(可选)

3.final,对懒加载有影响

三、需要一个工具类,只加载一次 hibernate.cfg.xml 文件

package cn.itcast.hibernate;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

publicfinalclass HibernateUtil 
{

    
private HibernateUtil() {}

    privatestatic SessionFactory sf 
= null

    
static {

        Configuration cfg 
= new Configuration();

        cfg.configure();

//cfg.configure(new File("filename")); //指定配置文件的路径,不指定则默认

        sf 
= cfg.buildSessionFactory();

    }
   

    publicstatic SessionFactory getSessionFactory() 
{

        returnsf;

    }
   

    publicstatic Session getSession() 
{

        returnsf.openSession();

    }


}

 

小贴士:将java类与hibernate源码绑定

四、Mysql 有多种引擎:

    MyISAM:5.0以前的缺省引擎,效率高但不支持事务。

    InnoDB:支持事务,则Hibernate操作时需要开启事务,进行操作后提交事务,这样才能将数据持久化:

Transaction tx = s.beginTransaction();//开启事务

        User user = new User();

        user.setName("name");

        user.setBirthday(new Date());

        s.save(user);

tx.commit(); //事务提交

五、Hibernate 核心接口概述:

Configuration:

负责管理Hibernate的配置信息,这些信息由配置文件提供,包括如下内容:

1.Hibernate运行的底层信息:数据库的URL、用户名、密码、JDBC驱动类等,数据库Dialect,数据库连接池等。

2.Hibernate映射文件(*.hbm.xml

调用代码:

1.属性文件(hibernate.properties)

Configuration cfg = new Configuration();

cfg.addClass(XXX.class);//该方法加载XXX.hbm.xml

cfg.addResource();

2.XML文件(hibernate.cfg.xml

Configuration cfg = new Configuration();

cfg.configure();

SessionFactory:

1.应用程序从SessionFactory(会话工厂)里获得Session(会话)实例。它在多个应用线程间进行共享。通常情况下,整个应用只有唯一的一个会话工厂---例如在应用初始化时被创建。然而,如果你使用Hibernate访问多个数据库,你需要每个数据库使用一个会话工厂。

2.会话工厂缓存了生成的SQL语句和Hibernate在运行时使用的映射元数据。

3.调用代码:

privatestatic SessionFactory sf = null

static {

    Configuration cfg = new Configuration();

    cfg.configure();

    sf = cfg.buildSessionFactory();

}

Session

1.Session不是线程安全的,它代表与数据库之间的一次操作会话

2.Session也称为持久化管理器,因为它是与持久化有关的操作接口

3.Session通过SessionFactory打开,在所有的工作完成后,需要关闭

4.Session缓存其管理的持久化对象

5.调用代码:

Session session sessionFactory.openSession();

Transaction:

1.它将应用代码从底层的事务实现中抽象出来---这可能是一个JDBC事务,一个JTA用户事务或者甚至是一个公共对象请求代码结构(CORBA---允许应用通过一组一致的API控制事务边界

2.这有助于保持Hibernate应用在不同类型的执行环境或容器中的可移植性

3.Hibernate提供的事务提交模式默认为非自动提交模式(默认:autoCommit=false),因此使用Hibernate进行操作时(增、删、改)必须显示的调用TransactionAPI

4.调用代码:

Transaction tx = session.beginTransction();

Tx.commit()/rollback();

Query/Criteria:

1.Query接口封装了Hibernate强大的对象查询能力,同时也支持数据库的更新操作

2.提供了动态查询的参数绑定功能

3.提供list(),iterator(),scroll()等对象导航方法

4.提供uiqueResult()方法获取单独的对象

5.提供executeUpdate()方法来执行DML语句

6.提供了可移植的分页查询方法

Session

1、savepresist保存数据,persist在事务外不会产生insert语句。

2、delete,删除对象

3、update,更新对象,如果数据库中没有记录,会出现异常,脱管对象如属性改变需要保存,则调用update方法

4、get,根据ID查,会立刻访问数据库

5、load,根据ID查,(返回的是代理,不会立即访问数据库)

6、saveOrUpdate,merge(根据IDversion的值来确定是否是saveupdate),调用merge你的对象还是托管的。当不知该对象的状态时可调用该方法

小贴士:瞬时对象id无值,脱管对象有值,hibernate通过该方式判断对象的状态

7、lock(把对象变成持久对象,但不会同步对象的状态)

六、Hibernate中对象的状态:

状态的参考:数据库中是否有记录;是否有session关联

1、瞬时(transient):数据库中没有数据与之对应,超过作用域被JVM垃圾回收器回收,一般是new出来且session没有关联的对象

2、持久(persistent):数据库中有数据与之对应,当前session有关联,并且相关联的session没有关闭,事务没有提交;持久对象状态发生改变,在事务提交时会影响到数据库(hibernate能检测到)

3、脱管(detached):数据库中有数据与之对应,但当前没有session与之关联;托管对象状态发生改变,hibernate不能检测到

对象在的状态转化:
    



当对象被
savecommit后,Hibernate Session 任然能察觉到对象,如果此时对象属性发生改变,则数据库中持久化的值同样被改变,如:

    //标准方法

    static void addUser(User user) {

        Session s = null;

        Transaction tx = null;

        try {

            s = HibernateUtil.getSession();

            tx = s.beginTransaction();

            s.save(user);

user.setName("new name");

            tx.commit();

        } catch (HibernateException e) {

            if (tx != null) {

                tx.rollback();

            }

            throw e;

        } finally {

            if (s != null)

                s.close();

        }

}

user对象在数据库中最终持久化的name=="new name",如果在commit之前修改过的属性,将会在commit时候统一对对象进行update

七、Hibernate Query LanguageHQL)和CriteriaQBC

HQL:面向对象的查询语言,与SQL不同,HQL中的对象名是区分大小写的(除了JAVA类和属性其他部分不区分大小写);HQL中查的是对象而不是和表,并且支持多态HQL主要通过Query来操作,Query的创建方式:

Query q = session.createQuery(hql);

1.from Person

2.from User user where user.name=:name

3.from User user where user.name=:name and user.birthday<:birthday

static void query(String name) {

        Session s = null;

        try {

            s = HibernateUtil.getSession();

            String hql = "from User as user where user.name=?"//from Object ... 因为HQL支持多态,所以执行 from Object时,将会将所有的表都查一遍

            /**

             * 当查询条件有多个的时候,则参数 "?" 将会有多个,这样对我们的维护带来极大不便,在HQL中我们利用命名参数处理

             * "from User as user where user.name=?" -->> "from User as user where user.name=:n"

             * query.setString("n", name);

             * 经过这样设置后在多条件情况下,我们不需要再顾及参数的先后顺序了

             */

            Query query = s.createQuery(hql);

            query.setString(0, name);

           

            /**

             * Hibernate 分页: 200-210

             * query.setFirstResults(200);

             * query.setMaxResults(10);

             * 这样的分页,为数据库的移植做到了很好的兼容,根据数据库设置的方言来判断

             */

            List<User> list = query.list();

                //Object obj = query.uniqueResult(); 当我们确定返回的结果集就一条记录,则可调用此方法,如有多条,则会报异常

            for(User user : list) {

                System.out.println(user.getName());

            }

        } finally {

            if (s != null) {

                s.close();

            }

        }

}

HQL SQL 查询的区别:

HQL根据属性名查对象,SQL根据字段查表

Creteria:Criteria是一种比HQL更面向对象的条件查询方式;Criteria的创建方式:

Criteria crit = session.createCrieria(DomainClass.class);

简单属性条件如:

criteria.add(Restrictions.eq(propertyName, value);

criteria.add(Restrictions.eqProperty(propertyName, otherPropertyName));

    staticvoid cri(String name) {

        Session s = null;

        try {

            s = HibernateUtil.getSession();

            Criteria c = s.createCriteria(User.class);    //对User进行约束查询

            c.add(Restrictions.eq("name", name)); //添加约束条件

            c.add(Restrictions.lt("birthday", new Date()));

            /**

             * Criteria 查询同样提供了分页

             */

            c.setFirstResult(200);

            c.setMaxResults(210);

            List<User> list = c.list();

            for (User user : list) {

                System.out.println(user.getName());

            }

        } finally {

            if (s != null) {

                s.close();

            }

        }

}

小贴士1、官方推荐HQL 查询

2、Hibernate try的异常可以不去操作,因为事务收不到commit事务就会回滚

八、对象关系的关联映射

1.多对一(Employee - Department --- 最常用

2.一对多(Department - Employee

3.一对一(Person - IdCard

4.多对多(Teacher - Student -- 需要建立中间表

在操作和性能方面都不太理想,所以多对多的映射,实际使用中最好转换成一对多的对象模型;Hibernate会为我们创建中间关联表,转换成两个一对多。

<set name="teacher" table="teacher_student">

<key column="teacher_id"/>

<many-to-many class="Student" column="student_id"/>

</set>

5.组件映射(User - Name

关联的属性是个复杂类型的持久化类,但不是实体,即:数据库中没有表与该属性对应,但该类的属性要永久保存的。

<component name="name" class="com.test.hibernate.domain.Name">

<property name="initial" />

<property name="first" />

<property name="last" />

</component>

当组件的属性不能和表中的字段简单对应的时候可以选择实现:

org.hibernate.usertype.UserType or

org.hibernate.usertype.CompositeUserType

6.集合映射(setlistmapbag

绝大部分使用set

如果习惯使用list,又不想让Hibernate维护顺序,对象里用List,映射时用bag

映射用listbag

键值对方式用map

数组因为对元素变化应用不方便

<set name="employees">

<key column="depart_id" />

<one-to-many class="Employee" />

<!-- <element type="string" column="name" /> -->

<!--

<composite-element class="YourClass">

<property name="prop1" />

<property name="prop2" />

</composite>

-->

</set>

7.InversecascadeEmployee - Department


九、映射文件剖析

1.hbm.cfg.xml

a)       

2.Xxx.hbm.xml

a)       


十、
Hibernate的持久化操作

1.save() //保存对象

a)      把临时对象加载到缓存中,使之成为持久化对象

b)      使用指定的ID生成器为持久化对象分配OID

c)      当对象处于持久化状态Hibernate不允许修改其IOD

2.update() //修改对象

a)      把游离对象加入到缓存中,使一个游离对象变成持久化对象

b)      计划执行update SQL语句,根据对象IOD来更新对象所对应的数据

c)      Update不能更新一个在session中已经关联的相同OID的对象

3.saveOrUpdate() //保存或修改对象

a)      同时包含saveupdate方法的功能,根据对象的状态自动执行相应的功能

b)      若对象为临时状态则执行save,若为游离状态则执行update方法

4.merge()//合并对象

a)      直接修改表中的记录,并不影响该对象原来的状态

5.delete()   //删除指定的对象

a)      如果是持久态对象,就计划执行delete语句

b)      如果是游离状态的对象,先使用游离对象被session缓存关联,变成持久化对象,再计划执行delete语句

5.contains() //判断实体对象是否与session关联

a)      可以用此方法判断对象是否处于持久化状态

6.evict() //把实体对象从缓存中移除

7.clear() //清除session缓存中所有持久化对象

8.get/load 方法区别:

a)      都是根据OID从数据库中加载一个持久化对象

b)      当数据库中不存在与OID对象的记录时,get()返回一个null引用,而load则会抛出ObjectNotFoundException异常

c)      Load方法可以返回一个实体的代理类实例,而get方法只是直接返回实体类对象


只有注册用户登录后才能发表评论。


网站导航: