您的位置:首页 > 产品设计 > UI/UE

hibernate案例入门一query transaction criteria sessionfactory和session区别 get和load的区别 opensession 和 getcurre

2016-02-24 10:02 686 查看
第一讲;hibernate入门

1. hibernate是什么

Hibernate是处于持久层一个orm框架,orm object relation mapping)是对象关系映射框架。

Struts是处于web层的一个框架。

spring 是容器框架,用于配置bean,并维护bean之间关系的框架

2. 什么是对象持久化

对象持久化就是把对象的信息保存到数据库或者文件。

3.为什么使用hibernate

(1)切换数据库比较麻烦

(2)使用jdbc操作数据库比较麻烦

(3)希望只关注业务本身,而不是数据库是什么

4.使用hibernate的好处

(1)让程序人员关心业务本身,而不关心数据库是什么

(2)分层更清晰,耦合性减小了,曾层层之间有了数据持久层做中转

(3)老程序员和新程序员写的sql语句的效率是不一样的,Hibernate会优化sql语句

5.hibernate的基础还是java的反射机制

6.Hibernare实际上就是对jdbc的轻量级封装

第二讲:hebernate入门案例

7.入门案例(手动配置完成curd操作)

(1)新建项目java project --hibernate1

(2)引入hibernate的开发包,在根目录下新建lib文件,把jar包放到lib文件夹下,然后build path-》build root path

(3)建数据库

Hibernate的daomain对象和数据库的字段是对应的

(4)开发domain对象和对象映射文件。

新建包com.sp.domain

新建类 employee(建议我们domain对象的名称就是对应表的首字母大写)

课外补充:Pojo就是简单的java对象,实际上就是普通的javabean。

Hibernate要求对象序列化,序列化的目的是为了唯一的表示该对象。同时也可以在网络和文件中传输。

employee.java

下面开发对象关系映射文件,用于指定我们的domain对象和表的映射关系。其取名建议为:表名.Hbm.xml文件,放在和domain对象同一个文件夹下。

新建employee.hbm.xml文件在com.sp.domain包下

我们的Employee.hbml.xml配置文件 :

<?xml version=”1.0” encoding=”utf-8”?>

<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.hsp.domain">

<class name="Employee" table="employee">

<!--table表示数据库字段表名,name表示package下的domain对象-->

<!-- id元素用于指定主键属性 -->

<id name="id" column="id" type="java.lang.Integer">

<!-- 该元素用于指定主键值生成策略hilo native increment sequence uuid -->

<generator class="sequence">

<param name="sequence">emp_seq</param>

(这里的名称就是创建的序列的名称,用于主键的自增长

create sequence emp_seq

start with 1

increment by 1

minvalue 1

nomaxvalue

nocycle

Nocache)

</generator>

</id>

<!-- 对其它属性还有配置 -->

<property name="name" type="java.lang.String">

<column name="name" not-null="false" />

</property>

<property name="email" type="java.lang.String" >

<column name="email" not-null="false"/>

</property>

<property name="hiredate" type="java.util.Date">--domain对象字段的名称

<column name="hiredate" not-null="false" />--数据库列的名称

</property>

</class>

</hibernate-mapping>

下面配置hibernate.cfg.xml,该文件用于配置使用数据库的信息同时管理对象映射文件。建在src文件夹下。

hibernate.cfg.xml配置文件

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<!-- hibernate 设计者,给我们提供了常用的配置 -->

<!-- 配置使用的driver -->

<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

<property name="connection.username">scott</property>

<property name="connection.password">tiger</property>

<property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orclhsp</property>

<!---jdbc:oracle:thin:@127.0.0.1:1521:orclhsp 分别是jdbc:oracle数据库:thin:@本地ip地址:端口号:数据库名->

<!-- 配置dialect方言,明确告诉hibernate连接是哪种数据库 -->

<property name="dialect">org.hibernate.dialect.OracleDialect</property>

<!-- 显示出对于sql -->

<property name="show_sql">true</property>

<!-- 指定要管理的对象映射文件 -->

<mapping resource="com/hsp/domain/Employee.hbm.xml"/>--注意这里是/不是.表示地址

</session-factory>

</hibernate-configuration>

下面我们做测试,新建testmain.java,注意引入的包

public class TestMain {

public static void main(String[] args) {

//我们创建comfiguratiom,该对象用于读取配置文件,并完成初始化

Configuration configuration=new Configuration().configure();

//创建sessionfactory

SessionFactory sessionfactory=configuration.buildSessionFactory();

//创建session相当于jdbc的connection ,不是servlet的httpsession,也不是jsp的 session

//hibernate要求程序员在进行增加删除和修改的时候,必须使用事务提交,否则不生效,查询可以不用事务。

Session Session=sessionfactory.openSession();

Transaction Transation =Session.beginTransaction();

//添加一个雇员

Employee Employee =new Employee();

Employee.setName("小明");

Employee.setEmail("2413172711@qq.com");

Employee.setHireDate(new Date());

//下面我们使用持久化,这是被hibernate封装起来的

Session.save(Employee );

Transation .commit();

Session.close();

}

}

第三讲:入门案例

Save(employee)就体现出来对象持久化了,这里hibernate去判断连接的哪种数据库,编写insert语句或者update语句存储数据到数据库中去。这里就是把对象保存到了数据库中。

把上面的代码抽取出来成为addEmployee()

下面我们写更新,sessionFactory是重量级的对象,我们应该保证sessionfactory是单台的。

新建工具包util,把它的构造方法携程私有的,加上final

静态块只会被实例化一次。

这是一个最简单的单例模式:实现加载配置文件,创建sessionfactory会话工厂等。一个数据库对应一个sessionfactory。

//外界先获取会话工厂,然后获取session()

Session session=MySessionFactory.getSessionFactory().openSession();

//要修改用户首先要获取用户再修改此用户

Transaction ts=session.beginTransaction();

Employee emp=(Employee )Session.load(Employee.class,3);

//这里体现了反射,load方法是通过主键id获取该对象实例,实例和表的记录相对应。

emp.setName(“笑话”);//这句话会导致update语句的产生,如下图:

Ts.commit();

Session.close();

去查配置文件知道employee类对应的表,因此会去更新employee表。

补充:获取一个类的class对象的3种方式:

补充:对象的三种状态:持久态 损失态 游离态

下面讲删除对象

//外界先获取会话工厂,然后获取session()

Session session=MySessionFactory.getSessionFactory().openSession();

Transaction ts=session.beginTransaction();

Employee emp=(Employee)session.load(Employee.class,3);

session.delete(emp);

ts.commit();

session.close();

第四讲:hibernate切换mysql数据库的方便

这次我们使用eclipse让hibernate自动完成domain-》映射文件-》表的工作

首先我们把hibernate配置文件重新配置

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<!-- hibernate 设计者,给我们提供了一写常用的配置 -->

<!-- 配置使用的driver -->

<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

<property name="connection.username">zhangmin</property>

<property name="connection.password">zhangmin</property>

<property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orclhsp</property>

<!-- 配置dialect方言,明确告诉hibernate连接是哪种数据库 -->

<property name="dialect">org.hibernate.dialect.OracleDialect</property>

<!-- 显示出对于sql -->

<property name="show_sql">true</property>

<!--自动 创建表 create是有表删除后再创建,没有表直接创建,update是如果有表,并且表结构没有发生变化,则不会创建新表,发生变化则创建表-->

<property name="hbm2ddl.auto">create</property>

<!-- 指定管理的对象映射文件 -->

<mapping resource="com/hsp/domain/Employee.hbm.xml"/>

</session-factory>

</hibernate-configuration>

序列是oracle的,mysql并不支持序列,下面我们修改employee.hbm.xml文件

放mysql的驱动到lib文件夹下,然后buildpath。

Hibernate针对不同的数据库使用的语句是不一样的。

由此可见,我们只需要该配置文件,无需修改任何代码就可以啦!

总结:

1.session sessionfactory transaction都是接口,configuration是类。

2.Orm对应哪个位置?

O:object 业务层

R:relation 关系型数据库

M:mapping 对象映射文件

Orm就是通过描述对象和数据库之间映射的元数据,讲java对象自动持久化到关系数据库中。

第六讲:回顾并优化项目

在更新数据的时候出现异常,我希望能够回滚。

Session session=MySessionFactory....

Transaction ts=null;

Try{

Ts.session.begin...

Int i=9/0;

}catch(Exception e)

{

If(ts!=null)

{

Ts.rollback();

}

Throw new RuntimeException(e.getMessage());

}finally

{

Session.close();

}

主键生成模式有:native identity sequence increment assign hilo uuid

Native :根据数据库底层的能力调用sequence identity increment

Assign:主键为字符类型,由用户自己设置id号

Hilo:高低位

Uuid:自动生成string类型的主键

Sequence:oracle主键自增

Increment:mysql主键自增

第十讲:opensession 和 getcurrentSession的区别

我们对工具类升级,让它可以返回一个全新的session和线程相关的session

final public class HibernateUtil {

private static SessionFactory sessionFactory=null;

//使用线程局部模式,就是把线程和变量关联起来

private static ThreadLocal threadLocal=new ThreadLocal();

private static ThreadLocal<Session> threadLocal=new ThreadLocal<Session>();

private HibernateUtil(){};

static {

sessionFactory=new Configuration().configure().buildSessionFactory();

}

//获取全新的全新的sesession

public static Session openSession(){

return sessionFactory.openSession();

}

//获取和线程关联的session

public static Session getCurrentSession(){

Session session=threadLocal.get();

//判断是否得到

if(session==null){

session=sessionFactory.openSession();

//把session对象设置到 threadLocal,相当于该session已经和线程绑定

threadLocal.set(session);

}

return session;

}

}

测试类:testmain.java

Opensession 返回的是全新的session,值是不一样的

Currentsession返回的是一样的值

1.怎么理解线程局部模式?

让变量在线程作用域中有效,不是在函数域中有效

第七讲:configuration和配置文件

Hibernate的核心类和接口?

① Configuration 类

它的用处是:

1. 读取hibernate.cfg.xml

2. 管理对象关系映射文件 *.hbm.xml

3. 加载hibernate 的驱动,url ,用户..

4. 管理hibernate配置信息

② hibernate.cfg.xml

③ 对象关系映射文件

④ SessionFactory (会话工厂)session(会话)

第九讲:get和load的区别

session.Get()和load()的区别?

1.get会返回实体类,如果查不到数据,会返回null,不会报错。load返回代理对象,如果查询不到数据,会抛出异常objectnotfoundexception。

2.使用get()去查询数据,会出现sql语句。Load()不会出现sql语句。

说明了:get()去查询数据,会先到缓存(一级二级缓存)去查,如果没有立即向db发出查询请求。Load()查询数据,即使在缓存中查询到了,返回的是一个代理对象,如果没有使用查询结果,不会真的向数据库发送查询请求,当你使用查询结果时,才向数据库发送查询请求。这种现象称为懒加载。

3.如果确定数据库有这个对象,就用load(),效率高。不确定用get()。

一级缓存实际就是sessionfactory,称为session级缓存

二级缓存介于磁盘和内存之间。

只有一次select语句,可知,使用load查询到了之后,会把结果存到二级缓存中去。这样第二次使用load时,就会在二级缓存中查到,同时,会把结果存到一级缓存中去,并且不会向数据库发送请求。如下图:

只有一个select语句。

面试:hibernate缓存分几级?有什么好处?

Session级别缓存和二级缓存。

缓存的机制就是为了减少对数据库查询的频繁访问。

第八讲:sessionfactory和session

1.sessionfactory是重量级类,一个数据库只对应一个sessionFactory

2.sessionfactory相当于一级缓存

3.Sessionfactory获取session的方法?

(1)Opensession获取全新的session

(2)getCurrentSession()获取和当前线程绑定的同一个session,这样有利于事务的控制

(3)Opensession()在事务提交后,获取的session需要手动关系,getCurrentSession()获取的session会自动提交

(4)通过opensession()进行查询可以不提交事务,getCurrentSession()进行查询需要提交事务

(5)如何选择:在同一个线程中,使用相同的session用getcurrentsession(),不同的session用opensession()。

4.如何确定你的session有没有关闭?

Windows:cmd netstat -an

oracle数据库端口:1521

Mysql:3306

Sqlserver:1433

Linix/unix netstat -ano top

5.全局事务和本地事务的区别?

Thread表示本地(局部)事务,jta表示全局事务,

本地事务:针对一个数据库的事务,全局事务:跨数据库的事务。

6.javaee中会话工厂在服务器,常驻内存。

补充:hibernate各种保存方式的区别?

第十一讲:query transaction criteria

事务:就是一组数据库操作的集合,它们要不全部成功,要不全部失败,具有原子性。

Query接口:

通过人名来检索,不能通过get和load方法了,可以使用query()接口

Query接口可以使用hql或者原生的sql来操作数据库。

Query接口的简单使用:

//获取query接口引用,这里不是指的数据库中的表,而是domain对象

Query query=session.createQuery(“ from Employee where name=’韩顺平’”);

//通过list方法获取结果,这个list会自动的讲封装成对应的domain对象,所以不用二次封装,resultset->object数组-》封装

List list= Query.list();

For(Employee e:list)

{

System.out.println(e.getAaaid()+" "+e.getHiredate());

}

Criteria接口的简单使用:

Criteria cri=session.createCriteria(Employee.class).setMaxResukts(2)返回两条记录

..add(restrictions.like(“name”,”sp%”))

.addOrder(Order.desc("id") );//要引包

List<Employee> list=cri.list();

For(Employe e :list)

{

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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: