24H免费课程咨询  TEL:13401595960   QQ:1870218756  微信:13401595960(李老师)

东方博宜

网站首页 > 软件开发资讯 > Java开发

Hibernate的参数化查询、命名参数查询、级联操作!

2017-07-27 20:59:20 东方博宜 阅读

1、手动引入一个hibernate的项目

A、添加hibernate需要的jar

B、添加hibernate.cfg.xml核心配置文件,在该文件中配置orm文件的位置

C、添加hibernateorm文件(xx.hbm.xml

D、添加POJO

E、添加HibernateSessionFactory

 

2、参数化查询

    /**

     * 参数化查询

     * @return

     */

    public static List getList(){

       Session session = HibernateSessionFactory.getSession();

       Query query = session.createQuery("from Emp where ename like ? and sal > ?");

       query.setString(0, "%%");

       query.setDouble(1, 3000.0);

      

       List list = query.list();

       HibernateSessionFactory.closeSession();

      

       return list;

    }

   

    /**

     * 参数化查询

     * @param hql

     * @param paramters

     * @return

     */

    public static List getList(String hql,Object[] paramters){

       Session session = HibernateSessionFactory.getSession();

       Query query = session.createQuery(hql);

       //为参数赋值

        for(int i = 0;i < paramters.length;i++){

           query.setParameter(i, paramters[i]);

       }

      

       List list = query.list();

       HibernateSessionFactory.closeSession();

      

       return list;

      

    }

   

    public static void main(String[] args) {

       Object[] paramters = {"%%",4000.0};

       List list = getList("from Emp where ename like ? and sal >= ?",paramters);

       for(int i = 0;list != null && i < list.size();i++){

           Emp emp = (Emp) list.get(i);

           System.out.println(emp.getEmpno() + " " + emp.getEname() + " " + emp.getSal());

       }

    }

 

3、命名参数

    /**

     * 命名参数查询

     * @return

     */

    public static List getListByName(){

       Session session = HibernateSessionFactory.getSession();

       Query query = session.createQuery("from Emp where ename like :n and sal > :s");

       query.setParameter("s", 5000.0);

       query.setParameter("n", "%%");

      

       List list = query.list();

       HibernateSessionFactory.closeSession();

      

       return list;

    }

   

    /**

     * 命名参数查询

     * @return

     */

    public static List getListByName(String hql,Map map){

       Session session = HibernateSessionFactory.getSession();

       Query query = session.createQuery(hql);

       //为命名参数赋值

       //循环map

       Set keys = map.keySet();

       Iterator it = keys.iterator();

      

       while(it.hasNext()){

           String name = (String) it.next();

           query.setParameter(name, map.get(name));

       }

      

       List list = query.list();

       HibernateSessionFactory.closeSession();

      

       return list;

    }

   

    /**

     * 命名参数查询

     * @return

     */

    public static List getListByNos(String hql,String name,Object[] nums){

       Session session = HibernateSessionFactory.getSession();

       Query query = session.createQuery(hql);

       query.setParameterList(name, nums);

      

       List list = query.list();

       HibernateSessionFactory.closeSession();

      

       return list;

    }

   

   

    public static void main(String[] args) {

//     String hql = "from Emp where ename like :name and sal > :sal";

//     Map map = new HashMap();

//     map.put("name", "%%");

//     map.put("sal", 2000.0);

//    

//     List list = getListByName(hql,map);

      

       Object[] nums = {1,3,5,8,10,12};

       List list = getListByNos("from Emp where empno in(:nos)","nos",nums);

       for(int i = 0;list != null && i < list.size();i++){

           Emp emp = (Emp) list.get(i);

           System.out.println(emp.getEmpno() + " " + emp.getEname() + " " + emp.getSal());

       }

    }

 

4、合并hbm.xml文件

将多个orm文件的class节点,合并到一个orm文件中,删除多余的orm文件,修改hibernate.cfg.xml文件(修改mapping节点)

 

5、抽取出hql语句放到hbm.xml中:session.getNamedQuery()

A、将hql语句定义到orm文件中

图片.png

 

B、在service中通过getNamedQuery来获取hql,生成Query的对象

    /**

     * orm文件获取hql,然后参数化查询

     * @param hql

     * @param paramters

     * @return

     */

    public static List getHqlList(String hqlname,Object[] paramters){

       Session session = HibernateSessionFactory.getSession();

        Query query = session.getNamedQuery(hqlname);//根据hqlnameorm文件中获取hql,生成query

       //为参数赋值

       for(int i = 0;paramters != null && i < paramters.length;i++){

           query.setParameter(i, paramters[i]);

       }

      

       List list = query.list();

       HibernateSessionFactory.closeSession();

      

       return list;

      

    }

   

   

    public static void main(String[] args) {

       Object[] parameters = {3000.0,5000.0};

       List list = getHqlList("getHiSalEmp",parameters);

       for(int i = 0;i < list.size();i++){

           Emp e = (Emp) list.get(i);

           System.out.println(e.getEmpno() + " " + e.getEname() + " " + e.getSal());

       }

    }

 

6、级联查询:有主外键关系的情况下,级联查询、删除(增加、修改)

dept表的deptno字段被emp表的deptno字段引用,形成主外键关联!

 

反转后的变化:

Emp

图片.png

 


 

Emp.hbm.xml

图片.png

 

Dept

图片.png

 

Dept.hbm.xml

图片.png

 

A、级联查询

一般来说,查询多的那方(外键表)有需求级联查询一的那方(主键表);反过来说,查询一的那方,一般不要求查询多的那方!

 

例子:查询员工级联查询部门

注意:查询员工级联查询员工所在的部门是基于延迟加载设计的,如果需要查询员工级联查询部门,则需要关闭这个查询的延迟加载机制!

 

Emp.hbm.xml

 

    /**

     * 根据主键查询对象

     * @param c

     * @param num

     * @return

     */

    public static Object getObject(Class c,int num){

       Session session = HibernateSessionFactory.getSession();

       Object obj = session.get(c, num);

       HibernateSessionFactory.closeSession();

      

       return obj;

    }

   

    public static void main(String[] args) {

       Emp e = (Emp) getObject(Emp.class,3);

       System.out.println(e.getEmpno() + " " + e.getEname());

       Dept d = e.getDept();

       System.out.println(d.getDeptno());

       System.out.println(d.getDname() + " " + d.getAddr());

    }

 

例子:查询部门级联查询员工

Emp.hbm.xml:关闭延迟加载

图片.png

 

EmpService

    /**

     * 根据主键查询对象

     * @param c

     * @param num

     * @return

     */

    public static Object getObject(Class c,int num){

       Session session = HibernateSessionFactory.getSession();

       Object obj = session.get(c, num);

       HibernateSessionFactory.closeSession();

      

       return obj;

    }

   

    public static void main(String[] args) {

       Dept d = (Dept) getObject(Dept.class,1);

       System.out.println(d.getDeptno() + " " + d.getDname() + " " + d.getAddr());

      

       Set set = d.getEmps();

       Iterator it = set.iterator();

       while(it.hasNext()){

           Emp e = (Emp) it.next();

           System.out.println(e.getEmpno() + " " + e.getEname() + " " + e.getDept().getDeptno());

       }

    }

 

问题:一般不能把两方的延迟加载设计都关闭,因为会造成不必要的查询!

比如:查询3号员工,会级联查询出员工所在的部门,又会级联查询出该部门下的所有员工,如果员工数量比较多,效率是极其低!

 

因此,我们一般,只是查询多的那方,级联查询一的那方!

 

B、 级联删除:一般只有删除1的那方(主键),级联操作(操作模式:a、级联删除引用的数据 b、级联的数据外键字段置null)多的那方

 

要点:

a、  orm文件上,描述允许哪种级联操作

b、  级联删除时,一的那方,对象不能是new出来仅仅赋值id,而是查询出来的(跟是否打开lazy的设置没有关系)

 

 

Dept.hbm.xml

图片.png

 

EmpService

    /**

     * 删除

     * @return

     */

    public static void delObject(Object obj){

       Session session = HibernateSessionFactory.getSession();

       Transaction ta = session.beginTransaction();

       session.delete(obj);

       ta.commit();

       HibernateSessionFactory.closeSession();

    }

   

    public static void main(String[] args) {

       Dept d = (Dept) getObject(Dept.class,6);//注意:对象是查询出来的

       delObject(d);

    }

 

情况二:删除Dept将对应的Empdeptno字段置空!

 图片.png

要点:

a、设置外键关联,删除时关联关系为set null

b、对象必须是new出来的,不能是查询出来的!!!

 

    /**

     * 删除

     * @return

     */

    public static void delObject(Object obj){

       Session session = HibernateSessionFactory.getSession();

       Transaction ta = session.beginTransaction();

       session.delete(obj);

       ta.commit();

       HibernateSessionFactory.closeSession();

    }

   

    public static void main(String[] args) {

       Dept d = new Dept();

       d.setDeptno(7);

       delObject(d);

    }


Powered by 东方博宜教育咨询江苏有限公司  ©2008-2017 www.czos.cn