建立模型对象,它在对象模型数据和关系型数据库之间构建了一条快速

Hibernate简介,hibernate

Hibernate的CRUD的准备工作:

一、概述

Hibernate是一个开放源代码的的对象关系映射框架。它对jdbc进行了封装,提供了强大,高性能的对象关系模型数据库的持久化服务。Hibernate提供的HQL(Hibernate Query Language)是面向对象的查询语言,它在对象模型数据和关系型数据库之间构建了一条快速,高效,便捷的沟通渠道。

1):建立表t_user.
2):建立模型对象:User类.
3):编写DAO组件.
DAO接口:IUserDAO
DAO实现类:UserDAOImpl(暂时不提供方法实现)
DAO测试类:UserDAOTest
4):使用Hibernate依赖jar包.
1).MySQL驱动包:mysql-connector-java-5.1.22.jar(勿忘)

二、Hibernate框架

1.ORM(Object Relation Mapping)称对象关系映射

在编写程序的时候,以面向对象的方式处理数据,在保存数据的时候,却以关系型数据的形式存储到数据库中,所以需要一种能在两者间进行数据转换的机制,这种机制称对象-关系映射机制,简称ORM.

2.实体对象的状态

>自由态

自由状态就是实体对象在内存中自由存在,此时它与数据库无关,自由状态有两个特性:

(1).不处于Session的缓存中,也就是不被任何一个Session实例关联。

(2).在数据中没有对应的记录。

>持久态

持久状态就是实体对象在Hibernate的管理情况下的状态。在持久状态下,实体对象的引用被纳入Hibernate实体容器中加以管理。处于持久状态的实体对象会被Hibernate固化到数据库中。持久状态的特性:

(1).位于一个Session实例的缓存中,也就是说,持久化对象总被一个Session实例关联。

(2).持久化对象和数据库中的相关记录对应。

(3).Session在清理缓存时,会根据持久化对象的属性变化来同步更新数据库。

(4).Session的Save()方法把实体对象从自由状态转变为持久状态。

(5).Session的load()方法或get()方法返回的实体对象总是持久状态。

(6).Session的update(),saveOrUpdate()和lock()方法使实体对象从游离状态转变被持久状态。

>游离态

当处于持久状态的实体对象,其对应的Session关闭以后,这个实体就处于游离状态,可以认为Session对象是实体对象在持久状态的宿主,而实体对象失去这个宿主,也就是这个宿主失效,那这个实体对象就处于游离状态。游离状态的特性:

(1).不再位于Session的缓存中,也可以说游离状态的实体对象不被Session关联。

(2).游离状态是由持久化变来的,因此在数据库中可能还存在与它对应的记录。

3.VO与PO

处于自由状态和游离状态下的实体对象称为值对象(Value Object,VO).

处于持久状态的实体对象称为持久对象(Persistent Object,PO).

VO和PO之间的区别:

1.VO对象包含两种状态,即自由状态和游离状态,是相对独立的对象,处于非管理状态。

2.PO对象处于持久状态,是Hibernate纳入其管理容器的对象,对应数据库中某条记录的Hibernate实体,PO的变化在事物提交的时将反映到数据库中。

3.如果一个PO与其对应的Session实例分离,就会变成VO.


三、Session管理

Session接口是Hibernate向应用程序提供的操作数据库的最主要的接口,它提供了基本的保存,更新,删除和加载Java对象的方法。

Session是由SessionFactory创建的,而SessionFactory的实现是线程安全的,也就是说,多个并发的线程可以同时访问一个SessionFactory并从其中获取Session实例,但Session不是线程安全的,Session中包含了数据库操作的相关信息,所以多个线程共享一个Session将会发生数据共享混乱。

5)Hibernate的CRUD的配置文件:
Hibernate的应用中主要包含两种配置文件.
1):主配置文件(包含连接数据库的基本要素:驱动类名,URL,账号,密码,方言,包含映射文件)

3.1、ThreadLocal模式解决Session共享问题

ThreadLocal不是一个线程的本地实现,即它不是一个线程,而是线程局部变量(Thread Local Variable)。它的作用是为每一个使用这个变量的的线程都提供一个变量值的副本,并且每一个线程都可以独立地改变自己的副本,而不会和其他线程的副本冲突,从线程的角度来看,就好像每一个线程都完全拥有一个该变量一样。

ThreadLocal会给每一个线程提供一个变量的副本,就可以实现线程范围内Session共享,从而避免线程频繁创建和销毁Session,但是需要注意,使用完毕后需要手动关闭。

package com.test;

import java.util.Iterator;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class LoginDao {
 private Session session=null;
 private Transaction tran=null;
 private static final ThreadLocal<Session> s=new ThreadLocal<Session>();//使用ThreadLocal方式来管理Session

 public LoginDao(){
  Configuration config=new Configuration().configure();
  SessionFactory factory=config.buildSessionFactory();
  //this.session=factory.openSession();
  this.session=s.get();//调用ThreadLocal的get方法得到session
  if (session==null) {
   this.session=factory.openSession();
   //this.session=factory.getCurrentSession();//使用这种方法,需要在配置文件中添加相应的配置信息
   s.set(session);//将session 放到ThreadLocal用进行管理
  }
 }

 /**
  * 插入数据
  */
 public void save(Login login){
  try {
   tran=session.beginTransaction();
   this.session.save(login);
   //提交事物
   tran.commit();
   System.out.println("用户信息保存成功");
  } catch (RuntimeException e) {
   if (tran!=null) {
    tran.rollback();
    //throw e;
    e.printStackTrace();
   }
  }finally{
   this.session.close();
  }
 }
 /**
  * 更新操作
  */
 public void update (Login login){
  try {
   tran=session.beginTransaction();
   session.update(login);
   tran.commit();
   System.out.println("更新成功");
  } catch (HibernateException e) {
   if (tran!=null) {
    tran.rollback();
    //throw e;
    e.printStackTrace();
   }
  }finally{
   this.session.close();
  }
 }
 /**
  * 删除操作
  * @param login
  */
 public void delete(Login login){
  try {
   tran=this.session.beginTransaction();
   session.delete(login);
   tran.commit();
   System.out.println("删除成功");
  } catch (HibernateException e) {
   if (tran!=null) {
    tran.rollback();
    //throw e;
    e.printStackTrace();
   }
  }finally{
   this.session.close();
  }
 }
 /**
  * 根据主键精确查询
  * 
  */
 public Login getLoginByid(String name){
  Login login=null;
  String hql="from Login as l where l.username=?";
  Query query=this.session.createQuery(hql);
  query.setString(0, name);
  Iterator list=query.list().iterator();
  if (list.hasNext()) {
    login=(Login)list.next();
  }
  System.out.println("主键精确查询");
  this.session.close();
  return login;
 }

 public List queryAll(){
  List list=null;
  String hql="from Login as l";
  Query query =this.session.createQuery(hql);
  list=query.list();
  System.out.println("查询所有记录");
  this.session.close();
  return list;
 }
 /**
  * 根据用户名进行模糊查询的操作
  */
 public List queryLike(String name){

  List list=null;
  String hql="from Login l where l.username like ?";
  Query query =this.session.createQuery(hql);
  query.setString(0, "%"+name+"%");
  list=query.list();
  System.out.println("模糊查询");
  this.session.close();
  return list;
 }

}

必发娱乐官网 1

3.2、openSession()和getCurrentSession()解析

Hibernate的SessionFactory类除了提供openSession()来返回Session外,还提供了getCurrentSession()方法,此方法是Hibernate的3.0.1版本之后才增加的,通过这个方法同样可以得到一个Session,但是这两个方法之间还是有区别的,它们之间的区别如下:

1.getCurrentSession()创建的Session会绑定当当前线程,而openSession()不会。

2.getCurrentSession()创建的Session会在事物回滚或事物提交后自动关闭,而openSession()创建的必须手动关闭,(调用的Session的close()方法)

注意:

(1).当使用本地事务(jdbc事务)时,需要在Hibernate.cfg.xml文件的<session-factory>节点中添加如下代码:

<property name="hibernate.current_session_context_class">thread</property>

(2).当使用的是全局事务(JTA事务)时,需要在hibernate.cfg.xml文件的<session-factory>节点中添加如下代码:

<property name="hibernate.current_session_context_class">jta</property>

如果使用getCurrentSession()方法,而没有在配置文件中添加以上的这些内容,那么编译不会报错,但是在运行程序时会出错,“No CurrentSessionContext configured!”,另外由于使用getCurrentSession()方法不需要手动关闭Session,所以不需要调用Session的close()方法。

2):每一个Domain对象的映射文件(处理对象和表中的映射关系).

3.3、Session的使用

3.3.1、save()方法

必发娱乐官网,Session的Save()方法使一个自由对象(也称临时对象)转变为持久对象。调用Session的save()方法需要完成3件事:

1.把对象加入Session的缓存中,使它进入持久化状态。

2.选用映射文件指定的标识符生成器,为持久化对象分配唯一的OID.

3.计划执行一个insert语句,把对象当前的属性值装到insert语句中。

需要注意的是在save()方法后,在事务commit()方法之前,又修改了持久化对象的属性,哪个当session在清理的时候,会额外执行一个SQL update操作。

User user = new User();
user.setPassword("123");
user.serUsername("xiazhongwei");
Session session = sessionFactory.openSession();
Transaction tran = session.beanTransaction();
session.save(user);
user.setPassword("456");
tran.commit();
session.close();

  第一条:inser into USER (ID ,USERNAME,PASSWORD) values(1,"xiazhongwei","123");

第二条: update USER SET USERNAME="xiazhongwei",PASSWORD="456" where id=?

3.3.2、persist()方法

 persist()方法与save()方法作用类似,也能把一个自由对象转变为持久对象。

需要注意persist()方法是在hibernate3中才出现的它实现了EJB3规范中定义的持久化语义,当调用persist()方法时,并不一定会立即为持久化对象的OID赋值,而有可能在Session清理的时候才为oid赋值。另外咋事务边界以外调用persist()方法,这个方法不会计划执行一个insert语句。。

3.3.3、update()方法

执行session的update方法使一个游离的对象变为持久对象,并计划执行一条update语句。会完成一下操作:

1.把游离对象加入当前session的缓存中,使它变为持久化对象。

2.计划执行一条update语句。

3.Session只有在清理缓存的时候才会执行update语句,及使多次修改对象的数据也只会在清理缓存的时候执行一次update语句。

3.3.4、saveOrUpdate()方法

如果传入的是临时对象,就调用save()方法,如果传入的是游离对象,就调用update方法,而如果传入的是持久化对象就直接返回。

3.3.5、load()方法

方法是根据给定的OID从数据库中加载一个持久化对象。load()方法当数据库中不存在与oid对应的记录时,load()方法跑出org.hibernate.ObjectNotFoundException异常。

3.3.6、get()方法

get()方法和load()方法相似,都是使用oid检索持久化对象,get()方法当数据库中不存在与oid对应的记录时,get()方法返回null.

和load()方法的还有一个区别是两者采用了不同的检索策略,在默认情况下所有的持久化对象都使用延迟加载策略,<class name="com.entity.User" table="USER" lazy="true">如果不加lazy属性默认也是true,如果给lazy属性改为false那么load()方法就会立即加载。但是get()方法则忽略class元素的lazy属性,也就是说不管lazy属性写的什么值,get()方法都会采用立即加载的策略。

那么何时该使用load何时该使用get呢?

(1).如果加载一个对象的目的是为了访问它的各个属性,那么可以使用get()方法。

(2).如果加载一个对象是为了删除它或者简历与别的对象的关联关系,可以用load()方法。

3.3.7、delete()方法

delete()方法即可以删除持久对象,也可以删除游离对象,当调用delete()方法时,如果传入的参数是游离对象,会先使游离对象与当前session关联,使游离对象变为持久对象,,而如果参数传入的是持久对象的时候,则会忽略这一步。

delete()方法也是在session清理缓存的时候执行一条delete语句。

 

一、概述 Hibernate是一个开放源代码的的对象关系映射框架。它对jdbc进行了封装,提供了强大,高性能的对象关系模型...

必发娱乐官网 2

操作数据库相关的对象

Configuration对象:
表示hibernate框架的配置对象,主要用于解析Hibernate配置文件和持久化映射文件中的信息,最重要的功能,是用来创建SessionFactory对象.(配置文件都要存放在CLASSPATH根路径).

SessionFactory对象:
1.负责创建Session对象.
2.数据库的连接信息是配置SessionFactory;
3.SessionFactory是线程安全的(DataSource),SessionFactory的创建需要很大的系统开销,实际上,在创建sessionFactory的时候才会去连接数据库,一般的,针对一个应用,一个数据库服务器,只需要一个SessionFactory实例就够了.
4.抽取Hibernate工具类:HibernateUtil
5.SessionFactory的重要方法:使用银行转账案例,说明openSession和getCurrentSession.

****根据对象和映射文件,在创建SessionFactory对象的时候,可以生成对应的数据表:****

hibernate.hbm2ddl.auto=create-drop :删除并创建表,关闭SessionFactory时,删除数据库表.
hibernate.hbm2ddl.auto=create :删除并创建表
hibernate.hbm2ddl.auto=update :更新表结构:
hibernate.hbm2ddl.auto=validate :验证表结构:如果表结构和映射文件不匹配,hibernate启动失败

Session对象:
1.主要方法:save/update/delete/get/createQuery/beginTransaction/getTransaction.
2.session不是线程安全的(好比Connection对象),所以,session的最大生命周期:一个线程,在web应用当中,一个session的最大生命周期:request.
3.Session中有一个缓存,称为一级缓存。存放当前工作单元加载的对象.
在一个session的生命周期之内,连续拿相同类型,相同ID的对象,只需要发送一次SQL.
4.一级缓存能提高一定的性能,但是有限.
5.session加载出来的对象,都存放于一级缓存中进行管理.
6.控制一级缓存的方法:
clear():清空一级缓存所有对象

Session中的方法的作用是用来改变对象的状态的,而不是发送SQL的.

临时状态/瞬时态(transient):刚刚用new语句创建,没有被持久化,不处于session中。特点:没有oid,不在session当中
持久化状态(persistent):已经被持久化,加入到session的缓存中。特点:有oid,在session当中
脱管态/游离状态(detached):已经被持久化,但不处于session中。特点:有oid,不在session当中
删除状态(removed):对象有关联的ID,并且在Session管理下,但是已经计划被删除。特点:有oid,在session当中,最终的效果是被删除.

判断规则:
1): 对象是否有OID;
2): 判断对象是否被Session所管理(在一级缓存中).

本文由必发娱乐官网发布于必发88手机网站,转载请注明出处:建立模型对象,它在对象模型数据和关系型数据库之间构建了一条快速

您可能还会对下面的文章感兴趣: