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());
}
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());
}
相关文章推荐
- arduino mega 2560 针脚说明
- API Guides(四)——Providing Resources To Resource Types
- 第一章 遇见HADOOP 第四节 超越批处理(hadoop:the definitive guide)
- mysql primary key & unique key
- iOS UISearchBar UISearchController
- iOS应用开发中StoryBoard搭建UI界面的基本使用讲解
- BlockingQueue
- UIDynamic物理引擎
- codeforces 609F. Frogs and mosquitoes 二分+线段树
- Volley源码解析<四> RequestQueue请求队列
- UITextField 监听数值变化的三种方法
- Request.Form[""]学习过程中遇到的异常问题
- 解决:BeanNotOfRequiredTypeException办法 @Autowired和@Resource注解的不同
- Leetcode 63:Unique Paths II
- EPUBBuilder编辑器新版
- iOS开发UI篇—transframe属性(形变)
- iOS开发UI篇—UIWindow简单介绍
- Android UI框架
- 常用AndroidUI
- OSchina android UI