准备数据库表,文章与之前的文章有关联,执行以下脚本
-- ----------------------------
-- 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还是打开的.不然会抛出异常
未完待续…….