Hibernate的凝乳的封装和的HQL的多表查询:

自己写的一个Hibernate的凝乳的封装

自己在dome一个小项目的时候,突发奇想,利用单例和工厂加上泛型的知识封装Po的CURD操作,直接上代码,文笔不好,呵呵,还请大家指教 

接口规范,定义凝乳操作 
Java的代码[IMG] http://www.javaeye.com/images/icon_copy.gif [/ IMG]
包edu.sasu.DAO;   
  
进口的java.util.List;   

  
  
/ **  
*所有实体类遵循的接口  
* @作者管理员  
*  
* @参数<T>  
* _AT_参数<ID>  
* /  
公共接口BaseDao <T> {   
  
    / **  
     *保存实体  
     * @参数实体的实体类  
     * /  
    公共布尔保存(操实体);   
       
    / **  
     *删除实体  
     * @参数实体的实体类  
     * /  
    公共布尔删除(操实体);   
       
    / **  
     *根据实体的ID删除实体  
     * @参数实体的实体类  
     * /  
    公共布尔deleteById(操实体);   
       
    / **  
     *跟新实体  
     * @参数实体的实体类  
     * /  
    / /公共布尔更新(操实体);   
    公共布尔更新(操实体,对象的OID);   
    / **  
     *根据实体D,查询单个实体  
     * @参数实体的实体类   
     * @返回  
     * /  
    / /公共ţfindById(操实体);   
    (操实体,对象entityID),公共ţfindById;   
    / **  
     *累出所有实体集合  
     * @的参数entityClass实体类  
     * @返回实体类名单  
     * /  
    公共的名单<T>的findAll(弦乐HQL);   
       
    公共的名单<T>的findAll(操实体);   
       
    / **  
     *保存和跟新方法  
     * /  
    公共布尔saveOrUpdate(操实体);   
}  

包edu.sasu.DAO;

进口的java.util.List;


/ **
*所有实体类遵循的接口
* @作者管理员
*
* @参数<T>
* _AT_参数<ID>
* /
公共接口BaseDao <T> {

        / **
         *保存实体
         * @参数实体的实体类
         * /
        公共布尔保存(操实体);
        
        / **
         *删除实体
         * @参数实体的实体类
         * /
        公共布尔删除(操实体);
        
        / **
         *根据实体的ID删除实体
         * @参数实体的实体类
         * /
        公共布尔deleteById(操实体);
        
        / **
         *跟新实体
         * @参数实体的实体类
         * /
        / /公共布尔更新(操实体);
        公共布尔更新(操实体,对象的OID);
        / **
         *根据实体D,查询单个实体
         * @参数实体的实体类 
         * @返回
         * /
        / /公共ţfindById(操实体);
        (操实体,对象entityID),公共ţfindById;
        / **
         *累出所有实体集合
         * @的参数entityClass实体类
         * @返回实体类名单
         * /
        公共的名单<T>的findAll(弦乐HQL);
        
        公共的名单<T>的findAll(操实体);
        
        / **
         *保存和跟新方法
         * /
        公共布尔saveOrUpdate(操实体);
}



实现BaseDao接口,实现其中的方法 
Java的代码[IMG] http://www.javaeye.com/images/icon_copy.gif [/ IMG]
包edu.sasu.DAOImpl;   
  
进口了java.io.Serializable;   
进口的java.util.ArrayList;   
进口的java.util.List;   
  
进口持久性单元对话框;   
导入org.hibernate.Session;   
导入org.hibernate.Transaction;   
  
导入edu.sasu.DAO.BaseDao;   
导入edu.sasu.Util.DBUtil;   
/ **  
*封装的基类操作  
* @作者管理员  
*  
* @参数<T>  
* /  
公共类BaseDAOImpl <T>实现BaseDao <T> {   
    市民同步布尔删除(操实体){   
        / / TODO自动生成方法存根   
        返回false;   
    }   
    / **  
     *删除某条数据  
     * /  
    市民同步布尔deleteById(操实体){   
        届会议DBUtil.getDBUtil()getSession();   
        交易TX = NULL;   
        尝试{   
            TX = session.beginTransaction();   
            使用Session.delete(实体);   
            tx.commit();   
        }赶上(HibernateException的E){   
            (TX = NULL){   
                tx.rollback();   
            }   
            返回false;   
        }   
        返回true;   
    }   
  
    市民同步列表<T>的findAll(操实体){   
        / / TODO自动生成方法存根   
        返回null;   
    }   
    / **  
     *查找单个数据  
     * /  
    市民同步ţfindById(操实体,对象entityID),{   
        届会议DBUtil.getDBUtil()getSession();   
        交易TX = NULL;   
        ţ温度;   
        尝试{   
            TX = session.beginTransaction();   
            TEMP =(T)的session.get(entity.getClass(),(序列化)entityID);   
            tx.commit();   
        }赶上(HibernateException的E){   
            (TX = NULL){   
                tx.rollback();   
            }   
            投射E;   
        }最后{   
               
        }   
        返回温度;   
    }   
    / **  
     *保存数据  
     * /  
    市民同步布尔保存(操实体){   
        届会议DBUtil.getDBUtil()getSession();   
        交易TX = NULL;   
        尝试{   
            TX = session.beginTransaction();   
            / / session.persist(实体);   
            的session.save(实体);   
            tx.commit();   
        }赶上(HibernateException的E){   
            (TX = NULL){   
                tx.rollback();   
            }   
            / /返回false;   
            论坛主题贴();   
        }   
        返回true;   
    }   
    / **  
     *跟新数据  
     * /  
    市民同步布尔更新(操实体,对象的OID){   
        届会议DBUtil.getDBUtil()getSession();   
        交易TX = NULL;   
           
        尝试{   
            TX = session.beginTransaction();       
            ţTEMP =(T)的session.get(entity.getClass(),(序列化)的OID);   
            session.merge(实体)/ /如果更新要抛异常;   
            tx.commit();   
        }赶上(HibernateException的E){   
            (TX = NULL){   
                tx.rollback();   
            }   
            / /返回false;   
            论坛主题贴();   
        }   
        返回true;   
    }   
    / **  
     *查找符合HQL的所有数据  
     * /  
    市民同步列表<T>的findAll(弦乐HQL){   
        届会议DBUtil.getDBUtil()getSession();   
        交易TX = NULL;   
        名单<T>列表=新的ArrayList <T>();   
        尝试{   
            TX = session.beginTransaction();   
            列表= session.createQuery(HQL)名单();   
            session.flush();   
            tx.commit();   
        }赶上(HibernateException的E){   
            (TX = NULL){   
                tx.rollback();   
            }   
            论坛主题贴();   
        }   
        返回列表;   
    }   
       
    / **  
     *保存和跟新方法  
     * /  
    市民同步布尔saveOrUpdate(操实体){   
        届会议DBUtil.getDBUtil()getSession();   
        交易TX = NULL;   
        尝试{   
            TX = session.beginTransaction();   
            session.saveOrUpdate(实体);   
            tx.commit();   
        }赶上(HibernateException的E){   
            (TX = NULL){   
                tx.rollback();   
            }   
            / /返回false;   
            论坛主题贴();   
        }   
        返回true;   
    }   
}  

包edu.sasu.DAOImpl;

进口了java.io.Serializable;
进口的java.util.ArrayList;
进口的java.util.List;

进口持久性单元对话框;
导入org.hibernate.Session;
导入org.hibernate.Transaction;

导入edu.sasu.DAO.BaseDao;
导入edu.sasu.Util.DBUtil;
/ **
*封装的基类操作
* @作者管理员
*
* @参数<T>
* /
公共类BaseDAOImpl <T>实现BaseDao <T> {
        市民同步布尔删除(操实体){
                / / TODO自动生成方法存根
                返回false;
        }
    / **
     *删除某条数据
     * /
        市民同步布尔deleteById(操实体){
                届会议DBUtil.getDBUtil()getSession();
                交易TX = NULL;
                尝试{
                        TX = session.beginTransaction();
                        使用Session.delete(实体);
                        tx.commit();
                }赶上(HibernateException的E){
                        (TX = NULL){
                                tx.rollback();
                        }
                        返回false;
                }
                返回true;
        }

        市民同步列表<T>的findAll(操实体){
                / / TODO自动生成方法存根
                返回null;
        }
    / **
     *查找单个数据
     * /
        市民同步ţfindById(操实体,对象entityID),{
                届会议DBUtil.getDBUtil()getSession();
                交易TX = NULL;
                ţ温度;
                尝试{
                        TX = session.beginTransaction();
                        TEMP =(T)的session.get(entity.getClass(),(序列化)entityID);
                        tx.commit();
                }赶上(HibernateException的E){
                        (TX = NULL){
                                tx.rollback();
                        }
                        投射E;
                }最后{
                        
                }
                返回温度;
        }
    / **
     *保存数据
     * /
        市民同步布尔保存(操实体){
                届会议DBUtil.getDBUtil()getSession();
                交易TX = NULL;
                尝试{
                        TX = session.beginTransaction();
                        / / session.persist(实体);
                        的session.save(实体);
                        tx.commit();
                }赶上(HibernateException的E){
                        (TX = NULL){
                                tx.rollback();
                        }
                        / /返回false;
                        论坛主题贴();
                }
                返回true;
        }
    / **
     *跟新数据
     * /
        市民同步布尔更新(操实体,对象的OID){
                届会议DBUtil.getDBUtil()getSession();
                交易TX = NULL;
                
                尝试{
                        TX = session.beginTransaction();        
                        ţTEMP =(T)的session.get(entity.getClass(),(序列化)的OID);
                        session.merge(实体)/ /如果更新要抛异常;
                        tx.commit();
                }赶上(HibernateException的E){
                        (TX = NULL){
                                tx.rollback();
                        }
                        / /返回false;
                        论坛主题贴();
                }
                返回true;
        }
    / **
     *查找符合HQL的所有数据
     * /
        市民同步列表<T>的findAll(弦乐HQL){
                届会议DBUtil.getDBUtil()getSession();
                交易TX = NULL;
                名单<T>列表=新的ArrayList <T>();
                尝试{
                        TX = session.beginTransaction();
                        列表= session.createQuery(HQL)名单();
                        session.flush();
                        tx.commit();
                }赶上(HibernateException的E){
                        (TX = NULL){
                                tx.rollback();
                        }
                        论坛主题贴();
                }
                返回列表;
        }
        
        / **
         *保存和跟新方法
         * /
        市民同步布尔saveOrUpdate(操实体){
                届会议DBUtil.getDBUtil()getSession();
                交易TX = NULL;
                尝试{
                        TX = session.beginTransaction();
                        session.saveOrUpdate(实体);
                        tx.commit();
                }赶上(HibernateException的E){
                        (TX = NULL){
                                tx.rollback();
                        }
                        / /返回false;
                        论坛主题贴();
                }
                返回true;
        }
}


基础工厂采用单例实现获取实例操作对象 
Java的代码[IMG] http://www.javaeye.com/images/icon_copy.gif [/ IMG]
包edu.sasu.factory;   
  
导入edu.sasu.DAO.BaseDao;   
导入edu.sasu.DAOImpl.BaseDAOImpl;   
/ **  
*基础工厂  
* @作者管理员  
*  
* @参数<T>  
* /  
公共类BaseFactory <T> {   
       
    私有静态BaseFactory baseFactory; / /单一实例   
    私人BaseDao <T>讼;   
    的私人BaseFactory(){   
        实例=,新BaseDAOImpl <T>();     
    }   
       
    公共BaseDao <T>的getInstance(){/ /不要把工厂的新放在构造函数里面,不然会出现递归错误   
        返回实例;   
    }   
       
    公共静态BaseFactory getFactory(){   
        (baseFactory == NULL){   
            baseFactory =新BaseFactory();   
        }   
        返回baseFactory;   
    }   
}  

包edu.sasu.factory;

导入edu.sasu.DAO.BaseDao;
导入edu.sasu.DAOImpl.BaseDAOImpl;
/ **
*基础工厂
* @作者管理员
*
* @参数<T>
* /
公共类BaseFactory <T> {
        
        私有静态BaseFactory baseFactory; / /单一实例
        私人BaseDao <T>讼;
        的私人BaseFactory(){
                实例=,新BaseDAOImpl <T>();        
        }
        
        公共BaseDao <T>的getInstance(){/ /不要把工厂的新放在构造函数里面,不然会出现递归错误
                返回实例;
        }
        
        公共静态BaseFactory getFactory(){
                (baseFactory == NULL){
                        baseFactory =新BaseFactory();
                }
                返回baseFactory;
        }
}

以上定义baseDAO接口,baeDAOIMpl什么接口的实现,baseFactory是工厂,对baseDAOimp实例化, 
在类中调用为:用户(一个POJO类) 
用户实体=新用户(); 
BaseFactory <USER>工厂BaseFactory.getFactory(); 
执行保存操作。factory.getInstance()保存(实体);实体用户的实例对象 
执行保存操作,请大家评点下此种写法有什么不好的地方,本人能力有限,觉得还可以,请大牛指教
幽默发表于2011年3月24日15时59

0 0请登录后投票

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


 /根据主键查询


公共的对象findRel(类desClass,INT创建者标识){
会话的会话= NULL;
对象obj = NULL;
尝试{
会议= HibernateUtil.getSession();
OBJ = session.get(desClass,新的整数(创建者标识));
}赶上(HibernateException的E){
论坛主题贴();
}最后{
HibernateUtil.closeSession(会议);
}
返回obj的;
}


Hibernate的条件查询(标准查询)

 
1,创建一个标准实例
net.sf.hibernate.Criteria这个接口代表对一个特定的持久化类的查询。Session是用来制造Criteria实例的工厂。 

标准的暴击= sess.createCriteria(Cat.class);/ /建立实力类可以为OBJECT.CLASS
crit.setMaxResults(50);
名单猫= crit.list();

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

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


进口org.hibernate.criterion.Projections ;/ /两个查询条件类
导入org.hibernate.criterion.Expression;

名单猫= sess.createCriteria(Cat.class)
    新增(Expression.like(“名称”,“弗里茨%”))
    。附加(Expression.between(“重量”,minWeight,maxWeight))
    名单();
表达式(表达式)可以按照逻辑分组。 

名单猫= sess.createCriteria(Cat.class)
    新增(Expression.like(“名称”,“弗里茨%”))
    新增(Expression.or(
     expression.eq(“年龄”,新的整数(0)),
     Expression.isNull(“时代”)
    ))
    名单();

返回(名称如“弗里茨%”和年龄等于0或者年龄为空)的结果集


名单猫= sess.createCriteria(Cat.class)
    附加(Expression.in(“名称”,新的String [] {“弗里茨”,“IZI”,“PK”}))
    新增(Expression.disjunction()
        附加(Expression.isNull(“年龄”))
     新增(Expression.eq(“年龄”,新的整数(0)))
     新增(Expression.eq(“年龄”,新的整数(1)))
     新增(Expression.eq(“年龄”,新的整数(2)))
    ))
    名单();

expression.disjunction()----意思什么可以按照逻辑分组
有很多预制的条件类型(Expression的子类)。有一个特别有用,可以让你直接嵌入SQL。 

名单猫= sess.createCriteria(Cat.class)
    新增(Expression.sql(“低像低($ alias.name)(?)”,“弗里茨%”,Hibernate.STRING))
    名单();
其中的{化名}是一个占位符,它将会被工程学系查询实体的行别名工程学系替代。(原文:{alias}占位符被查询实体的行别名所取代) 

3,对结果排序
可以使用net.sf.hibernate.expression.Order对结果调集排序。 

名单猫= sess.createCriteria(Cat.class)
    新增(Expression.like(“名称”,“F%”)
    ,。addOrder(Order.asc(“名称”))
    ,。addOrder(Order.desc(“年龄”))
    setMaxResults(50)
    名单();
4,关联(协会)
你可以在关联之间使用createCriteria(),很容易地在存在关系的实体之间指定约束。 

名单猫= sess.createCriteria(Cat.class)
    新增(Expression.like(“名称”,“F%”)
    个createCriteria(“小猫”。)
        新增(Expression.like(“名称”,“F%”)
    名单();
注意,第二个createCriteria()返回一个Criteria的新实例,指向kittens集合类的元素。 

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

名单猫= sess.createCriteria(Cat.class)
    。createAlias(“小猫”,“KT”)
    。createAlias(“龙虎斗”,“山”)
    新增(Expression.eqProperty(“kt.name”,“mt.name”))
    名单();
(createAlias())并不会建立一个标准的新实例。) 

请注意,前面两个查询中Cat实例所持有的kittens集合类并没有通过criteria预先过滤!如果你希望只返回满足条件的kittens,你必须使用returnMaps()。 

名单猫= sess.createCriteria(Cat.class)
    个createCriteria(“小猫”,“安静”。)
        新增(Expression.eq(“名称”,“F%”))
    ,。returnMaps()
    名单();
迭代ITER = cats.iterator();
而(iter.hasNext()){
    地图=(地图)iter.next“();
    猫猫(猫)map.get(Criteria.ROOT_ALIAS)的;
    猫小猫=(CAT)map.get(“KT”);
}
5,动态关联对象获取(动态关联抓取)
可以在运行时通过setFetchMode()来改变关联对象自动获取的策略。 

名单猫= sess.createCriteria(Cat.class)
    新增(Expression.like(“名称”,“弗里茨%”))
    (“龙虎斗”。setFetchMode,FetchMode.EAGER)
    名单();
这个查询会通过外连接(外连接)同时获得队友和小猫。 

6,根据范例查询(例如查询)
net.sf.hibernate.expression.Example类允许你从指定的实例创造查询条件。 

猫猫猫();
cat.setSex(“F”);
cat.setColor(Color.BLACK);
名单结果= session.createCriteria(Cat.class)
    新增(Example.create(CAT))
    名单();
版本属性,表示符属性和关联都会被忽略。默认情况下,null值的属性也被排除在外。 

你可以调整如何应用为例。你可以调整示例(范例)如何应用。 

例如例如= Example.create(CAT)
    。excludeZeroes()/ /排除零值的属性
    。excludeProperty(“色”)/ /排除一个名为“色”的属性
    。IGNORECASE()/ /执行区分大小写字符串比较
    enableLike(); / /使用类似字符串比较
名单结果= session.createCriteria(Cat.class)
    新增(例如)
    名单();
你甚至可以用示例对关联对象建立的标准。 

名单结果= session.createCriteria(Cat.class)
    新增(Example.create(CAT))
    个createCriteria(“伴侣”。)
        新增(Example.create(cat.getMate()))
    名单();









 
的HQL的多表查询:
对象之间总是有各种各样的关系,关联关系是类之间最常见的关系。多表查询是HQL中的强大功能之一,
包括内连接、左连接和右连接等。多表查询的设置及运行都比较麻烦,在运行本节中的示例时,
务必保证每一步都没有错误。
一:表之间的关联关系:
在数据库joblog中用到了3个表:student(学生表)、course(课程表)和sc(选课表)。在现实模型中,
一个学生可以选择多门课程,一个课程可以被多个学生选择,student和course是多对多的关联关系。
为了便于演示的HQL的多表查询,本显示细大全 - 宜配网假设学生和课程之间什么单向关联关系。
在多对多的关联关系中,一般来说有个中间表,这个表描述了多对多关系,这就是选课表sc,
SC每一行数据代表一个学生的选课和成绩。
各个表的主键:外键设定如下。
学生表的的主键什么的ID字段。
课程表的的主键什么的ID字段。
SC表的的主键是ID字段。
SC表中的斯诺字段是学生表的ID字段的:外键。
SC表中的CNO字段是课程表的ID字段的:外键。
在MySQL的查询浏览器中设定好上述关系。如果此处设定不正确,可能会影响多表连接处查询。
其中SC表的建表信息如下(其中弱者受制与了:外键关系)。
创建表“joblog”。“SC”(
'ID'INT(10)无符号的NOT NULL AUTO_INCREMENT的意见'身份证',
“斯诺”INT(10)无符号NOT NULL DEFAULT '0'评论'学号',
“CNO”INT(10)无符号NOT NULL DEFAULT '0'评论'课程号“,
“一级”的诠释(10)无符号默认为NULL评论“成绩”,
的PRIMARY KEY(“ID”),
键'FK_sc_1“(”斯诺“),
关键'FK_sc_2“(CNO)
约束'FK_sc_1的外键(“斯诺”)参考“学生”(“ID”),/ *:外键信息* /
约束'FK_sc_2的FOREIGN KEY(CNO')参考'当然'('ID')/ *:外键信息* /
)ENGINE = InnoDB的默认的CHARSET = GB2312;
二:表中的数据:
这一显示细中用到了3个表的数据
三:修改持久化类:
Student对象和Course对象之间是多对多的关系。此处使用的是单向关联,仅仅建立从Student到Course的单向关联。
仅有学生到课的单向关联。
为了建立Student到Course的单向关联关系,在Student.java中新加一个属性course。course属性是Set型的,
可以在这个属性中加入多个Course对象,建立起关联关系。下面是加入course属性后的源代码,粗体部分为加入的代码。
包hibernate.ch06;
进口java.util.HashSet;
进口java.util.Set;
公共类学生实现了java.io.Serializable {
        私人整数ID; / /编号
        私人整数SNO / /学号
        私人字符串SNAME / /姓名;
        私人字符串ssex; / /性别
        私人的字符串sdept; / /系部
        私人整数圣人; / /年龄
        私人的字符串saddress; / /住址
       私定课程=新的HashSet(); / /所选课程
       市民学生(){
}
/ /此处省略其他的构造方法扩展功能

/ /此处省略getter / setter方法访问器
/ /课程属性的获取访问器
   公共的集getCourse(){
        返回过程;
   }
   / /课程属性的集合访问器
   “无效setCourse(课程设置){
          this.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>元素是和<class>元素平行的元素。<set>元素表明将要映射的字段对应着一个集合。<set>元素包含多个属性,
其中:name属性用于设置映射的持久化类的属性名称,在本例中为Student表的course属性;table属性表示
多对多关联关系的中间表名称,此处为sc表;cascade表示当保存或者更新Student实例时,是否保存或更新Course对象。
     <SET>元素的子元素<key column="sno" />设定与学生表关联的中间表SC的:外键SNO。
     <set>元素的子元素<many-to-many>用于设定多对多关系。在该元素中,class属性用于设定多对多关系中,
与学生类关联的类课程类;列属性设定中间表相关的例句课程表连接处的:外键CNO。
完整的配置文件Student.hbm.xml如下所示。
<?XML版本=“1.0”?>
<的DOCTYPE Hibernate的映射公安!“ - / /休眠/ Hibernate映射的DTD 3.0 / / EN”
“http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd~~V”>
<hibernate-mapping>
      <class name="hibernate.ch06.Student" table="student" catalog="joblog">
           <ID name="id" type="integer">
                 <列name="id" />
                 <generator class="identity"> </发电机>
           </ ID>
           <! - 映射学号 - >
           <property name="sno" type="integer">
                 <列name="Sno" not-null="true"
           </财产>
           <! - 映射姓名 - >
           <property name="sname" type="string">
                <列name="Sname" length="45"
           </财产>
           <! - 映射系部 - >
           <property name="sdept" type="string">
                <列name="Sdept" length="10"
           </财产>
         <! - 映射年龄 - >
           <property name="sage" type="integer">
                <列name="Sage" />
           </财产>
           <! - 映射性别 - >
           <property name="ssex" type="string">
                <列name="Ssex" length="2"
           </财产>
           <! - 映射住址 - >
           <property name="saddress" type="string">
                <列name="Saddress" length="45"
           </财产>
          <! - 联接 - >
           <set name="course" table="sc" lazy="false" cascade="save-update">
               <key column="sno"
               <many-to-many class="hibernate.ch06.Course" column="cno" < - 多对多 - >
           </集>
       </类>
</休眠映射>
五:左外连接:
左外连接(左外连接)查询出左表对应的复合条件的所有记录,如查询张三同学的选课信息。
下面是类HQLLeftOuterJoinQuery的源代码。
包hibernate.ch06;
进口hibernate.HibernateSessionFactory;
导入java.util.Iterator的;
进口的java.util.List;
导入org.hibernate.Query;
导入org.hibernate.Session;
公共类HQLLeftOuterJoinQuery的{
       公共静态无效的主要(字串[] args){
             会话的会话= HibernateSessionFactory.currentSession();
            / /的HQL查询语句
            字符串HQL =“从学生的左加入s.courseçs.sname ='张三'”;
             查询的查询= session.createQuery(HQL)/ /创建查询;
             的名单= query.list(); / /执行查询
             迭代它= list.iterator();
             而(it.hasNext()){
                   Object []的OBJ =(对象[])it.next();
                   学生STU = obj的(学生)[0];
                   当然当然=(课程)obj的[1];
                  (“*********学生信息及其选课信息******************”);
                   (course! = NULL){
                    system.out.println(stu.getSno()“\ t”的stu.getSname()“\ T” 
                                “课程:”course.getCname());
                    }否则{
                          system.out.println(stu.getSno()“\ t”的stu.getSname()“\”);
                    };
             }
       }
}
如果只用单表查询,只能从student表中查询出张三的个人信息,而无法知道她的选课信息,因为选课信息存储在中间表sc中。
的HQL语句从学生小号左加入s.courseçs.sname ='张山'检索出了长三的选课信息。
     在的HQL中使用左外连接关键字进行左:外连接处,外关键字可以省略。
     s.course是Student对象中的一个属性,用来存储Student对象的选课信息。在执行查询时,将根据Student.hbm.xml中的
配置生成SQL语句,并检索信息。
     查询的结果返回一个Object[]数组,数组的第0个元素是Student对象,第1个元素是与Object[0]中对应的学生所选课的Course对象。
HQLLeftOuterJoinQuery类在执行过程中产生的左:外连接处的的SQL语句如下。
冬眠:
    选择
          id1_0_ student0_.id
          id4_1_ course2_.id
          student0_.Sno作为Sno1_0_
          student0_.Sname作为Sname1_0_
          student0_.Sdept作为Sdept1_0_
          student0_.Sage作为Sage1_0_
         student0_.Ssex作为Ssex1_0_
         student0_.Saddress作为Saddress1_0_
          course2_.Cno作为Cno4_1_
          course2_.Cname作为Cname4_1_
          course2_.Ccredit作为Ccredit4_1_
    从
          joblog.student student0_
    左外连接
        SC course1_
               在student0_.id = course1_.sno
   左外连接
        joblog.course course2_
               在course1_.cno = course2_.id
   哪里
        student0_.Sname ='张三'
冬眠:
    选择
          course0_.sno作为sno1_
          course0_.cno作为cno1_
          id4_0_ course1_.id
          course1_.Cno作为Cno4_0_
          course1_.Cname作为Cname4_0_
          course1_.Ccredit作为Ccredit4_0_
    从
          SC course0_
左外连接
        joblog.course course1_
                在course0_.cno = course1_.id
    哪里
        course0_.sno =?
使用如下语句将只返回学生对象。
从学生的左加入s.course C,其中s.sname ='张三'选择小号
如下是只返回学生对象的部分代码。
        会话的会话= HibernateSessionFactory.currentSession();      
       / /的HQL查询语句
        字符串HQL =“选择S从学生小号左加入s.courseçs.sname ='张三'”;
        查询的查询= session.createQuery(HQL)/ /创建查询;       
        的名单= query.list(); / /执行查询    
        迭代它= list.iterator();       
        而(it.hasNext()){
               学生STU(学生)it.next“,();
              (“*********学生信息及其选课信息******************”);
               system.out.println(stu.getSno()“\ t”的stu.getSname()“\”);
        }
六:左外抓取连接:
左外抓取连接指定在Hibernate检索数据时,采用抓取的方式,直接将数据加载到与Student对象关联的course属性中。
下面是左外抓取连接的程序。
        / /的HQL查询语句
        字符串HQL =“选择S从学生的左join fetch的s.courseçs.sname ='张三'”;
        查询的查询= session.createQuery(HQL)/ /创建查询;       
        的名单= query.list(); / /执行查询       
        迭代它= list.iterator();
        而(it.hasNext()){
                学生STU(学生)it.next“,();
               (“*********学生信息及其选课信息******************”);
               system.out.println(stu.getSno()“\ t”的stu.getSname()“\”);
        }
     左:外抓取连接处使用左join fetch的关键字。
与左外连接不同的是:左外抓取连接query.list()返回的集合中存放Student对象的引用,
与之相关联的选课信息存放在课程属性大全 - 宜配网。
七:右外连接:
HQL的大全 - 宜配网使用关键字右外部联接售后服务:外连接处,外关键字可以省略。售后服务:外连接处相关的例句左:外连接处类似,不再赘述。
八:内连接:
内连接(内蒙古
HQL的大全 - 宜配网使用关键字内部联接进行内连接处,下面什么使用内连接处的程序。
        会话的会话= HibernateSessionFactory.currentSession()/ /创建会议      
        HQL =字符串“从学生小号内加入s.course C”/ /的HQL查询语句
        查询的查询= session.createQuery(HQL)/ /创建查询;
        的名单= query.list(); / /执行查询       
        迭代它= list.iterator();            
        而(it.hasNext()){
                Object []的OBJ =(对象[])it.next();
                学生STU = obj的(学生)[0];
                当然当然=(课程)obj的[1];
               (“*********学生信息及其选课信息******************”);
                system.out.println(stu.getSno()“\ t”的stu.getSname()“\ t”的“课程:”的当然getCname());
        }
     HQL的大全 - 宜配网使用内
     可以使用选择S从学生的内在联接s.courseç只返回学生对象。
九:抓取内连接:
抓取内连接与内连接不同之处在于其对象的内存状态不一样。的HQL中使用内部联接取进行抓取内连接处,如下程序,所示。
        会话的会话HibernateSessionFactory.currentSession =()/ /创建会议      
        HQL =“选择S从学生的内在join fetch的s.courseç”/ /的HQL语句
        查询的查询= session.createQuery(HQL)/ /创建查询;       
        的名单= query.list(); / /执行查询       
        迭代它= list.iterator();      
        而(it.hasNext()){
        学生STU(学生)it.next“,();
        (“*********学生信息及其选课信息******************”);
        system.out.println(stu.getSno()“\ t”的stu.getSname()“\”);
    }
     内抓取连接处使用内部联接fech关键字。
     它与内连接的区别是返回检索的list中存放的是Student对象的引用,与之相关联的选课信息存放在course属性中

你可能感兴趣的:(Hibernate的凝乳的封装和的HQL的多表查询:)