HQL实用技术(二)

时间:2022-04-24 06:27:42

一、Hibernate支持的查询方式

  1、HQL查询
  2、Criteria查询
  3、原生SQL(Native SQL)查询

public void testHQL_2() {
        Configuration config = new Configuration().configure();
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
        Transaction tx = session.beginTransaction();
        
        String hql = "from User u where u.uid<4";
        Query query =  session.createQuery(hql);
        List<User> users = query.list();
        for (User user : users) {
            System.out.println(user);
        }
        
        tx.commit();
}

二、在HQL查询语句中绑定参数

  1、按参数位置绑定 (下标从0开始)

    from User where name = ? 

public void testSetXXX() {
        Configuration config = new Configuration().configure();
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
        Transaction tx = session.beginTransaction();
        
        //按照参数位置绑定
        
        String hql = "from User where uid=?";    //下表从0开始
        Query query = session.createQuery(hql);
        query.setInteger(0, 2);
        User user = (User) query.uniqueResult();
        System.out.println(user);
        
        tx.commit();
    }

  2、按参数名称绑定 (推荐使用)

    from User where name = :name

public void testSetName() {
        Configuration config = new Configuration().configure();
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
        Transaction tx = session.beginTransaction();
        
        //按照参数名称绑定
        
        String hql = "from User where uname=:uname";
        Query query = session.createQuery(hql);
        query.setString("uname","张三");
        User user = (User) query.uniqueResult();
        System.out.println(user);
        
        tx.commit();
    }

三、为参数赋值

  1、针对数据类型的赋值

    setXXX():针对具体数据类型
    setXXX( int position, XXX value)
    setXXX( String name, XXX value)

  2、任意类型参数

    setParameter():任意类型参数
    setParameter( int position, Object value)
    setParameter( String name, Object value)

public void testSetParameter() {
        Configuration config = new Configuration().configure();
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
        Transaction tx = session.beginTransaction();
        
        //setParameter():任意类型参数
        
        String hql = "from User where uid=:uname";
        Query query = session.createQuery(hql);
        query.setParameter("uname",1);
        User user = (User) query.uniqueResult();
        System.out.println(user);
        
        tx.commit();
    }

  3、setProperties():专为命名参数定制

      注意:也可以使用setProperties(Map)的用法 

public void testSetProperties() {
        Configuration config = new Configuration().configure();
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
        Transaction tx = session.beginTransaction();
        
        //setParameter():任意类型参数
        //动态查询
        
        User user = new User();
        user.setUname("%张%");
        user.setAge(14);
        String hql = "from User where 1=1";
        if(user.getUname()!=null){
            hql += " and uname like :uname";
        }
        if(user.getAge()!=null){
            hql += " and age<:age";
        }

        Query query = session.createQuery(hql);
        query.setProperties(user);
        List<User> list = query.list();
        for (User user2 : list) {
            System.out.println(user2);
        }
        
        tx.commit();
    }

    setProperties(Map)的用法

public void testSetMap() {
        Configuration config = new Configuration().configure();
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
        Transaction tx = session.beginTransaction();
        
        Map<String,Object> map = new HashMap<String, Object>();
        map.put("uname", "%张%");
        
        String hql = "from User where 1=1";
        if(map.get("uname")!=null){
            hql += " and uname like :uname";
        }
        
        Query query = session.createQuery(hql);
        query.setProperties(map);
        List<User> list = query.list();
        for (User user : list) {
            System.out.println(user);
        }
        
        tx.commit();
    }

 

四、分页查询

  Query接口的相关方法

  uniqueResult() :获取唯一对象(如果返回结果只有一条可以使用)
  setFirstResult() :设置从第几条开始
  setMaxResults():设置读取最大记录数

public void testPage() {
        Configuration config = new Configuration().configure();
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
        Transaction tx = session.beginTransaction();
        
        //分页查询
        //setMaxResults()也可以单独使用;
        
        int page = 2;
        int size = 2;
        String hql = "from User";
        
        Query query = session.createQuery(hql);
        query.setFirstResult((page-1)*size);
        query.setMaxResults(size);
        
        List<User> users = query.list();
        for (User user : users) {
            System.out.println(user);
        }
        
        tx.commit();
    }

  注意:setMaxResults()方法也可以单独使用,配合排序使用,setMaxResults(n)单独设置可实现获取前n条的效果

五、HQL投影查询

  HQL投影查询是查询一个持久化类的一个或多个属性值,或者是通过表达式或聚合函数得到的值;投影查询需要使用HQL的select子句;

  查询结果的封装主要分三种情况:

    1、封装成Object对象

//封装成Object对象
        String hql = "select uid from User";
        Query query = session.createQuery(hql);
        List<Integer> list = query.list();
        for (Integer integer : list) {
            System.out.println(integer);
        }

    2、封装成Object数组 

//封装成Object数组
        String hql = "select uname from User";
        Query query = session.createQuery(hql);
        List<String> list = query.list();
        for (String integer : list) {
            System.out.println(integer);
        }

    3、通过构造方法封装成对象 (实体类需要构造对象)

public class User {
            private Integer uid;
            private String uname;
            private Integer age;
            private String sex;
            public User() { }
            
            public User(Integer uid,String uname,String sex) {
                this.uid = uid;
                this.uname = uname;
                this.sex = sex;
            }
        }
public void testQuery_1() {
        Configuration config = new Configuration().configure();
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.getCurrentSession();
        Transaction tx = session.beginTransaction();
        
        //实体中必须有对应的构造方法
        String hql = "select new User(uid,uname,sex) from User";
        Query query = session.createQuery(hql);
        List<User> list = query.list();
        for (User user : list) {
            System.out.println(user);
        }
        
        tx.commit();
    }

注意:对象不是持久化状态,仅用于封装结果
提示:若查询结果仅用于展示,不需要保持持久化状态,应尽量使用投影查询以减少开销,提高效率

六、Hibernate的三种状态和六大接口分别是什么?

  1、瞬时态、持久态、游离态;

  2、接口:

    SessionFactory

    Session

    Query

    SQLQuery

    Filter:一般用于多表,对查询结果进行筛选

    Criteria:很少用,只能操作单表