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 ...
随机推荐
- 20145240《网络对抗》Web基础
Web基础 实验后回答问题 什么是表单? 表单在网页中主要负责数据采集功能. 一个表单有三个基本组成部分: 表单标签:这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法. 表单域 ...
- Mysql 默认编码问题
新安装的数据库默认编码是 latin1 +--------------------------+----------------------------+ | Variable_name | Valu ...
- MR案例:WordCount改写
请参照wordcount实现一个自己的MapReduce,需求为: a. 输入文件格式: xxx,xxx,xxx,xxx,xxx,xxx,xxx b. 输出文件格式: ...
- 如何升级到python3版本并且安装pip3
如何升级到python3版本并且安装pip3 准备: Python-3.5.2.tar.xz pip-8.1.2.tar.gz setuptools-24.0.2.zip 步骤: 1.自定义编译安装p ...
- Servlet3.0整合Springmvc(注解版)
在创建maven的web工程时候,如果报错缺少web.xml 则在pom添加如下配置 : <build> <plugins> <plugin> <groupI ...
- OnClickListener两种监听方法
//1种:接口OnClickListener ,在onclick响应 public class MainActivity extends Activity implements OnClickList ...
- windchill10.0&11.0API_chm版百度云
windchill10.0版本和11.0版本的javadoc,也就是api 文件内容 windchill10.0.chm版本的 windchill10.0api.chm版本 百度云链接(免费推荐) 链 ...
- 字符串与byte[]之间的转换
一. 编码 同一个字符在不同的编码下会被编成不同长度的编码,比如: ACSII,每个字符对应一个字节,实际上只使用了7位,从00h-7Fh.只能表达128个字符. GB2312,中文的一种编码,每个 ...
- MySQL表类型MyISAM/InnoDB的区别(解决事务不回滚的问题)
MyISAM:这个是默认类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法.与 ...
- hdu3544找规律
如果x>1&&y>1,可以简化到其中一个为1的情况,这是等价的,当其中一个为1(假设为x),另一个一定能执行y-1次, 这是一个贪心问题,把所有的执行次数加起来比较就能得到 ...