hibernate知识

来源:互联网 发布:迅雷emule监听端口 编辑:程序博客网 时间:2024/05/19 06:38

1、引入
  模型不匹配:
  java面向对象语言,对象模型,主要概念有继承、关联、多态等;数据库是关系模型,主要概念有表、主键、外键等。
  解决办法:
  1>使用JDBC手工转换
  2>使用ORM框架来解决,主流的ORM框架有hibernate、topLink、OJB。
  
2、安装配置
  配置文件hibernate.cfg.xml和hibernate.properties两种,这两个文件的作用一样,提供一个即可,推荐使用xml格式,下载目录/etc下是实例配置文件。
  可以在配置文件下指定:
  数据库的url,用户名,密码,jdbc驱动类,方言等。
  启动时hibernate会在classpath里找这个配置文件。
  映射文件:
  xx.hbm.xml,对象模型和关系模型的映射。
 
3、基本概念和CRUD
  开发流程:
  1>由Domain Object ->mapping ->db (官方推荐)
  2>由DB开始,用工具生成mapping和Domain object(使用较多)
  3>由映射文件开始

4、Domain Object的限制:
  1>默认的构造方法(必须的,反射用到);
  2>有无意义的标示符id(主键,可选);
  3>非final的,对懒加载有影响(可选);

5、Hibernate应用步骤:
  1>设计Domain对象xxx;
  2>设计接口xxxDao;
  3>导入hibernate.jar包和其依赖的包;
  4>编写xxx.hbm.xml映射文件,可以基于hibernate/eg目录下的org/hibernate/auction/User.hbm.xml修改;
  5>编写hibernate.cfg.xml配置文件,可以基于hibernate/etc/hibernate.cfg.xml修改;必须提供的几个参数:connection.driver_class、connection.url、connection.username、connection.password、dialect、hbm2ddl.auto;
  6>编写工具类HibernateUtils,主要用来完成Hibernate初始化和一个用于获取session的方法;
  7>实现xxxDao接口。
 
  配置文件:hibernate.cfg.xml
  <hibernate-configuration>
  <session-factory>
   <!-- 连接属性 -->
   <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
   <property name="connection.url">jdbc:mysql:///test_20120119</property>
   <property name="connection.username">root</property>
   <property name="connection.password">123456</property>
   <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
   
   <!-- 操作表机制 -->
   <property name="hbm2ddl.auto">update</property>
   
   <!-- 打印sql语句 -->
   <property name="show_sql">true</property>
   
   <!-- 配置映射文件,注意这里是“/”分割 -->
   <mapping resource="cn/itcast/domain/User.hbm.xml"/>
  </session-factory>
  </hibernate-configuration>

  映射文件:user.hbm.xml
  <?xml version="1.0"?>
  <hibernate-mapping package="cn.itcast.domain">
    <class name="User">
   <id name="id">
     <generator class="native"/>
   </id>
   <property name="name" unique="true"></property>
   <property name="birthday"></property>
   </class>
   </hibernate-mapping>
  
   java代码:
   1>初始化代码:(放在工具类HibernateUtil.java中,相当耗时,只需做一次)
   Configuration cfg = new Configuration();
  cfg.configure();
  sessionFactory = cfg.buildSessionFactory();
  2>模板代码:
  Session session = null;
  Transaction tx = null;
  try {
   session = HibernateUtil.getSession();
   tx = session.beginTransaction();
   // 你的代码,save,delete,update,query等;
   tx.commit();
  } catch (Exception e) {
   if (tx != null) {
    tx.rollback();
    throw e
   }
  } finally {
   if (session != null) {
    session.close();
   }
  }

6、Session的主要方法:
  1>save,persist保存数据,persist在事务外不会产生insert;
  2>delete,删除对象
  3>update,更新对象,如果数据库中没有记录,会出现异常;
  4>get,根据id查询,会立刻访问数据库;
  5>load,根据id查询,返回的是代理,不会立即访问数据库;
  6>saveOrUpdate,merge,根据id和version的值来确定是save还是update,调用saveOrUpdate之后,对象变为持久的;调用merge之后,对象还是托管的;
  7>lock,把对象变成持久对象,但不会同步对象的状态。
 
7、对象状态(判断条件:数据中是否有记录,当前是否与session关联):
  瞬时(transient):数据库中没有数据与之对应,超过作用于会被JVM垃圾回收器回收,一般是指new出来且与session没有关联的对象。
  持久(persist):数据库中有数据与之对应,当前与session有关联,并且关联的session没有关闭,事务没有提交;持久对象状态发生改变,在事务提交时会影响到数据库(hibernate能检测到)。
  脱管(detached):数据库中有数据与之对应,但当前没有session与之关联,托管对象状态发生改变时,hibernate不能检测到。
 
  三个对象转换图:
 
8、HQL和Criteria
  HQL(Hibernate Query Language):
  面向对象的查询语言,与SQL不同,HQL中的对象(java类和属性)是区分大小写的,HQL中查询的是对象而不是表,并且支持多态。
  HQL主要通过Query来操作,Query的创建方式:
  String hql = "from User as user where user.name=:name and user.birthday<:birthday";
  Query query = session.createQuery(hql);
 
  Criteria:
  Criteria是一种比HQL更面向对象的查询方式,Criteria的创建方式:
  Criteria criteria = session.createCriteria(DomainClass.class);
  简单属性条件:
  criteria.add(Restrictions.eq(propertyName, value));
  criteria.add(Restriction.eqProperty(propertyName,otherPropertyName));
 
9、关联映射:
  1>多对一(employee---department)
    Employee.hbm.xml中配置:
    <many-to-one name="depart" column="depart_id">
  2>一对多(department---employee)
    Department.hbm.xml中配置:
    <set name="employees" cascade="save-update" inverse="true">
   <key column="depart_id"></key>
   <one-to-many class="Employee"/>
   </set>
  3>一对一(person---idCard)
    1)基于主键的一对一:
     IdCard.hbm.xml中配置:
     <id name="id">
       <generator class="foreign">
      <param name="property">person</param>
     </generator>
     </id>
     Person.hbm.xml中配置:
     <one-to-one name="idCard" constrained="true"/>
    2)基于外键的一对一:
      可以描述为多对一,加unique="true"约束
      Person.hbm.xml中配置:
      <one-to-one name="idCard" property="person"/>
      IdCard.hbm.xml中配置:
      <many-to-one name="person" column="person_id" unique="true" not-null="true"></many-to-one>
  4>多对多(teacher---student)
    在操作和性能方面都不太理想,所以多对多的映射使用较少,使用中最好转换成一对多的对象模型,hibernate会为我们创建中间关联表,转换成两个一对多。
    <set name="students" table="teacher_student">
   <key column="teacher_id"></key>
   <many-to-many class="Student" column="student_id"></many-to-many>
  </set>
  5>组件映射(user---name)
    关联的属性是个复杂类型的持久化类,但不是实体,即数据库中没有表与该属性对应,但该类的属性是要持久保存的。
    <component name="name">
   <property name="firstName" column="first_name"></property>
   <property name="lastName" column="last_name"></property>
  </component>
  6>集合映射(set,list,array,map,bag)
    这些集合类都是hibernate实现的类,和java中集合类完全不一样,set,list,map分别和java中的Set,List,Map接口对应,bag映射成java中的List,这些集合的使用和java集合中对应的接口基本一致,在java的实体类中,集合只能定义为接口,不能定义为具体类,因为集合会在运行时被替换成hibernate的实现。
    集合的简单使用原则:
    大部分情况下使用Set,需要保证集合中的顺序时使用List,想用java.util.List又不需要保证顺序时使用bag。
    <set name="employees">
   <key column="depart_id"></key>
   <one-to-many class="Employee"/>
   </set>
  7>inverse和cascade(employee---department)
    cascade用来说明当对主对象进行某种操作时,是否也对从对象进行类似的操作,常用的cascade:
    none,all,save-update,delete,lock,refresh,evict,replicate,persist,merge,delete-orphan(one-to-many)。一般对many-to-one,many-to-many不设置级联,对one-to-one和one-to-many设置级联;
    inverse表示是否放弃维护关联关系(在java里两个对象产生关联时,对数据库表的影响);在one-to-many和many-to-many的集合定义中使用,inverse="true"表示该对象不维护关联关系;在属性一般在使用有序集合时设置成false,hibernate的缺省值为false;
    one-to-many维护关联关系就是更新外键;
    many-to-many维护关联关系就是在中间表增减记录。
    注意:配置成one-to-one的对象不维护关联关系。
 
   规律:只有在一对一关联关系中,查询主对象时,是直接左外连接查询,其他都是分两次查询。
  
   如何处理对象之间的关联关系的底层细节,可从两个方面思考:
   1>如何将对象之间的关联关系保存到数据库;
   2>如何检索出关联关系。
 
10、继承映射:
    1>一个类继承体系对应一张表(subclass)
     特点:效率高,空字段多。
     例如:
     employee表:id,name,depart_id,type,skill,sell
  2>每个子类对应一张表(joined-subclass)
   特点:空字段少,效率低。
   例如:
   employee表:id,name,depart_id
   skill表:id,skill
   sell表:id,sell
 
 

 

原创粉丝点击