Hibernate 学习笔记

    技术2022-05-11  13

    继承实现的三中策略 单表继承。每棵类继承树使用一个表(table per class hierarchy)  具体表继承。每个子类一个表(table per subclass)  类表继承。每个具体类一个表(table per concrete class)(有一些限制) 单表继承 <discriminator column="discriminator_column" type="discriminator_type" /> <subclass name="com.test.hibernate.Student">  <property name="number" column="studentNumber"/> </subclass>

    双向关联  概念:双向关联允许通过关联的任一端访问另外一端。在Hibernate中, 支持两种类型的双向关联。  一对多(one-to-many),Set或者bag值在一端, 单独值(非集合)在另外一端 。  多对多(many-to-many),两端都是set或bag值。例子(双向关联):group-user<class name="com.test.hibernate.Group" table="TBL_GROUP"> <id name="id" column="groupId"><generator class="native"></id> <set name="users" lazy="true" cascade="save-update" inverse="true">    <key column="groupId"/>  <one-to-many class="com.test.hibernate.User"/> </set></class>

    <class name="com.test.hibernate.User" table="TBL_USER"> <id name="id" column="userId"><generator class="native"/></id> <many-to-one name="group" column="groupId" outer-join="false"/></class>例子:从Java代码看group-user双向关联的inverse  概念:inverse用来标识双向关联的关联关系由哪一端维护。默认inverse的值为false,由主动方负责维护关联关系;如果设为true,则由反向一端维护关联关系。  用例:我们假设已经有一个Group类的实例:adminGroup,现在我们要新增一个用户,并且将用户分配到adminGroup中。  inverse="false",由主动方Group负责维护group-user的关联关系.  User user = new User("Jak");  adminGroup.getUsers.add(user);  session.save(user); session.update(group);  inverse="true",由Group的反向段User负责维护关联关系。  User user = new User("Jak");  user .setGroup(adminGroup); session.save(user);

    持久化对象的生命周期(lifecycle)Hibernate脏数据字段捡入  检索一个用户,并将它的用户名更改为"Mary"  Session session = sessionFactory.openSession();  Transaction tx = session.beginTransaction();  User user = (User) session.get(User.class, userId);  user.setName("Mary");  tx.commit();  session.close();持久化对象必须唯一  一个Session中不能同时存在两个ID相同的持久化对象 例如:id为userId的user_1对象已经存在Session中,这时如果Session中试图产生一个user_2对象!!  Session session = sessionFactory.openSession();  Transaction tx = session.beginTransaction();  User user_1 = (User)session.get(User.class,userId);  User user_2 = new User(userId,"Mary");  session.update(user_2); 最后将会产生异常:net.sf.hibernate.NonUniqueObjectException:  a different object with the same identifier value was already associated with the session 解决办法: 使用evict ()方法将user_1实例从session中去除。session.evict(user_1);

    Hibernate查询 概述:数据查询与检索是Hibernate中的一个亮点。相对其他ORM实现而言,Hibernate提供了灵活多样的查询机制。 标准化对象查询(Criteria Query):以对象的方式进行查询,将查询语句封装为对象操作。优点:可读性好,符合Java 程序员的编码习惯。缺点:不够成熟,不支持投影(projection)或统计函数(aggregation) Hibernate语言查询(Hibernate Query Language,HQL):它是完全面向对象的查询语句,查询功能非常强大,具备继承、多态和关联等特性 。Hibernate官方推荐使用HQL进行查询。 Native SQL Queries(原生SQL查询):直接使用数据库提供的SQL方言进行查询。例子:标准化对象查询(Criteria Query) 简单例子:查询用户名以"J"开头的所有用户。 Criteria criteria = session.createCriteria(User.class);        criteria.add(Expression.like("name","J%"));        List users = criteria.list();Hibernate语言查询(Hibernate Query Language,HQL) HQL用面向对象的方式生成SQL 以类和属性来代替表和数据列 支持多态 支持各种关联 减少了SQL的冗余 HQL支持所有的关系数据库操作 连接(joins,包括Inner/outer/full joins),笛卡尔积(cartesian products) 投影(projection) 聚合(Aggregation,max, avg)和分组(group) 排序(Ordering) 子查询(Subqueries) SQL函数(SQL function calls)

    例子: Hibernate语言查询(Hibernate Query Language,HQL) 简单例子:查询用户名以"J"开头的所有用户。 Query query = session.createQuery(   "from User user where user.name like 'J%'");        List users = query.list(); 复杂例子:从User和Group中查找属于"admin"组的所有用户。 Query query = session.createQuery(   "from User user where user.group.name='admin'");

    如果用传统的SQL则查询语句如下: select user.userId as userId, user.name as name, user.groupId as groupId, user.idCardId as idCardId   from TBL_USER user, TBL_GROUP group  where (group.groupName='admin'  and user.groupId=group.groupId)

    Hibernate最佳实践(Best Practices)1、使用Configuration装载映射文件时,不要使用绝对路径装载。最好的方式是通过getResourceAsStream()装载映射文件,这样Hibernate会从classpath中寻找已配置的映射文件。2、SessionFactory的创建非常消耗资源,整个应用一般只要一个SessionFactory就够了,只有多个数据库的时候才会使用多个SessionFactory。3、在整个应用中,Session和事务应该能够统一管理。(Spring为Hibernate提供了非常好的支持)4、将所有的集合属性配置设置为懒加载(lazy="true")。在hibernate2.x版本中,lazy默认值是"false",但hibernate3.x已经将lazy的默认改为"true"了。5、在定义关联关系时,集合首选Set,如果集合中的实体存在重复,则选择List(在定义配置文件时,可以将List定义为bag),数组的性能最差。6、在一对多的双向关联中,一般将集合的inverse属性设置为true,让集合的对方维护关联关系。例如:Group-User,由User来维护Group和User的关联关系。7、HQL子句本身大小写无关,但是其中出现的类名和属性名必须注意大小写区分。8、在非分布式架构中,不需要使用DTO来向上层传输数据。直接使用POJO的Entity就可以了。9、如果要精通Hibernate,熟练掌握关系数据库理论和SQL是前提条件。

     


    最新回复(0)