初识Hibernate
ORM原理简介:
ORM(Object Relationnal Mapping)是对象到关系的映射,它的作用是在关系数据库和对象这件做一个自动的映射,将数据库中的表映射成为对象,也就是持久化类,对关系型数据库以对象的形式进行操作,减少开发中数据重复的编程任务。
Hibernate配置文件
Hibernate通过读取默认的XML文件himbernate.cfg.xml加载数据库的配置信息,该配置文件被默认放在classpath根目录下。(文件名可以自定义,不过后面写工具类时就要写自定义的文件名,如果按照默认的就不需要写文件名了,后面还会在详细说明)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <!-- 上面三行代码是要写上的,如果不会的话,你可以查帮助文档,问度娘,或者在你的Hibernate安装文件夹中的pfoject文件夹中招cfg.xml结尾的案例 --> <!-- 以/jndi/name绑定到JNDI的SessionFactory实例 --> <hibernate-configuration> <session-factory> <property name="dialect">org.hibernate.dialect.HSQLDialect</property><!-- 数据库方言 -->(这里是mysql) <property name="connection.driver_class">com.mysql.jdbc.Driver</property><!-- jdbc数据库驱动 --> <property name="connection.url">jdbc:mysql://localhost:3306/mydb?characterEncoding=GBK</property><!-- 链接数据库 --> <property name="connection.username">root</property><!-- 用户名 --> <property name="connection.password"></property><!-- 密码 --> <property name="show_sql">true</property> <!-- 在控制台输出生成的每一条sql语句,开发者一般为了调试写为true,后期项目结束改为false --> <!-- 映射定义文件,(文件的路径) --> <mapping resource="com/itnba/maya/hibernate/Fruit.hbm.xml"/> </session-factory> </hibernate-configuration>
Hibernate映射
1.首先了解一下持久化类(也就是基本的Bean类)
在持久化类中每一个属性都有相应的set()和get()方法。它不依赖与任何接口和继承任何类。
Hibernate中持久化类的4条编程原则:
a.实现一个默认的构造函数(所有的持久化类都必须含有一个默认的无参数构造方法),以便Hibernate通过Constructor.newInstance()实例化持久化类。
b.提供一个标识属性(也就是对应数据库中主键的字段名)
c.使用非final类
d.为属性声明访问器:持久化类的属性不能声明为public,最好是private
2.对象关系映射:对象和关系型数据库之间的映射通常使用XML文档来实现的。映射文件的命名规则为*.hbm.xml 例如(User.hbm.xml)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- 上面复制粘贴 --> <hibernate-mapping default-lazy="false" package="com.itnba.maya.hibernate"> <!-- package选填,与下面对应好即可 --> <class name="Fruit" table="Fruit"> <!-- 如果上面写了包名这里的name直接写类名即可 --> <!-- name是类属性名,表中的字段名 column="ID" 类型type="long"--> <!-- 库表中的字段名和类型最好和类中的属性名一一对应,那么这样就只写name就可以了 --> <id name="ids"> <generator class="assigned"/> <!-- 表示主键 --> </id> <property name="name"/> <!-- 以下是其他字段 --> <property name="source" /> <property name="price" /> <property name="numbers" /> <property name="image" /> </class> </hibernate-mapping>
Hibernate的3种实例状态
1.瞬时状态
实体对象new出来时,但是还没有纳入Hibernate Session的管理中,如果没有变量对其引用,他将被JVM回收,瞬时状态的对象在内存中是孤立存在的,它与数据库中的数据无任何关联,仅仅是一个信息的载体。
2.对象处于Session的缓存中和其关联的状态,处于该状态的对象也称为持久化对象。持久化对象特点:和Session关联(受其管理)数据库中有对应的记录
3.(detached)(脱管状态)数据库中有对应的记录但是没有处于Session缓存中(和Session没有关联)的状态。处于该状态的对象也称为游离对象。
脱管对象特点: 数据库中有对应记录、没有和Session关联(不受其管理)
Hibernate初始化类
Session对象是Hibernate中数据库持久化操作的核心,他负责Hibernate所有的持久化操作。那么如何获取Session对象呢?
Session对象是通过SessionFactory对象获取的,而SessionFactory又是通过Configuration对象来创建的。(代码如下)
创建HibernateUtil类,实现对Hibernate的初始化
package com.itnba.maya.hibernate; import org.hibernate.*; import org.hibernate.cfg.*; public class HibernateUtil { private static final ThreadLocal<Session> threadLocal=new ThreadLocal<Session>();//为保证线程安全,将Seeeion放到ThreadLocal中管理。这样就避免了Session的多线程共享数据的问题 private static final SessionFactory sessionFactory=BuilderFactory();//构建SessionFanctory对象 private static SessionFactory BuilderFactory() { Configuration cfg=new Configuration().configure();//加载Hibernate配置文件 return cfg.buildSessionFactory(); } //获取session public Session getSession(){ Session session=threadLocal.get();//从线程中获取session, if(session==null){//如果session为空 session=sessionFactory.openSession();//那么就用SessionFactory来创建一个session threadLocal.set(session);//并且为了线程安全,将它放进线程锁中 } return session;//返回session } //关闭session public void closeSession(){ Session session=threadLocal.get();//首先也要从线程中获取session,看是否存在这一次会话中的session if(session != null){//如果存在 session.close();//先将session关闭掉 threadLocal.set(null);//再将线程中的session移除设为空 } } }
基本添加修改删除查询操作
package com.itnba.maya.hibernatetest; import java.util.List; import org.hibernate.*; import org.hibernate.cfg.*; public class TestNigeht { public static void main(String[] args){ Session session=null; //添加 /*try{ session=HibernateUtil.getSession(); Fruit f=new Fruit(); f.setIds("z002"); f.setName("西红柿"); session.beginTransaction(); session.save(f); session.getTransaction().commit(); }catch(Exception ex){ System.out.println("数据添加失败"); ex.printStackTrace(); session.getTransaction().rollback(); }finally{ HibernateUtil.closeSession(); }*/ //查询 /*try{ session=HibernateUtil.getSession(); Fruit f=session.get(Fruit.class,"z001"); List<Fruit> list=session.createQuery("from Fruit").getResultList(); System.out.println(f.getIds()+f.getName()); for(Fruit fr:list){ System.out.println(fr.getName()); } }catch(Exception ex){ ex.printStackTrace(); System.out.println("数据查询失败"); }finally{ HibernateUtil.closeSession(); }*/ //修改 /*session=HibernateUtil.getSession(); Fruit f=session.get(Fruit.class,"z001"); if(f != null){ try{ session.beginTransaction(); f.setName("冬瓜"); session.update(f); session.getTransaction().commit();; }catch(Exception ex){ session.getTransaction().rollback(); System.out.println("数据修改失败"); ex.printStackTrace(); }finally{ HibernateUtil.closeSession(); } }*/ //删除 session=HibernateUtil.getSession(); Fruit f=session.get(Fruit.class,"z002"); if(f != null){ try{ session.beginTransaction(); session.delete(f); session.getTransaction().commit(); }catch(Exception ex){ session.getTransaction().rollback(); System.out.println("数据删除失败"); ex.printStackTrace(); }finally{ HibernateUtil.closeSession(); } } } }