<class name = "Event" table = "EVENTS" >
<id name = "id" column = "EVENT_ID" >
<generator class = "native" />
</id>
< propertyname="date" type="timestamp" column="EVENT_DATE"/>
< property name="title"/> </class>
</hibernate-mapping>
name="id"
mapping attribute declares the name of the JavaBean property and tells Hibernate to use the
getId()
and
setId()
methods to access the property. The column attribute tells Hibernate which column of the
EVENTS
table holds the primary key value.
date
property mapping include the
column
attribute, but the
title
does not? Without the
column
attribute, Hibernate by default uses the property name as the column name. This works for
title
, however,
date
is a reserved keyword in most databases so you will need to map it to a different name.
title
mapping also lacks a
type
attribute. The types declared and used in the mapping files are not Java data types; they are not SQL database types either. These types are called
Hibernate mapping types, converters which can translate from Java to SQL data types and vice versa. Again, Hibernate will try to determine the correct conversion and mapping type itself if the
type
attribute is not present in the mapping. In some cases this automatic detection using Reflection on the Java class might not have the default you expect or need. This is the case with the
date
property. Hibernate cannot know if the property, which is of
java.util.Date
, should map to a SQL
date
,
timestamp
, or
time
column. Full date and time information is preserved by mapping the property with a
timestamp
converter.
Tip
Hibernate makes this mapping type determination using reflection when the mapping files are processed. This can take time and resources, so if startup performance is important you should consider explicitly defining the type to use
hibernate.properties
file(key-value), a more sophisticatedhibernate.cfg.xml
file, or even complete programmatic setup. Most users prefer the XML configuration file
SessionFactory
. SessionFactory is a global factory responsible for a particular database. If you have several databases, for easier startup you should use several
<session-factory>
configurations in several configuration files.
6.PO的操作必须在Session管理下才能同步到数据库。session由sessionfactory工厂产生,sessionfactory是数据库编译后的内存镜像,通常一个应用对应一个sessionfactory对象。sessionfactory对象由configuration对象产生,configuration对象负责加载hibernate配置文件
7.hibernate的优点
1)不需要使用编写sql语句,而是允许采用oo方式来访问数据库
2)jdbc访问过程中大量的checked异常被包装成hibernate的runtime异常,从而不再要求程序必须处理所有异常
8.eclipse中可以借助一些插件,middle gen/ synchronizer等,根据数据表生成pojo,或者根据pojo生成配置文件等
9.validate 加载hibernate时,验证创建数据库表结构 create 每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。 create-drop 加载hibernate时创建,退出是删除表结构 update 加载hibernate自动更新数据库结构
10.session缓存的作用
1)减少访问数据库的频率
Transation tx = session.beginTransaction();
//第一次执行session的get()方法,缓存里没有没有OID为1的对象,所以通过SQL select语句到数据库中加载该对象,并把它放到session缓存中
Customer c1 = (Customer)session.get(Customer.class,new Long(1));
//第二次执行session的get()方法,get()方法先到Session缓存里找OID为1的对象,由于上面已经存在了这样的对象,就直接返回该对象的引用,所以c1,c2引用的是同一个对象
Customer c2 = (Customer)session.get(Customer.class,new Long(1));
system.out.println(c1==c2);//true
2)当缓存中的持久化对象之间存在循环关联关系时,session会保证不出现访问对象力的死循环,以及由死循环引起的jvm堆栈溢出异常
3)保证数据库中的相关记录与缓存中的相应对象保持同步
customer.setName("tome");
session.save(customer);
customer2 = (customer)session.get(Customer.class,customer.getId());
customer2.setName("jake");
tx.commit();//插入的是jake(脏数据检查)
11.三种状态
User user = new User();// user瞬时状态,与数据库和session都没有关系,生命周期:退出作用域,就会被jvm垃圾回收
session.save(user);// user处于持久状态,数据库中已经有记录与之对应起来,处于session里面。在此状态下发生的任何变化hibernate都知
//若有user.setName();看sql语句,会有update这条语句,所以,在此状态下(还没close)发生的变化,hibernate都知,所以在此状态下要改变值不用调用update(),而在脱管状态下要改变值要调用update()
session.close();//user处于脱管状态,与session无关系,但是数据库中有些记录,该user有数据库中存入的id值,在脱管状态对象的值发生改变,要更新到数据库中就要调用update()
而持久的状态不用
12.不知什么状态的时候,调用saveOrUpdate,判断是否有id,有id就更新,没id就保存(整型的话id==0,其他类型都id==null)也可在配置文件中设置<id unsaved-value="-1">等,默认是0,null
13.merge与saveOrUpdate的区别:前者执行后状态还是脱管的,后者执行后状态变成持久的
14.String hql="from User as user where user.name=?";//注User是对象,不是表名,如果写表名会出错,区分大小写,支持多态,可以把User改成Object,会把数据库中所有的表都查询一遍