一、开发实现的细节
1、 domain实体类的限制
a) 必须有默认的构造方法:
hibrnate会利用反射机制生成相对应的实体对象时会调用该类的无参构造方法
User user=User.class.newInstance();
b) 主键id (可选)
c) 类是非final的,对子类的生成有影响 (可选)
2、 映射文件
一个java类在映射文件中用一对<class></class>标签表示。
如果有多个java类在映射文件中就应该有多个<class></class>标签。
对于这些<class></class>标签标签也可以放到一个映射文件中,也可以放到多个映射文件中。
实体类名.hbm.xml
<hibernate-mapping
package="com.hbsi.domain"> //指的是实体类所在的包
<class name="User" table="user"> //name和table得值是一样的,则table可以省略,完成java类名和表名建立关系
<id name="id" column="id"> //主键,特殊单独拿出来进行联系,主键的生成方法有多种,所以要用属性generator来指定生成方法
<generator class="native"/>//指定主键生成器
</id>
<property name="name"/>//类中的普通属性和表中的列建立关系用property
<property name="brithday"/>
</class>
</hibernate-mapping>
3、 java代码的编写
Configuration cfg=new Configuration();
cfg.configure();//完成hibrnate的初始化--读取配置文件
寻找放在classpath路径下的默认的hibrnate.cfg.xml文件
//SessionFactory对象-----相当于jdbc代码中DriverManager驱动器管理器
sf=cfg.buildSessionFactory();
以上三步很耗时,所以要优化代码:
建立一个工具类:HibrnateUtil
packagecom.hbsi.hibrnate;
importorg.hibernate.Session;
importorg.hibernate.SessionFactory;
importorg.hibernate.cfg.Configuration;
public finalclass HibrnateUtil {//工具类一般不被继承所以是final的,工具类一般不被实例化成对象,所以构造方法为private的
private static SessionFactory sf;
private HibrnateUtil(){
}
//只在类被加载的时候执行一次
static{
Configuration cfg=new Configuration();
cfg.configure();//完成hibrnate的初始化--读取配置文件
//SessionFactory对象-----相当于jdbc代码中DriverManager驱动器管理器
sf=cfg.buildSessionFactory();
}
public static SessionFactory getSf() {//为了在类的外面获取到
return sf;
}
public static Session getSession(){
return sf.openSession();
}
}
测试类:
packagecom.hbsi.test;
importjava.util.Date;
importorg.hibernate.HibernateException;
importorg.hibernate.Session;
importorg.hibernate.Transaction;
import com.hbsi.domain.User;
import com.hbsi.hibrnate.HibrnateUtil;
public classTestHibrnate {
public static void main(String[] args) {
User user=new User();
user.setName("jerry");
user.setBrithday(new Date());
addUser(user);
System.out.println("end");
}
static void addUser(Object obj){
Session s=null;
Transaction tx=null;
try{
s=HibrnateUtil.getSession();
tx=s.beginTransaction();//开启事务
s.save(obj);//将user对象保存到数据库表中
tx.commit();//事务的提交
}catch(HibernateException e){
if(tx!=null){//证明事务正确开启了,而是保存出错了
tx.rollback();
}
throw e;
}finally{
if(s!=null){
s.close();
}
}
}
static void addUser1(Object obj){//等价于上面的方法,不对异常进行处理,直接进行抛出去了
Session s=null;
Transaction tx=null;
try{
s=HibrnateUtil.getSession();
tx=s.beginTransaction();
s.save(obj);
tx.commit();
}finally{
if(s!=null){
s.close();
}
}
}
}
二、org.hibrnate.Session接口中的常用方法
1、 save,persist保存数据。
在不开启事务的时候:
save()方法时产生了insert语句并执行,但由于没有提交事务,所以最终被事务被回滚删掉了。
Persist()在事务外不会产生insert语句。
//插入
static void addUser(Object obj){
Session s=null;
Transaction tx=null;
try{
s=HibrnateUtil.getSession();
tx=s.beginTransaction();//开启事务
s.save(obj);//将user对象保存到数据库表中
tx.commit();//事务的提交
}catch(HibernateException e){
if(tx!=null){//证明事务正确开启了,而是保存出错了
tx.rollback();
}
throw e;
}finally{
if(s!=null){
s.close();
}
}
}
static void addUser1(Object obj){//等价于上面的方法,不对异常进行处理,直接进行抛出去了
Session s=null;
Transaction tx=null;
try{
s=HibrnateUtil.getSession();
tx=s.beginTransaction();
s.save(obj);
tx.commit();
}finally{
if(s!=null){
s.close();
}
}
}
2、delete,删除对象
3、update,更新对象,如果数据库中没有记录,会出现异常。
在托管状态下想要改变值,需要调用update()方法更新数据
在持久状态下不用调用update()方法,因为在此状态下hibrnate会直接调用
4、get,根据ID查,会立刻访问数据库。
//查找
由于session可以管理多个数据库表所对应的多个实体对象,如果要查询id为1的实体对象,session.get方法需要知道去从那个数据库表中查询id为i1的记录,所以,除了给get方法传递所要查询的实体对象的id值外,还必须给get烦恼过分传递实体对象的类型,get方法才能知道去哪个数据库表中进行查询
public static User getUser(int id){
Session s=null;
try{
s=HibrnateUtil.getSession();
Class clazz=User.class;//通过反射机制读取映射文件,获取到是那张表与该类相对应
User user=(User)s.get(clazz,id);
return user;
}finally{
if(s!=null){
s.close();
}
}
}
5、Load,根据ID查,(返回的是代理,不会立即访问数据库,当第一次访问的时候才会加载数据库)。
//load()方法查找
public static User getUser1(int id){
Session s=null;
try{
s=HibrnateUtil.getSession();
Class clazz=User.class;//通过反射机制读取映射文件,获取到是那张表与该类相对应
User user=(User)s.load(clazz,id);//懒加载,返回代理对像,该对象永不为空
System.out.println(user.getId()+":"+user.getName());//第一次使用该对象,需要连接数据库
return user;
}finally{
if(s!=null){
s.close();
}
}
}
6、saveOrUpdate,merge(根据ID和version的值来确定是save或update),调用merge你的对象还是托管的。
7、lock(把对象变成持久对象,但不会同步对象的状态)。
五、对象状态
·瞬时(transient):
数据库中没有数据与之对应,一般是new出来且与session没有关联的对象,超过作用域会被JVM垃圾回收器回收。
User user=new User();//user是一个瞬时对象
·持久(persistent):
数据库中有数据与之对应,当前与session有关联,并且相关联的session没有关闭,事务没有提交;持久对象状态发生改变,在事务提交时会影响到数据库(hibernate能检测到)。
·脱管(detached):
数据库中有数据与之对应,但当前没有session与之关联;托管对象状态发生改变,hibernate不能检测到。