Hibernate CURD的封装和HQL的多表查询:

本身写的一个Hibernate CURD的封装

本身在dome一个小项目的时候,突发奇想,利用单例和工厂加上泛型的知识封装Po的CURD操做,直接上代码,文笔很差,呵呵,还请你们指教 

接口规范,定义CURD操做 
Java代码 [img]http://www.javaeye.com/images/icon_copy.gif[/img]
package edu.sasu.DAO;   
  
import java.util.List;   

  
  
/**  
* 全部实体类遵循的接口  
* @author Administrator  
*  
* @param <T>  
* @param <ID>  
*/  
public interface BaseDao<T> {   
  
    /**  
     * 保存实体  
     * @param entity 实体类  
     */  
    public boolean save(T entity);   
       
    /**  
     * 删除实体  
     * @param entity 实体类  
     */  
    public boolean delete(T entity);   
       
    /**  
     * 根据实体ID删除实体  
     * @param entity 实体类  
     */  
    public boolean deleteById(T entity);   
       
    /**  
     * 跟新实体  
     * @param entity 实体类  
     */  
    //public boolean update(T entity);   
    public boolean update(T entity, Object OID);   
    /**  
     * 根据实体d,查询单个实体  
     * @param entity 实体类   
     * @return  
     */  
    //public T findById(T entity);   
    public T findById(T entity, Object entityID);   
    /**  
     * 累出全部实体集合  
     * @param entityClass 实体类  
     * @return 实体类List  
     */  
    public  List<T> findAll(String hql);   
       
    public List<T> findAll(T entity);   
       
    /**  
     * 保存和跟新方法  
     */  
    public boolean saveOrUpdate(T entity);   
}  

package edu.sasu.DAO;

import java.util.List;


/**
* 全部实体类遵循的接口
* @author Administrator
*
* @param <T>
* @param <ID>
*/
public interface BaseDao<T> {

        /**
         * 保存实体
         * @param entity 实体类
         */
        public boolean save(T entity);
        
        /**
         * 删除实体
         * @param entity 实体类
         */
        public boolean delete(T entity);
        
        /**
         * 根据实体ID删除实体
         * @param entity 实体类
         */
        public boolean deleteById(T entity);
        
        /**
         * 跟新实体
         * @param entity 实体类
         */
        //public boolean update(T entity);
        public boolean update(T entity, Object OID);
        /**
         * 根据实体d,查询单个实体
         * @param entity 实体类 
         * @return
         */
        //public T findById(T entity);
        public T findById(T entity, Object entityID);
        /**
         * 累出全部实体集合
         * @param entityClass 实体类
         * @return 实体类List
         */
        public  List<T> findAll(String hql);
        
        public List<T> findAll(T entity);
        
        /**
         * 保存和跟新方法
         */
        public boolean saveOrUpdate(T entity);
}



实现BaseDao接口,实现其中的方法 
Java代码 [img]http://www.javaeye.com/images/icon_copy.gif[/img]
package edu.sasu.DAOImpl;   
  
import java.io.Serializable;   
import java.util.ArrayList;   
import java.util.List;   
  
import org.hibernate.HibernateException;   
import org.hibernate.Session;   
import org.hibernate.Transaction;   
  
import edu.sasu.DAO.BaseDao;   
import edu.sasu.Util.DBUtil;   
/**  
* 封装的基类操做  
* @author Administrator  
*  
* @param <T>  
*/  
public class BaseDAOImpl<T>  implements BaseDao<T>{   
    public synchronized boolean delete(T entity) {   
        // TODO Auto-generated method stub   
        return false;   
    }   
    /**  
     * 删除某条数据  
     */  
    public synchronized boolean deleteById(T entity) {   
        Session session = DBUtil.getDBUtil().getSession();   
        Transaction tx = null;   
        try {   
            tx = session.beginTransaction();   
            session.delete(entity);   
            tx.commit();   
        } catch (HibernateException e) {   
            if(tx != null){   
                tx.rollback();   
            }   
            return false;   
        }   
        return true;   
    }   
  
    public synchronized List<T> findAll(T entity) {   
        // TODO Auto-generated method stub   
        return null;   
    }   
    /**  
     * 查找单个数据  
     */  
    public synchronized T findById(T entity, Object entityID) {   
        Session session = DBUtil.getDBUtil().getSession();   
        Transaction tx = null;   
        T temp;   
        try {   
            tx = session.beginTransaction();   
            temp = (T) session.get(entity.getClass(),(Serializable) entityID);   
            tx.commit();   
        } catch (HibernateException e) {   
            if(tx != null){   
                tx.rollback();   
            }   
            throw e;   
        }finally{   
               
        }   
        return temp;   
    }   
    /**  
     * 保存数据  
     */  
    public synchronized boolean save(T entity) {   
        Session session = DBUtil.getDBUtil().getSession();   
        Transaction tx = null;   
        try {   
            tx = session.beginTransaction();   
            //session.persist(entity);   
            session.save(entity);   
            tx.commit();   
        } catch (HibernateException e) {   
            if(tx != null){   
                tx.rollback();   
            }   
            //return false;   
            e.printStackTrace();   
        }   
        return true;   
    }   
    /**  
     * 跟新数据  
     */  
    public synchronized boolean update(T entity, Object OID) {   
        Session session = DBUtil.getDBUtil().getSession();   
        Transaction tx = null;   
           
        try {   
            tx = session.beginTransaction();       
            T temp = (T) session.get(entity.getClass(), (Serializable) OID);   
            session.merge(entity); //若是update要抛异常   
            tx.commit();   
        } catch (HibernateException e) {   
            if(tx != null){   
                tx.rollback();   
            }   
            //return false;   
            e.printStackTrace();   
        }   
        return true;   
    }   
    /**  
     * 查找符合hql的全部数据  
     */  
    public synchronized List<T> findAll(String hql) {   
        Session session = DBUtil.getDBUtil().getSession();   
        Transaction tx = null;   
        List<T> list = new ArrayList<T>();   
        try {   
            tx = session.beginTransaction();   
            list = session.createQuery(hql).list();   
            session.flush();   
            tx.commit();   
        } catch (HibernateException e) {   
            if(tx != null){   
                tx.rollback();   
            }   
            e.printStackTrace();   
        }   
        return list;   
    }   
       
    /**  
     * 保存和跟新方法  
     */  
    public synchronized boolean saveOrUpdate(T entity) {   
        Session session = DBUtil.getDBUtil().getSession();   
        Transaction tx = null;   
        try {   
            tx = session.beginTransaction();   
            session.saveOrUpdate(entity);   
            tx.commit();   
        } catch (HibernateException e) {   
            if(tx != null){   
                tx.rollback();   
            }   
            //return false;   
            e.printStackTrace();   
        }   
        return true;   
    }   
}  

package edu.sasu.DAOImpl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import edu.sasu.DAO.BaseDao;
import edu.sasu.Util.DBUtil;
/**
* 封装的基类操做
* @author Administrator
*
* @param <T>
*/
public class BaseDAOImpl<T>  implements BaseDao<T>{
        public synchronized boolean delete(T entity) {
                // TODO Auto-generated method stub
                return false;
        }
    /**
     * 删除某条数据
     */
        public synchronized boolean deleteById(T entity) {
                Session session = DBUtil.getDBUtil().getSession();
                Transaction tx = null;
                try {
                        tx = session.beginTransaction();
                        session.delete(entity);
                        tx.commit();
                } catch (HibernateException e) {
                        if(tx != null){
                                tx.rollback();
                        }
                        return false;
                }
                return true;
        }

        public synchronized List<T> findAll(T entity) {
                // TODO Auto-generated method stub
                return null;
        }
    /**
     * 查找单个数据
     */
        public synchronized T findById(T entity, Object entityID) {
                Session session = DBUtil.getDBUtil().getSession();
                Transaction tx = null;
                T temp;
                try {
                        tx = session.beginTransaction();
                        temp = (T) session.get(entity.getClass(),(Serializable) entityID);
                        tx.commit();
                } catch (HibernateException e) {
                        if(tx != null){
                                tx.rollback();
                        }
                        throw e;
                }finally{
                        
                }
                return temp;
        }
    /**
     * 保存数据
     */
        public synchronized boolean save(T entity) {
                Session session = DBUtil.getDBUtil().getSession();
                Transaction tx = null;
                try {
                        tx = session.beginTransaction();
                        //session.persist(entity);
                        session.save(entity);
                        tx.commit();
                } catch (HibernateException e) {
                        if(tx != null){
                                tx.rollback();
                        }
                        //return false;
                        e.printStackTrace();
                }
                return true;
        }
    /**
     * 跟新数据
     */
        public synchronized boolean update(T entity, Object OID) {
                Session session = DBUtil.getDBUtil().getSession();
                Transaction tx = null;
                
                try {
                        tx = session.beginTransaction();        
                        T temp = (T) session.get(entity.getClass(), (Serializable) OID);
                        session.merge(entity); //若是update要抛异常
                        tx.commit();
                } catch (HibernateException e) {
                        if(tx != null){
                                tx.rollback();
                        }
                        //return false;
                        e.printStackTrace();
                }
                return true;
        }
    /**
     * 查找符合hql的全部数据
     */
        public synchronized List<T> findAll(String hql) {
                Session session = DBUtil.getDBUtil().getSession();
                Transaction tx = null;
                List<T> list = new ArrayList<T>();
                try {
                        tx = session.beginTransaction();
                        list = session.createQuery(hql).list();
                        session.flush();
                        tx.commit();
                } catch (HibernateException e) {
                        if(tx != null){
                                tx.rollback();
                        }
                        e.printStackTrace();
                }
                return list;
        }
        
        /**
         * 保存和跟新方法
         */
        public synchronized boolean saveOrUpdate(T entity) {
                Session session = DBUtil.getDBUtil().getSession();
                Transaction tx = null;
                try {
                        tx = session.beginTransaction();
                        session.saveOrUpdate(entity);
                        tx.commit();
                } catch (HibernateException e) {
                        if(tx != null){
                                tx.rollback();
                        }
                        //return false;
                        e.printStackTrace();
                }
                return true;
        }
}


基础工厂采用单例实现获取实例操做对象 
Java代码 [img]http://www.javaeye.com/images/icon_copy.gif[/img]
package edu.sasu.factory;   
  
import edu.sasu.DAO.BaseDao;   
import edu.sasu.DAOImpl.BaseDAOImpl;   
/**  
* 基础工厂  
* @author Administrator  
*  
* @param <T>  
*/  
public class BaseFactory<T> {   
       
    private static BaseFactory baseFactory; //单一实例   
    private BaseDao<T> Instance;   
    private BaseFactory(){   
        Instance = new BaseDAOImpl<T>();     
    }   
       
    public BaseDao<T> getInstance(){ //不要把factory的new放在构造函数里面,否则会出现递归错误   
        return Instance;   
    }   
       
    public static BaseFactory getFactory(){   
        if(baseFactory == null){   
            baseFactory = new BaseFactory();   
        }   
        return baseFactory;   
    }   
}  

package edu.sasu.factory;

import edu.sasu.DAO.BaseDao;
import edu.sasu.DAOImpl.BaseDAOImpl;
/**
* 基础工厂
* @author Administrator
*
* @param <T>
*/
public class BaseFactory<T> {
        
        private static BaseFactory baseFactory; //单一实例
        private BaseDao<T> Instance;
        private BaseFactory(){
                Instance = new BaseDAOImpl<T>();        
        }
        
        public BaseDao<T> getInstance(){ //不要把factory的new放在构造函数里面,否则会出现递归错误
                return Instance;
        }
        
        public static BaseFactory getFactory(){
                if(baseFactory == null){
                        baseFactory = new BaseFactory();
                }
                return baseFactory;
        }
}

以上定义baseDAO接口,baeDAOIMpl是接口的实现,baseFactory是工厂,对baseDAOimp实例化, 
在类中调用为: User(一个PoJo类) 
User entity= new User(); 
BaseFactory<User> factory = BaseFactory.getFactory(); 
执行保存操做: factory.getInstance().save(entity);  entity User的实例对象 
执行保存操做,请你们评点下此种写法有什么很差的地方,本人能力有限,以为还能够,请大牛指教
humour 发表于 2011-3-24 15:59

0 0 请登陆后投票

superobin 等级: 初级会员 
[img]http://www.javaeye.com/images/user-logo.gif?1299226978[/img] 
性别:  [img]http://www.javaeye.com/images/icon_minigender_1.gif[/img]


 /根据主键查询


public Object findRel(Class desClass, int creatorId) {
Session session = null;
Object obj = null;
try {
session = HibernateUtil.getSession();
obj = session.get(desClass, new Integer(creatorId));
} catch (HibernateException e) {
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
return obj;
}


Hibernate条件查询(Criteria Query)

 
一、建立一个Criteria实例
net.sf.hibernate.Criteria这个接口表明对一个特定的持久化类的查询。Session是用来制造Criteria实例的工厂。 

Criteria crit = sess.createCriteria(Cat.class);//建立实力类能够为OBJECT.CLASS
crit.setMaxResults(50);
List cats = crit.list();

返回最多50条记录的结果集。

二、缩小结果集范围
一个查询条件(Criterion)是net.sf.hibernate.expression.Criterion接口的一个实例。类net.sf.hibernate.expression.Expression定义了得到一些内置的Criterion类型。 


import org.hibernate.criterion.Projections;//两个查询条件类
import org.hibernate.criterion.Expression;

List cats = sess.createCriteria(Cat.class)
    .add( Expression.like("name", "Fritz%") )
    .add( Expression.between("weight", minWeight, maxWeight) )
    .list();
表达式(Expressions)能够按照逻辑分组. 

List cats = sess.createCriteria(Cat.class)
    .add( Expression.like("name", "Fritz%") )
    .add( Expression.or(
     Expression.eq( "age", new Integer(0) ),
     Expression.isNull("age")
    ) )
    .list();

返回(name like "Fritz%" and age 等于0 或者 age 为空)的结果集


List cats = sess.createCriteria(Cat.class)
    .add( Expression.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
    .add( Expression.disjunction()
        .add( Expression.isNull("age") )
     .add( Expression.eq("age", new Integer(0) ) )
     .add( Expression.eq("age", new Integer(1) ) )
     .add( Expression.eq("age", new Integer(2) ) )
    ) )
    .list();

Expression.disjunction()----意思是能够按照逻辑分组
有不少预制的条件类型(Expression的子类)。有一个特别有用,可让你直接嵌入SQL。 

List cats = sess.createCriteria(Cat.class)
    .add( Expression.sql("lower($alias.name) like lower(?)", "Fritz%", Hibernate.STRING) )
    .list();
其中的{alias}是一个占位符,它将会被所查询实体的行别名所替代。(原文:The {alias} placeholder with be replaced by the row alias of the queried entity.) 

三、对结果排序
可使用net.sf.hibernate.expression.Order对结果集排序. 

List cats = sess.createCriteria(Cat.class)
    .add( Expression.like("name", "F%")
    .addOrder( Order.asc("name") )
    .addOrder( Order.desc("age") )
    .setMaxResults(50)
    .list();
四、关联(Associations)
你能够在关联之间使用createCriteria(),很容易地在存在关系的实体之间指定约束。 

List cats = sess.createCriteria(Cat.class)
    .add( Expression.like("name", "F%")
    .createCriteria("kittens")
        .add( Expression.like("name", "F%")
    .list();
注意,第二个createCriteria()返回一个Criteria的新实例,指向kittens集合类的元素。 

下面的替代形式在特定状况下有用。 

List cats = sess.createCriteria(Cat.class)
    .createAlias("kittens", "kt")
    .createAlias("mate", "mt")
    .add( Expression.eqProperty("kt.name", "mt.name") )
    .list();
(createAlias())并不会建立一个Criteria的新实例。) 

请注意,前面两个查询中Cat实例所持有的kittens集合类并无经过criteria预先过滤!若是你但愿只返回知足条件的kittens,你必须使用returnMaps()。 

List cats = sess.createCriteria(Cat.class)
    .createCriteria("kittens", "kt")
        .add( Expression.eq("name", "F%") )
    .returnMaps()
    .list();
Iterator iter = cats.iterator();
while ( iter.hasNext() ) {
    Map map = (Map) iter.next();
    Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
    Cat kitten = (Cat) map.get("kt");
}
五、动态关联对象获取(Dynamic association fetching)
能够在运行时经过setFetchMode()来改变关联对象自动获取的策略。 

List cats = sess.createCriteria(Cat.class)
    .add( Expression.like("name", "Fritz%") )
    .setFetchMode("mate", FetchMode.EAGER)
    .list();
这个查询会经过外链接(outer join)同时得到 mate和kittens。 

六、根据示例查询(Example queries)
net.sf.hibernate.expression.Example类容许你从指定的实例创造查询条件。 

Cat cat = new Cat();
cat.setSex('F');
cat.setColor(Color.BLACK);
List results = session.createCriteria(Cat.class)
    .add( Example.create(cat) )
    .list();
版本属性,表示符属性和关联都会被忽略。默认状况下,null值的属性也被排除在外。 

You can adjust how the Example is applied. 你能够调整示例(Example)如何应用。 

Example example = Example.create(cat)
    .excludeZeroes()           //exclude zero valued properties
    .excludeProperty("color")  //exclude the property named "color"
    .ignoreCase()              //perform case insensitive string comparisons
    .enableLike();             //use like for string comparisons
List results = session.createCriteria(Cat.class)
    .add(example)
    .list();
你甚至能够用示例对关联对象创建criteria。 

List results = session.createCriteria(Cat.class)
    .add( Example.create(cat) )
    .createCriteria("mate")
        .add( Example.create( cat.getMate() ) )
    .list();









 
HQL的多表查询:
对象之间老是有各类各样的关系,关联关系是类之间最多见的关系。多表查询是HQL中的强大功能之一,
包括内链接、左链接和右链接等。多表查询的设置及运行都比较麻烦,在运行本节中的示例时,
务必保证每一步都没有错误。
一:表之间的关联关系:
在数据库joblog中用到了3个表:student(学生表)、course(课程表)和sc(选课表)。在现实模型中,
一个学生能够选择多门课程,一个课程能够被多个学生选择,student和course是多对多的关联关系。
为了便于演示HQL的多表查询,本节中假设student和course之间是单向关联关系。
在多对多的关联关系中,通常来讲有个中间表,这个表描述了多对多关系,这就是选课表sc,
sc每一行数据表明一个学生的选课和成绩。
各个表的主键、外键设置以下。
student表的主键是id字段。
course表的主键是id字段。
sc表的主键是id字段。
sc表中的Sno字段是student表id字段的外键。
sc表中的Cno字段是course表id字段的外键。
在MySQL Query Browser中设置好上述关系。若是此处设置不正确,可能会影响多表链接查询.
其中sc表的建表信息以下(其中包含了外键关系)。
CREATE TABLE 'joblog'. 'sc' (
'id' int(10) unsigned NOT NULL auto_increment COMMENT 'id',
'Sno' int(10) unsigned NOT NULL default '0' COMMENT '学号',
'Cno' int(10) unsigned NOT NULL default '0' COMMENT '课程号',
'Grade' int(10) unsigned default NULL COMMENT '成绩',
PRIMARY KEY ('id'),
KEY 'FK_sc_1' ('Sno'),
KEY 'FK_sc_2' ('Cno'),
CONSTRAINT 'FK_sc_1' FOREIGN KEY ('Sno') REFERENCES 'student' ('id'), /* 外键信息 */
CONSTRAINT 'FK_sc_2' FOREIGN KEY ('Cno') REFERENCES 'course' ('id')   /* 外键信息 */
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
二:表中的数据:
这一节中用到了3个表的数据
三:修改持久化类:
Student对象和Course对象之间是多对多的关系。此处使用的是单向关联,仅仅创建从Student到Course的单向关联。
仅有Student到Course的单向关联。
为了创建Student到Course的单向关联关系,在Student.java中新加一个属性course。course属性是Set型的,
能够在这个属性中加入多个Course对象,创建起关联关系。下面是加入course属性后的源代码,粗体部分为加入的代码。
package hibernate.ch06;
import java.util.HashSet;
import java.util.Set;
public class Student implements java.io.Serializable {
        private Integer id;            //ID
        private Integer sno;           //学号
        private String sname;          //姓名
        private String ssex;           //性别
        private String sdept;          //系部
        private Integer sage;          //年龄
        private String saddress;     //住址
       private Set course=new HashSet();    //所选课程
       public Student() {
}
//此处省略其余的构造方法

//此处省略getter/setter访问器
//course属性的get访问器
   public Set getCourse() {
        return course;
   }
   //course属性的set访问器
   public void setCourse(Set course) {
          this.course = course;
   }
}
持久化类Course.java和SC.java无需修改
 
在映射文件中加入关联信息:
在Student.hbm.xml映射配置文件中,加入Student到Course的映射信息。具体代码以下。
        <set name="course" table="sc" lazy="false" cascade="save-update">
         <key column="sno" />
         <many-to-many class="hibernate.ch06.Course" column="cno" />
        </set>
说明以下。
     <set>元素是和<class>元素平行的元素。<set>元素代表将要映射的字段对应着一个集合。<set>元素包含多个属性,
其中:name属性用于设置映射的持久化类的属性名称,在本例中为Student表的course属性;table属性表示
多对多关联关系的中间表名称,此处为sc表;cascade表示当保存或者更新Student实例时,是否保存或更新Course对象。
     <set>元素的子元素<key column="sno" />设定与student表关联的中间表sc的外键sno。
     <set>元素的子元素<many-to-many>用于设定多对多关系。在该元素中,class属性用于设定多对多关系中,
与Student类关联的类Course类;column属性设定中间表与course表链接的外键cno。
完整的配置文件Student.hbm.xml以下所示。
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
      <class name="hibernate.ch06.Student" table="student" catalog="joblog">
           <id name="id" type="integer">
                 <column name="id" />
                 <generator class="identity"></generator>
           </id>
           <!--映射学号-->
           <property name="sno" type="integer">
                 <column name="Sno" not-null="true" />
           </property>
           <!--映射姓名-->
           <property name="sname" type="string">
                <column name="Sname" length="45" />
           </property>
           <!--映射系部-->
           <property name="sdept" type="string">
                <column name="Sdept" length="10" />
           </property>
         <!--映射年龄-->
           <property name="sage" type="integer">
                <column name="Sage" />
           </property>
           <!--映射性别-->
           <property name="ssex" type="string">
                <column name="Ssex" length="2" />
           </property>
           <!--映射住址-->
           <property name="saddress" type="string">
                <column name="Saddress" length="45" />
           </property>
          <!--联接-->
           <set name="course" table="sc" lazy="false" cascade="save-update">
               <key column="sno" />
               <many-to-many class="hibernate.ch06.Course" column="cno" />    <!--多对多-->
           </set>
       </class>
</hibernate-mapping>
五:左外链接:
左外链接(Left Outer Join)查询出左表对应的复合条件的全部记录,如查询张三同窗的选课信息。
下面是类HQLLeftOuterJoinQuery的源代码。
package hibernate.ch06;
import hibernate.HibernateSessionFactory;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
public class HQLLeftOuterJoinQuery {
       public static void main(String[] args) {
             Session session=HibernateSessionFactory.currentSession();
            //HQL查询语句
            String hql="from Student s left join s.course c where s.sname='张三'";
             Query query=session.createQuery(hql);         //建立查询
             List list=query.list();                          //执行查询
             Iterator it=list.iterator();
             while(it.hasNext()){
                   Object[] obj=(Object[])it.next();
                   Student stu=(Student)obj[0];
                   Course course=(Course)obj[1];
                  System.out.println("*********学生信息及其选课信息******************");
                   if(course!=null){
                    System.out.println(stu.getSno() "\t" stu.getSname() "\t" 
                                "课程:" course.getCname());
                    }else{
                          System.out.println(stu.getSno() "\t" stu.getSname() "\t");
                    };
             }
       }
}
若是只用单表查询,只能从student表中查询出张三的我的信息,而没法知道她的选课信息,由于选课信息存储在中间表sc中。
HQL语句from Student s left join s.course c where s.sname='张山'检索出了长三的选课信息。
     在HQL中使用left outer join关键字进行左外链接,outer关键字能够省略。
     s.course是Student对象中的一个属性,用来存储Student对象的选课信息。在执行查询时,将根据Student.hbm.xml中的
配置生成SQL语句,并检索信息。
     查询的结果返回一个Object[]数组,数组的第0个元素是Student对象,第1个元素是与Object[0]中对应的学生所选课的Course对象。
HQLLeftOuterJoinQuery类在执行过程当中生成的左外链接的SQL语句以下。
Hibernate:
    select
          student0_.id as id1_0_,
          course2_.id as id4_1_,
          student0_.Sno as Sno1_0_,
          student0_.Sname as Sname1_0_,
          student0_.Sdept as Sdept1_0_,
          student0_.Sage as Sage1_0_,
         student0_.Ssex as Ssex1_0_,
         student0_.Saddress as Saddress1_0_,
          course2_.Cno as Cno4_1_,
          course2_.Cname as Cname4_1_,
          course2_.Ccredit as Ccredit4_1_
    from
          joblog.student student0_
    left outer join
        sc course1_
               on student0_.id=course1_.sno
   left outer join
        joblog.course course2_
               on course1_.cno=course2_.id
   where
        student0_.Sname='张三'
Hibernate:
    select
          course0_.sno as sno1_,
          course0_.cno as cno1_,
          course1_.id as id4_0_,
          course1_.Cno as Cno4_0_,
          course1_.Cname as Cname4_0_,
          course1_.Ccredit as Ccredit4_0_
    from
          sc course0_
left outer join
        joblog.course course1_
                on course0_.cno=course1_.id
    where
        course0_.sno=?
使用以下语句将只返回Student对象。
select s from Student s left join s.course c where s.sname='张三'
以下是只返回Student对象的部分代码。
        Session session=HibernateSessionFactory.currentSession();      
       //HQL查询语句
        String hql="select s from Student s left join s.course c where s.sname='张三'";
        Query query=session.createQuery(hql);       //建立查询       
        List list=query.list();          //执行查询    
        Iterator it=list.iterator();       
        while(it.hasNext()){
               Student stu=(Student)it.next();
              System.out.println("*********学生信息及其选课信息******************");
               System.out.println(stu.getSno() "\t" stu.getSname() "\t");
        }
六:左外抓取链接:
左外抓取链接指定在Hibernate检索数据时,采用抓取的方式,直接将数据加载到与Student对象关联的course属性中。
下面是左外抓取链接的程序。
        //HQL查询语句
        String hql="select s from Student s left join fetch s.course c where s.sname='张三'";
        Query query=session.createQuery(hql);      //建立查询       
        List list=query.list();         //执行查询       
        Iterator it=list.iterator();
        while(it.hasNext()){
                Student stu=(Student)it.next();
               System.out.println("*********学生信息及其选课信息******************");
               System.out.println(stu.getSno() "\t" stu.getSname() "\t");
        }
     左外抓取链接使用left join fetch关键字。
与左外链接不一样的是:左外抓取链接query.list()返回的集合中存放Student对象的引用,
与之相关联的选课信息存放在course属性中。
七:右外链接:
HQL中使用关键字right outer join右外链接,outer关键字能够省略。右外链接与左外链接相似,再也不赘述。
八:内链接:
内链接(Inner Join)是指两个表中指定的关键字相等的值才会出如今结果集中的一种查询方式。
HQL中使用关键字inner join进行内链接,下面是使用内链接的程序。
        Session session=HibernateSessionFactory.currentSession()    //建立Session      
        String hql="from Student s inner join s.course c";        //HQL查询语句
        Query query=session.createQuery(hql);     //建立查询
        List list=query.list();        //执行查询       
        Iterator it=list.iterator();            
        while(it.hasNext()){
                Object[] obj=(Object[])it.next();
                Student stu=(Student)obj[0];
                Course course=(Course)obj[1];
               System.out.println("*********学生信息及其选课信息******************");
                System.out.println(stu.getSno() "\t" stu.getSname() "\t" "课程:" course. getCname());
        }
     HQL中使用inner join进行内链接,内链接只关联并检索那些选了课的学生信息及其选课信息,没有选课的学生不在检索结果中。
     可使用select s from Student s inner join s.course c只返回Student对象。
九: 抓取内链接:
抓取内链接与内链接不一样之处在于其对象的内存状态不同。HQL中使用inner join fetch进行抓取内链接,以下程序所示。
        Session session=HibernateSessionFactory.currentSession();     //建立Session      
        String hql="select s from Student s inner join fetch s.course c";       //HQL语句
        Query query=session.createQuery(hql);       //建立查询       
        List list=query.list();    //执行查询       
        Iterator it=list.iterator();      
        while(it.hasNext()){
        Student stu=(Student)it.next();
        System.out.println("*********学生信息及其选课信息******************");
        System.out.println(stu.getSno() "\t" stu.getSname() "\t");
    }
     内抓取链接使用inner join fech关键字。
     它与内链接的区别是返回检索的list中存放的是Student对象的引用,与之相关联的选课信息存放在course属性中
相关文章
相关标签/搜索