Hibernate中用left join(左外连接)查询映射中没有关联关系的两个表记录问题
一、问题背景
create table SPLIT_SUMMARY ( uuid VARCHAR2(32) not null, star_tdate VARCHAR2(26) default '', end_date VARCHAR2(26) default '', store_id VARCHAR2(32) default '', order_total_price NUMBER(13,2) default 0.00, product_total_price NUMBER(13,2) default 0.00, store_fz_price NUMBER(13,2) default 0.00, shop_fz_price NUMBER(13,2) default 0.00, status CHAR(1) default '0', create_date VARCHAR2(26) default '', note VARCHAR2(512) default '' )
商户表store结构如下:
create table STORE ( store_id VARCHAR2(32) default '' not null, store_name VARCHAR2(254) default '' )
两表在Hibernate映射中没有关联关系,split_summary中的store_id可能在store表中,也可能不在,要查询所有的split_summary中的记录以及store中store_id和split_summary表中store_id相匹配的记录。很容易想到在oracle使用左连接进行查询,sql语句如下:
select ss.uuid,ss.store_id, s.store_name from split_summary ss left join store s on ss.store_id=s.store_id where 1=1 order by ss.uuid desc
二、Hibernate中的左连接查询
from Item i left join i.bids b with b.amount > 100 where i.description like '%Foo%'
而上述中的split_summary和store在映射中是没有定义关联关系的,怎么解决?
三、解决方案
protected Map<String, Object> getQuerySQL(HttpServletRequest request, ActionForm form) { OrderSplitForm sform = (OrderSplitForm) form; // 构建返回Map Map<String, Object> returnMap = new HashMap<String, Object>(); // 构建参数Map Map<String, String> params = new HashMap<String, String>(); // 编写SQL StringBuffer sql = new StringBuffer( "select ss.uuid,ss.store_id,s.store_name,ss.SHOP_FZ_PRICE,ss.STORE_FZ_PRICE," + "ss.ORDER_TOTAL_PRICE,ss.PRODUCT_TOTAL_PRICE,ss.status,ss.STAR_TDATE,ss.END_DATE," + "ss.note from split_summary ss left join store s on ss.store_id = s.store_id where 1=1"); // 将账单与店铺关联起来, 使用左连接,解决不是商户的问题 // sql.append(" and ss.storeId = store.id"); // 店铺编号查询条件 if (!StringUtil.isEmpty(sform.getStoreId())) { sql.append(" and ss.store_Id = :storeId"); params.put("storeId", sform.getStoreId()); } // 店铺名查询条件 if (!StringUtil.isEmpty(sform.getStoreName())) { sql.append(" and s.store_Name like :storeName"); params.put("storeName", "%" + sform.getStoreName() + "%"); } // 开始时间查询条件 if (!StringUtil.isEmpty(sform.getStartDate())) { sql.append(" and ss.STAR_TDATE >= :startDate"); params.put("startDate", sform.getStartDate()); } // 结束时间查询条件 if (!StringUtil.isEmpty(sform.getEndDate())) { sql.append(" and ss.END_DATE <= :endDate"); params.put("endDate", sform.getEndDate()); } // 分账单状态 if (!StringUtil.isEmpty(sform.getStatus())) { sql.append(" and ss.status = :status"); params.put("status", sform.getStatus()); } // 按照创建时间倒序排序 // sql.append(" order by ss.create_Date desc"); sql.append(" order by ss.uuid desc"); returnMap.put("sql", sql.toString()); returnMap.put("param", params); return returnMap; }
/** * Native SQL查询 * @param nativeSQL sql * @param map 参数绑定map * @param page 分页查询参数 * @param typeMap 标量查询返回类型 * @return * @throws Exception */ public List listByNativeSQL(String nativeSQL, Map<String, Object> map, Pager page, Map<String, Type> typeMap) throws Exception { List list = null; try { session = sessionFactory.openSession(); SQLQuery query = session.createSQLQuery(nativeSQL); if (map != null) { for (String key : map.keySet()) { if (nativeSQL.indexOf(":" + key) != -1) { query.setParameter(key, map.get(key)); System.out.println("param[" + key + "]===" + map.get(key)); } } } if (typeMap != null) { for (String key : typeMap.keySet()) { query.addScalar(key, typeMap.get(key)); } } if (page != null) { query.setFirstResult(page.getFromRow()); query.setMaxResults(page.getRowsPerPage()); } else { query.setFirstResult(0); query.setMaxResults(20); } list = query.list(); if (page != null) { SQLQuery countQuery = session.createSQLQuery(countSql(nativeSQL)); if (map != null) { for (String key : map.keySet()) { if (nativeSQL.indexOf(":" + key) != -1) { countQuery.setParameter(key, map.get(key)); System.out.println("param[" + key + "]===" + map.get(key)); } } } if (countQuery != null) { List countlist = countQuery.list(); if (countlist != null && countlist.size() > 0) { page.setTotalRow(((Number) countlist.get(0)).intValue()); } } } } catch (Exception e) { e.printStackTrace(); PubLogs.dbLogError(new StringBuffer("获取查询列表失败!").append( "PubHibernate.list(nativeSQL)").append( "nativeSQL=" + nativeSQL), e); throw e; } finally { if (session != null && session.isOpen()) { session.close(); } } if (list != null) { covertNullToSpace(list); } return list; }
使用createSQLQuery进行Native SQL进行查询。
if (typeMap != null) { for (String key : typeMap.keySet()) { query.addScalar(key, typeMap.get(key)); } }
typeMap定义如下
public class SplitSummary extends PubBean { // 结算账单开始日期 private String startDate = ""; // 结算账单结束日期 private String endDate = ""; // 店铺编号 private String storeId = ""; // 订单总金额 private double orderTotalPrice = 0.00; // 商品总价 private double productTotalPrice = 0.00; // 店铺分账金额 private double storeFzPrice = 0.00; // 平台分账金额 private double shopFzPrice = 0.00; // 状态 private String status = ""; // 创建时间 private String createDate = ""; // 备注 private String note = ""; /** * nativeSQL查询时返回字段的类型 * @return */ public static Map<String, Type> getTypeMap() { Map<String, Type> map = new LinkedHashMap<String, Type>(); map.put("uuid", Hibernate.STRING); map.put("store_id", Hibernate.STRING); map.put("store_name", Hibernate.STRING); map.put("SHOP_FZ_PRICE", Hibernate.DOUBLE); map.put("STORE_FZ_PRICE", Hibernate.DOUBLE); map.put("ORDER_TOTAL_PRICE", Hibernate.DOUBLE); map.put("PRODUCT_TOTAL_PRICE", Hibernate.DOUBLE); map.put("status", Hibernate.STRING); map.put("STAR_TDATE", Hibernate.STRING); map.put("END_DATE", Hibernate.STRING); map.put("note", Hibernate.STRING); return map; } public String getStartDate() { return startDate; } public void setStartDate(String startDate) { this.startDate = startDate; } public String getEndDate() { return endDate; } public void setEndDate(String endDate) { this.endDate = endDate; } public String getStoreId() { return storeId; } public void setStoreId(String storeId) { this.storeId = storeId; } public double getOrderTotalPrice() { return orderTotalPrice; } public void setOrderTotalPrice(double orderTotalPrice) { this.orderTotalPrice = orderTotalPrice; } public double getProductTotalPrice() { return productTotalPrice; } public void setProductTotalPrice(double productTotalPrice) { this.productTotalPrice = productTotalPrice; } public double getStoreFzPrice() { return storeFzPrice; } public void setStoreFzPrice(double storeFzPrice) { this.storeFzPrice = storeFzPrice; } public double getShopFzPrice() { return shopFzPrice; } public void setShopFzPrice(double shopFzPrice) { this.shopFzPrice = shopFzPrice; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getCreateDate() { return createDate; } public void setCreateDate(String createDate) { this.createDate = createDate; } public String getNote() { return note; } public void setNote(String note) { this.note = note; } }
四、遇到的坑
3、addScalar设置返回类型时,要把查询的全部设置,否则设置几个返回几个;还要保证设置参数返回类型的顺序,查询和类型要一致,本例中采用了LinkedHashMap进行设置。
Hibernate中用left join(左外连接)查询映射中没有关联关系的两个表记录问题的更多相关文章
- SQL 左外连接查询 将右表中的多行变为左表的一列或多列
示例: --行列互转 /**************************************************************************************** ...
- oracle——外连接查询
一.问题描述 有时我们为了保留某个表中的数据,而该表中的数据在另外一个关联表中未必都存在对应,此时就应该试用外连接查询. 比如:两个表,产品表和子产品表 注:子产品的parent_product_id ...
- [原创]java WEB学习笔记91:Hibernate学习之路-- -HQL 迫切左外连接,左外连接,迫切内连接,内连接,关联级别运行时的检索策略 比较。理论,在于理解
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Hibernate迫切左外连接和迫切内连接
•迫切左外连接: •LEFT JOIN FETCH 关键字表示迫切左外连接检索策略. –list() 方法返回的集合中存放实体对象的引用, 每个 Department 对象关联的 Employee ...
- [原创]java WEB学习笔记88:Hibernate学习之路-- -Hibernate检索策略(立即检索,延迟检索,迫切左外连接检索)
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- 在查询用户的权限的时候 使用左外连接 和 access数据库中左外连接
一般做视图最好是做成左外连接的.而其作用尤其在我们查询用户当前的权限时尤为明显,我们将 权限表即模块表放→角色权限表→角色表→用户角色表→用户表 就这样left outer join 连接起来,这样就 ...
- 内连接、左外连接、右外连接、全外连接、交叉连接(CROSS JOIN)-----小知识解决大数据攻略
早就听说了内连接与外连接,以前视图中使用过.这次自考也学习了,只是简单理解,现在深入探究学习(由于上篇博客的出现)与实践: 概念 关键字: 左右连接 数据表的连接有: 1.内连接(自然连接): 只有两 ...
- Mysql数据库左外连接,右外连接,模糊查询
内连接,左外连接,右外连接都是数据库的常用连接与使用手段 内连接 select * from assets_car c inner join category c on a.id = c.id; 左外 ...
- mysql——多表——外连接查询——左连接、右连接、复合条件查询
), d_id ), name ), age ), sex ), homeadd ) ); ,,,'nan','beijing'); ,,,'nv','hunan'); ,,,'nan','jiang ...
随机推荐
- 20145322第一次JAVA实验报告
20145322第一周JAVA实验报告 课程:Java程序设计 班级:1453 指导教师:娄嘉鹏 实验名称:Java开发环境的熟悉(Linux + Eclipse) 实验日期:2016.04.08 实 ...
- Dancing Links DLX
Dancing Links DLX Dancing Links 用来解精准覆盖问题. 精准覆盖问题有两种版本. 精准覆盖 : 给一个01矩阵,如何选出若干行,使得每列都有且仅有一个1. 可以求最少行数 ...
- 使用阿里云ECS安装HDFS的小问题
毕设涉及HDFS,理论看的感觉差不多了,想搭起来测试一下性能来验证以便进行开题报告,万万没想到装HDFS花费了许多天,踩了许多坑,记录一下. 背景:使用两台阿里云学生机ECS,分处不同账号不同区域,一 ...
- css hover dropdown
html-------------------------- <div class="dropdown"> <span>鼠标移动到我这!</span& ...
- mysql字符编码的设置以及mysql中文乱码的解决方法
查看字符编码 首先,将中文插入到数据库乱码是因为没有将数据库编码设置为支持中文的编码,mysql的默认编码是Latin1,不支持中文,应该设置为utf8查看自己的数据库编码是否已设置好,进入数据库,输 ...
- 使用iview--1
在任意一个你想创建项目的路径下 每次输入就输一致的就可以 /*************************安装选项开始****************/ 回车再次回车就如下,输入Y 继续 回车,输 ...
- yii2打印数据属性(字段名)/数据
yii2打印数据属性(字段名)/数据 单条数据: $model = $this->findModel($id);//打印字段名 $array = $model->attributes(); ...
- 联表更新SQL语句
联表更新语句第一次写,,,主要是在实现功能上需要向repay_detail添加一个新的字段item_id.但是以前的老数据的话这个字段的值就为null 所以就写了下面一条语句就更新了老数据...SQL ...
- Day14 js高级部分
JS中文学习文档 http://jquery.cuishifeng.cn/ 一.函数变量的作用域: 变量的作用域是在声明时决定的而不是调用执行时决定 作用域链: 二.词法分析: 函数执行前,会进行预编 ...
- Python执行Linux系统命令方法
Python执行Linux系统命令的4种方法 (1) os.system 仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息 复制代码代码如下: system(command) -> ...