Hibernate3简单总结part1

 

Hibernate3简单总结

1. 简单概念

hibernate是位于数据层(持久层)的框架。主要用于封装对数据的操作

hibernate 作用是将面向关系型数据库的操作,转换成面向对象的操作

因此,需要有数据库与对象的映射关系,也成ORM元数据

2. 基本配置

2.1 所需jar包:

JPA包:

required包:

mysql数据库驱动包:

2.2 ORM元数据文件

文件名:   ClassName + .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">

<!—dtd约束,从hibernate核心包里的 org.hibernate 包内的hibernate-mapping-3.0.dtd拷贝 -->

       <hibernate-mapping>

       <!-- key 是配置主键的生成策略 -->

       <class name="cn.xiaoge.domain.Student" table="t_student">

              <id name="id">

                     <!-- key 是配置主键的生成策略

                            #1 increment        主键自增(先查询数据库中最大id,然后再+1

                            #2 identity            mysql中的主键自增

                            #3 sequence         oracl中的主键自增

                            #4 hilo                  hilo算法,也能实现主键自增

                            #5 native             自动匹配identity sequence hilo这三种

                            #6 uuid                 利用uuid自动生成主键

                            #7 assigned                手动设置主键

 -->

                     <generator class="native"></generator>

              </id>

             

              <property name="name" column="name"></property>

              <!-- 配置一对多 -->

              <!--

                     set元素  表示 一对多 或 多对多的关系

                     inverse属性  表示是否不维护关联关系(如果不维护关联关系,值应设置为true

                     cascade代表级联

                            #1 save-update(偶尔用)       保存及更新

                            #2 delete(不用)               删除相关的元素

                            #3 all(不用)                   save-update + delete

                            #4 delete-orphan(不用)               删除孤儿元素(如,外键为空的order会被删除)

                            #5 all-delete-orphan(不用)  相当于 all + delete-orphan

                            #6 none                              默认值  无关联

               -->

              <set name="courses" table="t_student_course">

              <!—key 是配置自己被引用作外键时的属性 -->

                     <key column="sid"></key>

              <!-- class 一定要写全类名,或者之前配置package  columnclass对应的外键名 -->

                     <many-to-many class="cn.xiaoge.domain.Course" column="cid">

</many-to-many>

              </set>

       </class>

</hibernate-mapping>

2.3 hibernate.cfg.xml配置

文件名:    hibernate.cfg.xml      (固定名)

存放位置: src目录下

基本配置:

<?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-configuration>

<session-factory>

       <!-- 配置数据库连接的基本信息(驱动名,url,用户名,密码---合称“四大天王”) -->

       <property name="hibernate.connection.driver_class">

              com.mysql.jdbc.Driver

       </property>

       <property name="hibernate.connection.url">

              jdbc:mysql:///myhibernate01

       </property>

       <property name="hibernate.connection.username">root</property>

       <property name="hibernate.connection.password">1234</property>

       <!-- 配置是否显示sql语句 -->

       <property name="show_sql">true</property>

       <!-- 是否将sql语句格式化输出 -->

       <property name="format_sql">true</property>

       <!--

              hbm2ddl.auto 表结构生成策略

              create(学习、测试)        每次启动时重新创建表结构

              create-drop(学习、测试)         每次启动时重新创建表结构,在关闭时,将表删除

              update(学习时用)           操作表时,表不存在就创建表,表存在就在原表操作

              validate         验证表,操作表时,表不存在,或表结构不符合,就抛出异常

       -->

       <property name="hbm2ddl.auto">update</property>

    <!-- 设置当前session xx 绑定(一般设置与线程绑定)  -->

       <property name="current_session_context_class">thread</property>

    <!--  设置sql语句的方言(一般选择最短的那个方言)  -->

       <property name="dialect">

              org.hibernate.dialect.MySQL5Dialect

       </property>

       <!-- 配置映射文件 -->

       <mapping resource="cn/xiaoge/domain/User.hbm.xml" />

</session-factory>

</hibernate-configuration>

3. 对象的三种状态

3.1 瞬时状态

特点:

       oid && 未与session连接(不在session缓存中)

3.2 持久化状态

特点:

       oid && session连接

3.3 游离状态

特点:

       oid && 不与session连接

注意:

id,但是数据库中没有与之相应的id。这种对象不能算作是游离状态,勉强也只能算是瞬时状态


3.4 三种状态之间的转换

Hibernate3简单总结part1_第1张图片

4. 多表查询

4.1一对多 && 多对一

一对多:(如顾客Customer与订单Order的关系)

       1)在Customer的实体类中,引用Orderset集合

              private Set<Order> orders = new HashSet<Order>();

       2)在Customer.hbm.xml映射文件中,添加set元素

<set name="orders" cascade="save-update">           

                     <key column="cid"></key>                  //表示是自己主键被引用的列名

                     <one-to-many class="cn.xiaoge.domain.Order" />  //注意,class是多的一方的全名

              </set>

多对一:

       3)在Order的实体类中,引用Customer的对象

              private Customer customer;

       4)在Order.hbm.xml的关系映射文件中,做如下配置

              <many-to-one name="customer" column="cid" class="cn.xiaoge.bean.Customer">

              </many-to-one>

4.2 多对多

多对多(如学生Student与课程Course

       1)在Student的实体类中,引用Courseset集合

              private Set<Student> students = new HashSet<Student>();

       2)在Student.hbm.xml配置关系映射

              <set name="courses" table="t_student_course">    //多对多的中间表

                     <key column="sid"></key>         //sid 是中间表引用student主键时的外键名

                     <many-to-many class="cn.xiaoge.bean.Course" column="cid">

</many-to-many>   //cid 是中间表引用Course主键时的外键名

              </set>

       3)在CourseCourse.hbm.xml中,做类似操作,注意,是类似,不是一模一样!!!

4.3 一对一

一对一关系:如公司与注册登记的公司地点

       1)在Company中引用地址的对象

                     private Address address;

       2)在Company.hbm.xml中做如下配置:

       <one-to-one name="address"  class="cn.xiaoge.bean.Address"></one-to-one>

       3)在Address的实体类中引用Company

              private Company company;

       4)在Address.hbm.xml中做如下配置:

              //方式一

              <id name="id">

                     <generator class="foreign">

                            <param name="property">company</param>

                     </generator>

              </id>

<one-to-one name="company" class="cn.xiaoge.bean.Company" constrained="true">

</one-to-one>

              //方式二

              <id name="id">

                     <generator class="native"></generator>

              </id>

              <property name="address"></property>

              <many-to-one  name="company" class="cn.xiaoge.bean.Company"

column="cid" unique="true">

</many-to-one>

5. Hibernate的检索策略(重点)

5.1 类级别检索策略

       涉及的方法: load方法

       涉及的属性: class元素上的lazy属性

              lazy : true(默认值): 延迟检索 => 不会立即发送sql查询.使用时才查询

              lazy : false : 立即检索 => 会立即发送sql查询.

       : get方法永远是立即检索.

       结论: 延迟检索用于提高效率.如果不用, 不会检索.使用时才加载.

5.2 关联级别检索策略

一对多:

涉及属性:

       fetch属性: 决定加载关联数据时使用哪种sql语句

              select(默认值): 会使用单表查询select语句加载关联数据.

              join: 会使用表链接语句加载关联数据.

              subselect:使用子查询加载关联数据

       lazy属性: 决定加载关联数据的时机

              true:         延迟加载.=> 在使用关联数据时才会加载.

              false:  立即加载.=> 无论是否使用关联数据,都会立即加载

              extra:  极其懒惰.=> 如果仅仅获得关联数据集合的size.只会发送count聚合函数查询数量.

策略配置:

       fetch(默认值) : select

       lazy(默认值) : true

       //结论: 使用关联数据时,才加载关联数据.加载时使用单表select查询.

       ---------------------------------------------------------------------

       fetch(默认值) : select

       lazy(默认值) : false

       //结论: 获得客户时,立即加载与客户关联的订单数据.使用单表select查询

       ---------------------------------------------------------------------

       fetch(默认值):select

       lazy(默认值): extra

       //结论: 加载客户时,不会加载关联的订单.打印订单数量时,

//只发送count查询数量.打印属性时,会发送单表select查询.

       ---------------------------------------------------------------------

       fetch(默认值):join

       lazy(默认值): true/false/extra

       //结论: fetch使用多表查询,一定会同时加载关联数据. 那么lazy属性失效.

       ----------------------------------------------------------------------

fetch(默认值) : subselect 子查询 =>

//查询单个客户=>相当于select

           //查询多个客户=> 加载多个客户的关联数据时,会使用子查询

       lazy(默认值): false

       //结论:  加载多个客户数据时,会立即使用子查询加载所有客户的订单数据.

       ----------------------------------------------------------------------

       fetch(默认值):subselect 子查询 => 查询单个客户=>相当于select

                                          //查询多个客户=> 加载多个客户的关联数据时,会使用子查询

       lazy(默认值): true

       //结论:  查询多个客户时,不会立即查询客户下的订单数据. 使用订单时,会使用子查询加载所有客户的订单数据

       -----------------------------------------------------------------------

       fetch(默认值):subselect 子查询 => 查询单个客户=>相当于select

       //查询多个客户=> 加载多个客户的关联数据时,会使用子查询

       lazy(默认值): extra

       //结论:  查询多个客户时,不会立即查询客户下的订单数据.打印客户的订单数量时,只会发送count查询数量. 使用订单具体属性时,会使用子查询加载所有客户的订单数据

多对一:

涉及属性:

       fetch属性: 使用什么样的sql语句查询

              select:单表select查询

              join:多表连接

             

       lazy属性:  加载策略

              false:立即加载

              proxy:我不决定加载策略.由对方类级别加载策略决定

              no-proxy: 不做研究.

测试:

       fetch(默认值):select

       lazy(默认值): false

       //结论: 查询订单时,会立即查询订单的客户.会发送多条单表查询select.

       --------------------------------------------------------------------

       fetch(默认值):select

       lazy(默认值): proxy

                     //true     

                     //false

       //结论: 查询订单时,发送多条单表查询select. 至于是否立即加载,要看Customer的类级别加载策略.

       --------------------------------------------------------------------

       // fetch(默认值):join

       // lazy(默认值): proxy/false

       //结论: 加载订单时,会使用多表查询,同时加载订单的客户数据. lazy属性失效

关联级别检索策略(一对多)

     Fetch

Lazy

select

join

subselect

true

使用关联数据时,才加载关联数据.并使用单表select查询

立即查询关联数据,多表查询,lazy属性失效

延时查询关联数据,在关联数据时,使用子查询

false

查询主对象时,立即加载关联数据,并使用单标select查询

立即查询关联数据,多表查询,lazy属性失效

立即查询关联数据,并使用子查询

extra

延时查询关联数据时, 查询关联数据数量时,只查询数量,不查询关联对象的具体信息

立即查询关联数据,夺标查询,lazy属性失效

延时查询关联数据,查询关联数据数量时,只查询数量,不查询关联对象的具体信息

关联级别检索策略(多对一)

     Fetch

Lazy

select

join

false

例如:查询订单时,立即查询订单的客户.并会发送多条单表查询select

立即查询关联数据,且是多表查询,lazy属性失效

proxy

例如:查询订单时,会依据顾客的lazy属性值。若顾客的lazy=false“,立即查询订单的客户.并会发送多条单表查询select。若顾客的lazy=true”,会延时查询顾客信息

立即查询关联数据,且是多表查询,lazy属性失效

no-proxy

不研究

不研究

5.3 Hibernate中查询方式

1. 根据OID查询.

       参考类级别检索策略。可以分为getXxx.class,oid)和loadXxx.class,oid

2.对象视图导航.

       根据对象.属性,或 对象.方法()进行查询

3.SQL查询

       类似mysql语句查询,详细信息查看mysql总结:http://my.oschina.net/xiaogezi/blog/631825

4.HQL查询

       HQLHibernate Query Language

       基本查询: Query query = session.createQuery("from Customer");

       条件查询: Query query = session.createQuery("from Customer where id = 1");

       投影查询: Query query = session.createQuery("select new Customer(c.cid,c.cname) from Customer c");

       排序: Query query = session.createQuery("from Customer order by cid desc");

       分页:

              Query query = session.createQuery("from Customer");

              // *** pageNum 当前页(之前的 pageCode

              query.setFirstResult(0);

              // * 每页显示个数 , pageSize

              query.setMaxResults(2);

       绑定参数:

              //方式1. 用索引设置参数

              Query query = session.createQuery("from Customer where cid = ?");

              query.setInteger(0, cid);

              //方式2. 用字段名设置参数

              Query query = session.createQuery("from Customer where cid = :xxx");

              query.setParameter("xxx", cid);

       聚合函数&分组:

              聚合函数:sum avg max min count

              分组: group by

       连接查询:

         内连接:

              显式内连接: session.createQuery(" from Customer c inner join c.orders ");

              隐式内连接: session.createQuery(" from Customer c, Order o where c.id = o.cid ");

              迫切内连接:session.createQuery(" from Customer c inner join fetch c.orders ");

        外连接:

              左外连接:session.createQuery(" from Customer c left outer join c.orders ");

              左外迫切连接:session.createQuery(" from Customer c left outer join fetch c.orders ");

              右外连接:session.createQuery(" from Customer c right outer join c.orders ");

              右外迫切连接:session.createQuery(" from Customer c right outer join fetch c.orders ");

连接与迫切连接的区别:

       普通外连接,是把结果封装到不同的对象中,最终得到了一个Object[]list对象

       右外迫切连接,自动把一对多中多的对象封装到一的一方,最终得到了一的一方的对象的list集合。

5.Criteria查询(了解内容)

       Criteria的离线查询

              // #1.获取离线criteria对象

              DetachedCriteria dCriteria = DetachedCriteria.forClass(Customer.class);

              //#2.拼装参数

              dCriteria.add(Restrictions.ge("id", 5));

              //#3.获取可以执行的criteria

              Criteria criteria = dCriteria.getExecutableCriteria(session);

              List<Customer> list = criteria.list();

       Criteria的普通查询:session.createCriteria(Customer.class).list();

       Criteria的条件查询:

              criteria.add(Restrictions.xxx(字段名, ));

              // 模糊查询 like;

              /*Criteria criteria = session.createCriteria(Customer.class);

              criteria.add(Restrictions.like("cname", "t%"));

              List<Customer> list = criteria.list();*/

             

              // 条件并列查询

              Criteria criteria = session.createCriteria(Customer.class);

              criteria.add(Restrictions.like("cname", "t%"));

              criteria.add(Restrictions.ge("age", 35));

              List<Customer> list = criteria.list();

       Criteria的分页查询:

Criteria criteria = session.createCriteria(Order.class);

              criteria.setFirstResult(10);       //设置索引值

              criteria.setMaxResults(10);      //设置每页显示的最大数量

       Criteria的排序:

              Criteria criteria = session.createCriteria(Customer.class);

              criteria.addOrder(org.hibernate.criterion.Order.asc("age"));     //升序

              criteria.addOrder(org.hibernate.criterion.Order.desc("age"));   //降序

              List<Customer> list = criteria.list();

你可能感兴趣的:(Hibernate)