hibernate学习笔记(五) 深入探究hibernate查询

作者:叁念

准备数据库表,文章与之前的文章有关联,执行以下脚本

-- ----------------------------
-- Table structure for cst_customer
-- ----------------------------
DROP TABLE IF EXISTS `cst_customer`;
CREATE TABLE `cst_customer`  (
  `cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
  `cust_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '客户名称(公司名称)',
  `cust_source` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '客户信息来源',
  `cust_industry` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '客户所属行业',
  `cust_level` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '客户级别',
  `cust_linkman` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人',
  `cust_phone` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '固定电话',
  `cust_mobile` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '移动电话',
  PRIMARY KEY (`cust_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of cst_customer
-- ----------------------------
INSERT INTO `cst_customer` VALUES (1, '阿里', '', NULL, '', '', '', '');
INSERT INTO `cst_customer` VALUES (2, '百度', '', NULL, '', '', '', '');
INSERT INTO `cst_customer` VALUES (3, '腾讯', NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `cst_customer` VALUES (4, '叁念', NULL, NULL, NULL, NULL, NULL, NULL);

-- ----------------------------
-- Table structure for cst_linkman
-- ----------------------------
DROP TABLE IF EXISTS `cst_linkman`;
CREATE TABLE `cst_linkman`  (
  `lkm_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '联系人编号(主键)',
  `lkm_name` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人姓名',
  `lkm_cust_id` bigint(32) NOT NULL COMMENT '客户id',
  `lkm_gender` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人性别',
  `lkm_phone` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人办公电话',
  `lkm_mobile` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人手机',
  `lkm_email` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人邮箱',
  `lkm_qq` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人qq',
  `lkm_position` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人职位',
  `lkm_memo` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人备注',
  PRIMARY KEY (`lkm_id`) USING BTREE,
  INDEX `FK_cst_linkman_lkm_cust_id`(`lkm_cust_id`) USING BTREE,
  CONSTRAINT `FK_cst_linkman_lkm_cust_id` FOREIGN KEY (`lkm_cust_id`) REFERENCES `cst_customer` (`cust_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of cst_linkman
-- ----------------------------
INSERT INTO `cst_linkman` VALUES (1, '张三', 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `cst_linkman` VALUES (2, '李四', 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `cst_linkman` VALUES (3, '王五', 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `cst_linkman` VALUES (4, '赵六', 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `cst_linkman` VALUES (5, '田七', 4, NULL, NULL, NULL, NULL, NULL, NULL, NULL);


一、Hql单表查询

1.1 基本查询
(为节省篇幅,基本查询贴出所有代码,后文只贴出主要代码)

        Session session = HibernateUtil.openSession();
        Transaction transaction = session.beginTransaction();

        String hql1 = "from com.sannian.bean.Customer";
        String hql2 = "from Customer";
        String hql3 = "from java.lang.Object";//知道一下,不要这么写

        Query query1 = session.createQuery(hql1);
        List list1 = query1.list();
        System.out.println(list1);

        Query query2 = session.createQuery(hql2);
        List list2 = query2.list();
        System.out.println(list2);
        /**
         * 以上query1,query2打印结果如下:
         * [Customer [cust_id=1, cust_name=阿里], 
         * Customer [cust_id=2, cust_name=百度], 
         * Customer [cust_id=3, cust_name=腾讯], 
         * Customer [cust_id=4, cust_name=叁念]]
         */
        Query query3 = session.createQuery(hql3);
        List list3 = query3.list();
        System.out.println(list3);
        /**
         * query3打印结果如下:
         * [Customer [cust_id=1, cust_name=阿里], 
         * Customer [cust_id=2, cust_name=百度], 
         * Customer [cust_id=3, cust_name=腾讯], 
         * Customer [cust_id=4, cust_name=叁念], 
         * LinkMan [lkm_id=1, lkm_name=张三], 
         * LinkMan [lkm_id=2, lkm_name=李四], 
         * LinkMan [lkm_id=3, lkm_name=王五], 
         * LinkMan [lkm_id=4, lkm_name=赵六], 
         * LinkMan [lkm_id=5, lkm_name=田七]]
         */

        transaction.commit();
        session.close();
1.2 排序查询
        String hql1 = "from Customer order by cust_id asc";//升序
        String hql2 = "from Customer order by cust_id desc";//降序
1.3 条件查询
        String hql1 = "from Customer where cust_id = ?";
        query.setLong(0, 2l);
        或
        String hql2 = "from Customer where cust_id = :cust_id";
        query.setLong("cust_id", 2l);
1.4 分页查询
        String hql = "from Customer";
        Query query = session.createQuery(hql);
        query.setFirstResult(0);
        query.setMaxResults(2);
1.5 聚合查询
        String hql1 = "select count(*) from Customer";
        String hql2 = "select sum(cust_id) from Customer";
        String hql3 = "select avg(cust_id) from Customer";
        String hql4 = "select max(cust_id) from Customer";
        String hql5 = "select min(cust_id) from Customer";
1.6 投影
        String hql1 = "select cust_name from Customer";
        String hql2 = "select cust_id, cust_name from Customer";//返回的是数组列表
        String hql3 = "select new Customer(cust_id, cust_name) from Customer";//要想返回的是对象列表,这种写法必须要有相应的构造器
1.7 多表查询
1.7.1 SQL写法
            //1.交叉连接(笛卡尔积) - 尽可能避免,查询出来的数据一般没有什么意义
                select * from A,B
            //2.内连接
                //2.1 隐式内连接
                    select * from A,B where a.id = b.aid
                //2.2 显式内连接
                    select * from A inner join B where a.id = b.aid
            //3.外连接
                //3.1 左外
                    select * from A left join B on a.id = b.aid
                //3.2 右外
                    select * from A right join B on a.id = b.aid

关于内连接与外链接的一些理解可以看如下图(其中A、B为不同的两张表,AB表有部分公共数据)

1.7.2 HQL写法
            //1.内连接:将连接的两端对象分别返回,放到数组中
                String hql = "from Customer c inner join c.linkmens";

                Query query = session.createQuery(hql);
                List<Object[]> list = query.list();

            //2.迫切内连接:帮我们封装对象,返回值就是一个对象
                String hql = "from Customer c inner join fetch c.linkmens";

                Query query = session.createQuery(hql);
                List<Customer> list = query.list();

            //3.外连接
            //3.1 左外
                String hql = "from Customer c left join c.linkmens";

                Query query = session.createQuery(hql);
                List<Object[]> list = query.list();

             |-- 迫切左外
             //3.2 右外
                String hql = "from Customer c right join c.linkmens";

                Query query = session.createQuery(hql);
                List<Object[]> list = query.list();

             |-- 迫切右外

二、Criteria查询

2.1 基本查询
            Criteria criteria = session.createCriteria(Customer.class);
            List list = criteria.list();
2.2 条件查询
            Criteria criteria = session.createCriteria(Customer.class);
            criteria.add(Restrictions.eq("cust_id", 3l));
            List list = criteria.list();
2.3 分页查询
            Criteria criteria = session.createCriteria(Customer.class);
            // 每页显示2个,显示第2页
            criteria.setFirstResult(2);
            criteria.setMaxResults(2);
            List list = criteria.list();
2.4 排序查询
            Criteria criteria = session.createCriteria(Customer.class);
            criteria.addOrder(Order.asc("cust_id"));//升序
            criteria.addOrder(Order.desc("cust_id"));//降序
            List list = criteria.list();    
2.5 统计查询
            Criteria criteria = session.createCriteria(Customer.class);
            criteria.setProjection(Projections.sum("cust_id"));     
            Object res = criteria.uniqueResult();
2.6 离线查询(之前的都是非离线查询)

离线与非离线的区别

        非离线:
            session.createCriteria(Customer.class)  
        离线:
            // Web/Service层 凭空创建Criteria
            DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
            dc.add(Restrictions.eq("cust_id", 4l));

            //发送到dao层
            Session session = HibernateUtil.openSession();
            Transaction transaction = session.beginTransaction();

            // dao层
            Criteria criteria = dc.getExecutableCriteria(session);
            List list = criteria.list();

三、 查询优化

3.1 类级别查询
        /**
         * get:立即加载,执行方法时立即发送SQL语句查询
         */
        Customer customer = session.get(Customer.class, 1l);
        System.out.println(customer);
        /**
         * load:(默认)执行方法时不会发送SQL语句,而是返回了一个对象,使用这个对象时(如打印)才开始查询
         * 默认是这样的,当然我们可以修改其查询方式,这涉及到了一个叫“懒加载”的概念,
         * 即“lazy='true|false'”,由上可知,lazy默认是false
         */
        Customer customer2 = session.load(Customer.class, 2l);
        System.out.println(customer2);

懒加载的配置方式:
Customer.hbm.xml文件中,配置“lazy=’true|false’”,如下:

<hibernate-mapping package="com.sannian.bean">
    <class name="com.sannian.bean.Customer" table="cst_customer" lazy="false">
    ......
        lazy(默认值):true, 查询类时,会返回代理对象.会在使用属性时,根据关联的session查询数据库.加载数据.
        lazy:false. load方法会与get方法没有任何区别.调用时即加载数据.
        结论:为了提高效率.建议使用延迟加载(懒加载)
        注意:使用懒加载时要确保,调用属性加载数据时,session还是打开的.不然会抛出异常

未完待续…….

猜你喜欢

转载自blog.csdn.net/qq_36868342/article/details/80668799
今日推荐