1.
#hibernate.hbm2ddl.auto create-drop 程序启动,hibernate初始化的时候,删掉表,创建表;程序运行结束后把所有表删掉。
#hibernate.hbm2ddl.auto create 程序启动,在创建表前会把表删掉。当虚拟机退出的时候(在hibernate退出的时候),它不会删表 (和上一种通常在测试环境下使用)
#hibernate.hbm2ddl.auto update 如果不一致,会更新一下表结构
#hibernate.hbm2ddl.auto validate 会校验映射文件跟表结构是否对应,如果不对应,不会update,而是报错。(这种方式更安全一些)
2.
Domain Object限制:
(1).必需要有一个无参构造函数
(2).有无意义的标示符id(主键)(可选)
(3).非final的,对懒加载有影响(可选)
3.
pubic final class HibernateUtil{
private static SessionFactory sessionFactory;
private HibernateUtil(){}
static{
Configuration cfg = new Configuration();
cfg.configure(); //如果文件名不是hibernate.cfg.xml,则可写成cfg.configure("abc.xml");
sessionFactory = cfg.buildSessionFactory();
}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
}
(1).声明为final,因为HibernateUtil类不需要被继承
(2).HibernateUtil不想被new,所以可以把构造方法设为private
(3).虚拟机加载这个类的时候,会执行static里面的代码,而且只执行一次
标准的结构
public class Main {
public static void main(String[] args) {
User user = new User();
user.setBirthday(new Date());
user.setName("name");
addUser(user);
}
static void addUser(User user){
Session s=null;
Transaction tx=null;
try{
s=HibernateUtil.getSession();
tx=s.beginTransaction();
s.save(user);
tx.commit();
}catch(HibernateException e){
if(tx!=null){
tx.rollback();
throw e;
}finally{
if(s!=null){
s.close();
}
}
}
}
}
4. 未解决的疑问 15分钟左右,关于load的println (解决了?因为session关闭了?)
a.在hibernate.cfg.xml里,true可以在运行时,把sql打印出来
b.session的get和load方法的区别?
最大区别:load不会立刻去访问数据库(所以不会打印出select语句),当第一次使用时,才会去访问数据库。
load返回的是代理,不会立即访问数据库
load是懒加载
在代码 User user1 = (User)session.load(User.class, id);
if(user1 != null){} 中; user1是永远都不会是空的,即使id为-1213212(不存在),原理,在运行load方法时,会new一个User的子类
c.save和persist方法的区别:
save,persist保存数据,persist在事务外不会产生insert语句。
唯一区别: 在没开启事务的时候,save方法会运行insert语句插入数据,但是因为事务没开启,所以回滚了。
persist方法见到没开启事务,就不会插入数据。
Session的几个主要方法
1.save,persist保存数据,persist在事务外不会产生insert语句。
2.delete,删除对象
3.update,更新对象,如果数据库中没有记录,会出现异常。
4.get,根据ID查,会立刻访问数据库。
5.load,根据ID查,(返回的是代理,不会立即访问数据库)。
6.saveOrUpdate,merge(根据ID和version的值来确定是save或update),调用merge你的对象还是托管的。
7.lock(把对象变成持久对象,但不会同步对象的状态)
5.
对象状态
瞬时(transient):数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来且与session没有关联的对象。
持久(persistent):数据库中有数据与之对应,当前与session有关联,并且相关联的session没有关闭,事务没有提交;持久对象状态发生改变,在事务提交时会影响到数据库(hibernate能检测到)。
脱管(detached):数据库中有数据与之对应,但当前没有session与之关联;脱管对象状态发生改变,hibernate不能检测到
eg. session.save(user); user.setName("new name"); tx.commit;
结果,两条语句,一条insert,一条update。 说明处于持久状态的对象,他发生变化的时候,hibernate能知道
eg. session.save(user); user.setName("new name"); user.setBirthday(new Date()); tx.commit;
结果,两条语句,一条insert,一条update。 持久对象变化时不会立即更新数据库,而是等到commit时才做
hbm.xml文件中, unsaved-value可以不配,默认情况下,如果id是整数,则unsaved-value是0;如果id是String,则unsaved-value是空。 在保存时,hibernate会先读配置文件,如果配置了这个值,则比较,如果相等,则是瞬时的,就保存