微信扫一扫

028-83195727 , 15928970361
business@forhy.com

JavaEE学习笔记之SSH—Hibernate(5)

hibernate2016-07-07

今天来看看 Hibernate 的一个功能——高级查询

当然只是简单来了解一下,Hibernate 的高级查询内容很丰富。

高级查询分为两部分:

1.QBL ——-> hql查询

2.QBC ——-> 模板查询

第一部分:

1.内连接查询

内连接(INNER JOIN)使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。根据所使用的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。

a、等值连接:
    在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列(条件列)。

b、不等连接:
    在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、<=、<、!>、!<和<>。

c、自然连接:
    在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列(条件列)。

例1:查询出顾客以及其拥有的订单信息(没有下单的用户查询不到)
    默认返回多个对象和(或)属性,存放在 Object[]队列中
        String hql = " from Customer as cus inner join cus.orders os";
        Query query = session.createQuery(hql);
        List<Object> os = query.list();
        for( Object o : os){
            Object[] oo = (Object[]) o;
            Customer cus = (Customer) oo[0];
            Order order = (Order) oo[1];

            System.out.println(cus.getName()+"--"+order.getCost());
        }
例2:查询比jacky年龄大的所有人的信息
        String hql = " from Customer as cus,Customer as cus2 " +
                "where cus.age>cus2.age and cus.name='jacky'";
        Query query = session.createQuery(hql);
        List<Object> os = query.list();
        for( Object o : os){
            Object[] oo = (Object[]) o;
            Customer cus = (Customer) oo[0];
            Customer cus2 = (Customer) oo[1];
            System.out.println(cus.getName()+"--"+cus2.getName());
        }
例3:抓取 fetch
    一个"fetch"连接允许仅仅使用一个选择语句就将相关联的对象或一组值的集合随着他们的父对象的初始化而被初始化
        //fetch 抓取
        String hql = "from Customer as c join fetch c.orders";
        Session session = HibernateSessionFactory.getSession();
        Query query = session.createQuery(hql);
        List<Customer> os = query.list();
        for(Customer customer : os){
            System.out.println(customer);
            for(Order order: customer.getOrders()){
                System.out.println("   "+order);
            }
        }
例4:指定查询列
        String hql = "select o.total,c.name,c.address  from Customer as c join c.orders as o";
        Session session = HibernateSessionFactory.getSession();
        Query query = session.createQuery(hql);
        List<Object> os = query.list();
        for(Object o : os){
            Object[] arr = (Object[]) o;
            for(Object a: arr){
                System.out.print(a+";");
            }
            System.out.println();
        }

select查询

1.指定查询集合
        select o
        from Customer as c 
        join c.orders as o
        where c.name = '张三'
        =>
        select c.orders 
        from Customer as c 
        where c.name = '张三'

        结果:
            List<Order>
2.指定查询列
        select o.total,c.name
        from Customer as c 
        join c.orders as o 
        where c.name = '张三'

        结果:
            List<Object[]>
3.将查询结果保存到list集合中
        select new list(c,o)  
        from Customer as c 
        join c.orders as o

        结果
            List<List<Object>>
4.将查询结果重新封装到一个对象中
        select new com.briup.model.OrderModel(c.id,c.name,c.address,o.orderDate,o.total)"
        from Customer as c 
        join c.orders as o
5.聚集函数

    avg()   平均数

    sum()   总和

    max()   最大数

    count() 总数

6.where子句

    数学运算符           +, -, *, /

    二进制比较运算符    =, >=, <=, <>, !=, like

    逻辑运算符           and, or, not in, not in, between, is null, is not null, is empty, is                            not empty, member of and not member of

    函数              current_date(), current_time(), current_timestamp()
                        substring(), trim(), lower(), upper(), length(), locate(), abs(), sqrt(), bit_length() coalesce() nullif()

    任何数据库支持的SQL标量函数比如sign(), trunc(), rtrim(), sin()

    JDBC参数传入 
                        占位符 :?
                        命名参数:name, :start_date, :x1

    SQL 直接常量 'foo', 69, '1970-01-01 10:00:01.0'

7.order by子句

    desc    降序

    asc     升序
8.group by

    select avg(o.total),o.c_id

    from tbl_order o

    group by o.c_id

    having o.c_id =1;

2.外连接。

与内连接不同的是,外连接不只列出与连接条件相匹配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行。分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)和全外连接(FULL OUTER JOIN或FULL JOIN)三种

例3:查询所有的用户以及其下的订单
        String hql = " from Customer as cus left join cus.orders";
        Query query = session.createQuery(hql);
        List<Object> os = query.list();
        for( Object o : os){
            Object[] oo = (Object[]) o;
            Customer cus = (Customer) oo[0];
            Order order = (Order) oo[1];
            if(order!=null){
                System.out.println(cus.getName()+","+order.getCost()+","+order.getOrderDate());
            }else{
                System.out.println(cus.getName());
            }
        }

3.交叉连接

 交叉连接不带WHERE 子句,它返回被连接的两个表所有数据行的笛卡尔积,返回到结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

第二部分:

1.查询所有

例4: 查询出所有的顾客信息
        Criteria criteria = session.createCriteria(Customer.class);
        List<Customer> customers = criteria.list();
        for(Customer cus : customers){
            System.out.println(cus);
        }

2.Restrictions用法

Restrictions.eq    --> equal,等于.

Restrictions.allEq --> 参数为Map对象,使用key/value进行多个等于的比对,相当于多个Restrictions.eq的效果

Restrictions.gt    --> great-than > 大于

Restrictions.ge    --> great-equal >= 大于等于

Restrictions.lt    --> less-than, < 小于

Restrictions.le    --> less-equal <= 小于等于

Restrictions.between --> 对应SQL的between子句

Restrictions.like  --> 对应SQL的LIKE子句

Restrictions.in    --> 对应SQL的in子句

Restrictions.and   --> and 关系

Restrictions.or    --> or 关系

Restrictions.isNull--> 判断属性是否为空,为空则返回true

Restrictions.isNotNull --> 与isNull相反

例5: 查询符合条件的顾客的信息(年龄大于12)
        Criteria criteria = session.createCriteria(Customer.class);
        criteria.add(Restrictions.gt("age", 12));
        List<Customer> customers = criteria.list();
        for(Customer cus : customers){
            System.out.println(cus);
        }
例6: 查询名字在"terry,larry,tom"之间的用户的信息
        Session session = HibernateSessionFactory.getSession();
        Transaction tran = session.beginTransaction();
        String[] names = {"terry","larry","tom"}; 
        Criteria criteria = session.createCriteria(Customer.class);
        criteria.add(Restrictions.in("name", names));
        List<Customer> customers = criteria.list();
        for(Customer cus : customers){
            System.out.println(cus);
        }       
例7: 年龄为空的用户信息
criteria.add(Restrictions.isNull("age"))
例8: 查询名字在"terry,larry,tom"之间的用户的信息或者年龄等于15的顾客的信息
criteria.add(Restrictions.or(Restrictions.in("name", names), Restrictions.eq("age", 15)));

3.Order 排序

criteria.addOrder() 添加排序约束
     Order.desc("id") 按照id降序排列
     Order.asc("id")  按照id升序排列

4.为模板添加模板

        //1创建模板
        Criteria criteria = session.createCriteria(Order.class);
        //2为模板添加约束
        criteria.add(Restrictions.isNull("customer"));      //添加约束为 不属于customer的order即c_id=null
        criteria.add(Restrictions.ge("total", 300.0));      //添加约束为 total 大于 300.0
        //3为模板添加模板   customer为order中维护的属性
        Criteria customerCriteria = criteria.createCriteria("customer");
        //4为模板的模板添加约束
        customerCriteria.add(Restrictions.eq("name", "张一百"));
        //5查询
        List<Order> orders = criteria.list();
        for (Order order : orders) {
            System.out.println(order);
        }

5.其他

    Conjunction

    Disjunction

    Example