hibernate对象的三种状态:
(一) 瞬时(临时)状态: 对象被创建时的状态,数据库里面没有与之对应的记录!
(二) 持久状态: 处于session的管理中,并且数据库里面存在与之对应的记录!
(三) 游离状态: 对象不处于session的管理中,但是数据库里面存在与之对应的记录!
对象与session产生关系的时机:
1、save()或者saveorupdate();
2、get()或者load();
清空缓存:
1、clear();//清空所有加载的实例
2、evict(实例);//从缓存里面移除这个实例——效果同上,需要指定实例,对象
三种状态的转换过程:
hibernate涉及的脏检查:
当事务提交时(commit),hibernate会检查session中处在持久状态的对象, 判断与数据库是否一致,不一致则会将缓存里面的数据更新掉数据库里面的数据!
那么session什么时候刷新缓存:
1、执行commit方法时 //执行脏检查
2、session.flush(); //不会提交事务执行脏检查
更新数据的方法:
update(对象):
saveOrUpdate(对象):
1、通过id查询主键,存在就更新,不存在就新增!
2、当mapping配置文件的generator节点的class属性不为assigned时,造成只有update没select时,更改class为assigned可以解决!
3、不会发起查询,直接更新 merge(对象):合并,先查询,与缓存里面的数据比较一样时不做任何操作,不一样时,再更新或者插入!效率更高!
saveOrUpdate(对象)与merge(对象)方法:
1、主键生成策略:assigned
操作一样!
2、主键生成策略:sequence,动态更新(dynamic-update="true")策略
saveOrUpdate(对象)只更新
merge(对象)先发起一条查询语句,在发起更新或者插入语句
1 public static boolean addDept(){ 2 boolean flag=false; 3 Configuration conf=null; 4 SessionFactory factory=null; 5 Session session=null; 6 Transaction trans=null; 7 try { 8 //读取配置文件 9 //指定配置文件 10 //conf=new Configuration().configure("xxx.cfg.xml"); 11 conf=new Configuration().configure(); 12 //创建sessionfactory 13 factory=conf.buildSessionFactory(); 14 //打开会话 15 session=factory.openSession(); 16 //开启事务 17 trans=session.beginTransaction(); 18 19 Dept dept=(Dept)session.get(Dept.class, 8); 20 //当设置了gennerator为sequence时,不给参数是以指定sequence填值 21 //dept.setDeptno(10); 22 dept.setDeptname("test测试部"); 23 dept.setLoc("xz"); 24 //持久化 25 //session.save(dept); 26 //session.delete(dept); 27 //Dept dp=(Dept)session.get(Dept.class, 1);//没有数据,返回空值 28 //System.out.println(dp.getDeptname()); 29 //延迟加载 30 //Dept dp=(Dept)session.load(Dept.class, 5);//没有数据,报异常 31 //保存或更新 32 session.saveOrUpdate(dept); 33 //合并 34 //session.merge(dept); 35 //提交事务 36 trans.commit(); 37 38 flag=true; 39 } catch (Exception e) { 40 e.printStackTrace(); 41 trans.rollback(); 42 }finally{ 43 if(session!=null){ 44 session.close(); 45 46 } 47 }
补充:
配置文件节点以及属性总结:
hbm映射配置文件:
1、通常情况下,一个mapping只写一个class节点,因此一个mapping文件对应一个(类与数据库表);
class节点:
name属性:对象的路径,这里指大路径、对象名!
也可以在<hibernate-mapping>节点pakage属性指定包路径,只写对象名
table属性:指定数据库表名,可以忽略大小写
dynamic-update属性:指定是否动态更新,这个属性在saveOrupdate/merge方法执行时,尤为重要!
id节点:
主键配置:oid:object 对象的编号
name:实体类里面属性的名称;
column:数据库表里面的列:不写表示和实体类属性名一致!
generator节点:
生成器:
主键的生成策略:通过class设定:
assign:由程序指定主键值!
foreign:由外键生成!
identity:标识列!sqlserver支持!
sequence:序列,oracle,db2,!
increment:自增,mysql!
native:由数据库自己决定以上哪种方式!
param节点:
指定索引名
property节点:
type:属性的类型,可以是java类型(要写完全限定名),也可以是hibernate类型!可以省略
示例:
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5 <!-- 类和表 属性和字段的关系 --> 6 <!-- <hibernate-mapping package="cn.cy.Hibernate.entity"> --> 7 <hibernate-mapping> 8 <!-- 与关键字冲突 ”~~“解决 --> 9 <!-- 通常一个mapping只写一个class节点 --> 10 <!-- 类名和表名可以不一样! --> 11 <class name="cn.cy.Hibernate.entity.Dept" table="dept" dynamic-update="true"> 12 <!-- <class name="Dept" table="dept"> --> 13 <!-- 当数据库里面的列明与java属性一致时,我们可以省略colnumn --> 14 <!-- 15 主键配置:oid:object 对象的编号 16 name:实体类里面属性的名称; 17 column:数据库表里面的列:不写表示和实体类属性名一致! 18 --> 19 <id name="deptno" column="deptno"> 20 <!-- 21 生成器: 22 主键的生成策略:通过class设定: 23 assign:由程序指定主键值! 24 foreign:由外键生成! 25 identity:标识列!sqlserver支持! 26 sequence:序列,oracle,db2,! 27 increment:自增,mysql! 28 native:由数据库自己决定以上哪种方式! 29 --> 30 <generator class="sequence"> 31 <!-- 指定序列名 --> 32 <param name="sequence">seq_index</param> 33 </generator> 34 </id> 35 <!-- 36 性质: 37 type:属性的类型,可以是java类型(要写完全限定名),也可以是hibernate类型!可以省略 38 column:可以单独写成子节点! 39 --> 40 <property name="deptname" column="deptname" type="java.lang.String" /> 41 <property name="loc" column="loc" type="java.lang.String"/> 42 </class> 43 </hibernate-mapping>
cfg指定数据库配置文件:
1 <!DOCTYPE hibernate-configuration PUBLIC 2 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 4 5 <hibernate-configuration> 6 <session-factory> 7 8 <!-- 指定oracle对应得dialect --> 9 <property name="dialect"> 10 org.hibernate.dialect.Oracle10gDialect 11 </property> 12 <!-- 数据库jdbc驱动 --> 13 <property name="connection.driver_class"> 14 oracle.jdbc.driver.OracleDriver 15 </property> 16 17 <!-- 数据库url --> 18 <property name="connection.url"> 19 jdbc:oracle:thin:@localhost:1521:XE 20 </property> 21 22 <!-- 用户名 --> 23 <property name="connection.username">user_admin</property> 24 <!-- 用户密码 --> 25 <property name="connection.password">abc123</property> 26 27 <!-- session范围和上下文 --> 28 <property name="current_session_context_class">thread</property> 29 <!-- 是否在运行期间生成的SQL输出到日志以供调试 --> 30 <property name="show_sql">true</property> 31 <!-- 是否格式化sql --> 32 <property name="format_sql">true</property> 33 <!-- 映射 --> 34 <mapping resource="cn/cy/Hibernate/entity/Dept.hbm.xml" /> 35 </session-factory> 36 </hibernate-configuration>
我可以自己命名cfg.xml文件吗?
答案是可以的:
1 //读取指定配置 2 conf=new Configuration().configure("xxx.cfg.xml"); 3 //读取默认配置hibernate.cfg.xml 4 conf=new Configuration().configure();