mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-24 23:56:36 +00:00
Fix for #224 - ENH: Add tableAliasMapping() to RawSqlBuilder ... for better mapping of complex objects with raw sql
This commit is contained in:
@@ -2,12 +2,7 @@ package com.avaje.ebean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import com.avaje.ebean.util.CamelCaseHelper;
|
||||
|
||||
@@ -541,6 +536,22 @@ public final class RawSql implements Serializable {
|
||||
return dbColumnMap.values().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify any column mappings with the given table alias to have the path prefix.
|
||||
* <p>
|
||||
* For example modify all mappings with table alias "c" to have the path prefix "customer".
|
||||
* </p>
|
||||
*/
|
||||
public void tableAliasMapping(String tableAlias, String path) {
|
||||
|
||||
String startMatch = tableAlias+".";
|
||||
for (Map.Entry<String, Column> entry : dbColumnMap.entrySet()) {
|
||||
if (entry.getKey().startsWith(startMatch)) {
|
||||
entry.getValue().tableAliasMapping(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Column of the RawSql that is mapped to a bean property (or ignored).
|
||||
*/
|
||||
@@ -622,10 +633,23 @@ public final class RawSql implements Serializable {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the property name mapped to this db column.
|
||||
*/
|
||||
private void setPropertyName(String propertyName) {
|
||||
this.propertyName = propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepend the path to the property name.
|
||||
* <p/>
|
||||
* For example if path is "customer" then "name" becomes "customer.name".
|
||||
*/
|
||||
public void tableAliasMapping(String path) {
|
||||
if (path != null) {
|
||||
propertyName = path + "." + propertyName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,17 @@ public class RawSqlBuilder {
|
||||
return columnMapping(dbColumn, IGNORE_COLUMN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify any column mappings with the given table alias to have the path prefix.
|
||||
* <p>
|
||||
* For example modify all mappings with table alias "c" to have the path prefix "customer".
|
||||
* </p>
|
||||
*/
|
||||
public RawSqlBuilder tableAliasMapping(String tableAlias, String path) {
|
||||
columnMapping.tableAliasMapping(tableAlias, path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the immutable RawSql object. Do this after all the column mapping
|
||||
* has been defined.
|
||||
@@ -122,6 +133,7 @@ public class RawSqlBuilder {
|
||||
protected Sql getSql() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import org.junit.Test;
|
||||
|
||||
import com.avaje.ebean.RawSql.Sql;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TestRawSqlBuilder extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
@@ -12,9 +14,9 @@ public class TestRawSqlBuilder extends BaseTestCase {
|
||||
|
||||
RawSqlBuilder r = RawSqlBuilder.parse("select id from t_cust");
|
||||
Sql sql = r.getSql();
|
||||
Assert.assertEquals("id", sql.getPreFrom());
|
||||
Assert.assertEquals("from t_cust", sql.getPreWhere());
|
||||
Assert.assertEquals("", sql.getPreHaving());
|
||||
assertEquals("id", sql.getPreFrom());
|
||||
assertEquals("from t_cust", sql.getPreWhere());
|
||||
assertEquals("", sql.getPreHaving());
|
||||
Assert.assertNull(sql.getOrderBy());
|
||||
|
||||
}
|
||||
@@ -24,9 +26,9 @@ public class TestRawSqlBuilder extends BaseTestCase {
|
||||
|
||||
RawSqlBuilder r = RawSqlBuilder.parse("select id from t_cust where id > ?");
|
||||
Sql sql = r.getSql();
|
||||
Assert.assertEquals("id", sql.getPreFrom());
|
||||
Assert.assertEquals("from t_cust where id > ?", sql.getPreWhere());
|
||||
Assert.assertEquals("", sql.getPreHaving());
|
||||
assertEquals("id", sql.getPreFrom());
|
||||
assertEquals("from t_cust where id > ?", sql.getPreWhere());
|
||||
assertEquals("", sql.getPreHaving());
|
||||
Assert.assertNull(sql.getOrderBy());
|
||||
}
|
||||
|
||||
@@ -35,26 +37,26 @@ public class TestRawSqlBuilder extends BaseTestCase {
|
||||
|
||||
RawSqlBuilder r = RawSqlBuilder.parse("select id from t_cust where id > ? order by id desc");
|
||||
Sql sql = r.getSql();
|
||||
Assert.assertEquals("id", sql.getPreFrom());
|
||||
Assert.assertEquals("from t_cust where id > ?", sql.getPreWhere());
|
||||
Assert.assertEquals("", sql.getPreHaving());
|
||||
Assert.assertEquals("order by", sql.getOrderByPrefix());
|
||||
Assert.assertEquals("id desc", sql.getOrderBy());
|
||||
assertEquals("id", sql.getPreFrom());
|
||||
assertEquals("from t_cust where id > ?", sql.getPreWhere());
|
||||
assertEquals("", sql.getPreHaving());
|
||||
assertEquals("order by", sql.getOrderByPrefix());
|
||||
assertEquals("id desc", sql.getOrderBy());
|
||||
|
||||
r = RawSqlBuilder.parse("select id from t_cust order by id desc");
|
||||
sql = r.getSql();
|
||||
Assert.assertEquals("id", sql.getPreFrom());
|
||||
Assert.assertEquals("from t_cust", sql.getPreWhere());
|
||||
Assert.assertEquals("", sql.getPreHaving());
|
||||
Assert.assertEquals("id desc", sql.getOrderBy());
|
||||
assertEquals("id", sql.getPreFrom());
|
||||
assertEquals("from t_cust", sql.getPreWhere());
|
||||
assertEquals("", sql.getPreHaving());
|
||||
assertEquals("id desc", sql.getOrderBy());
|
||||
|
||||
r = RawSqlBuilder
|
||||
.parse("select id, sum(x) from t_cust where id > ? group by id order by id desc");
|
||||
sql = r.getSql();
|
||||
Assert.assertEquals("id, sum(x)", sql.getPreFrom());
|
||||
Assert.assertEquals("from t_cust where id > ?", sql.getPreWhere());
|
||||
Assert.assertEquals("group by id", sql.getPreHaving());
|
||||
Assert.assertEquals("id desc", sql.getOrderBy());
|
||||
assertEquals("id, sum(x)", sql.getPreFrom());
|
||||
assertEquals("from t_cust where id > ?", sql.getPreWhere());
|
||||
assertEquals("group by id", sql.getPreHaving());
|
||||
assertEquals("id desc", sql.getOrderBy());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -63,40 +65,40 @@ public class TestRawSqlBuilder extends BaseTestCase {
|
||||
RawSqlBuilder r = RawSqlBuilder
|
||||
.parse("select id, sum(x) from t_cust where id > ? group by id having sum(x) > ? order by id desc");
|
||||
Sql sql = r.getSql();
|
||||
Assert.assertEquals("id, sum(x)", sql.getPreFrom());
|
||||
Assert.assertEquals("from t_cust where id > ?", sql.getPreWhere());
|
||||
Assert.assertEquals("group by id having sum(x) > ?", sql.getPreHaving());
|
||||
Assert.assertEquals("order by", sql.getOrderByPrefix());
|
||||
Assert.assertEquals("id desc", sql.getOrderBy());
|
||||
assertEquals("id, sum(x)", sql.getPreFrom());
|
||||
assertEquals("from t_cust where id > ?", sql.getPreWhere());
|
||||
assertEquals("group by id having sum(x) > ?", sql.getPreHaving());
|
||||
assertEquals("order by", sql.getOrderByPrefix());
|
||||
assertEquals("id desc", sql.getOrderBy());
|
||||
|
||||
// no where
|
||||
r = RawSqlBuilder
|
||||
.parse("select id, sum(x) from t_cust group by id having sum(x) > ? order by id desc");
|
||||
sql = r.getSql();
|
||||
Assert.assertEquals("id, sum(x)", sql.getPreFrom());
|
||||
Assert.assertEquals("from t_cust", sql.getPreWhere());
|
||||
Assert.assertEquals("group by id having sum(x) > ?", sql.getPreHaving());
|
||||
Assert.assertEquals("order by", sql.getOrderByPrefix());
|
||||
Assert.assertEquals("id desc", sql.getOrderBy());
|
||||
assertEquals("id, sum(x)", sql.getPreFrom());
|
||||
assertEquals("from t_cust", sql.getPreWhere());
|
||||
assertEquals("group by id having sum(x) > ?", sql.getPreHaving());
|
||||
assertEquals("order by", sql.getOrderByPrefix());
|
||||
assertEquals("id desc", sql.getOrderBy());
|
||||
|
||||
// no where, no order by
|
||||
r = RawSqlBuilder.parse("select id, sum(x) from t_cust group by id having sum(x) > ?");
|
||||
sql = r.getSql();
|
||||
Assert.assertEquals("id, sum(x)", sql.getPreFrom());
|
||||
Assert.assertEquals("from t_cust", sql.getPreWhere());
|
||||
Assert.assertEquals("group by id having sum(x) > ?", sql.getPreHaving());
|
||||
assertEquals("id, sum(x)", sql.getPreFrom());
|
||||
assertEquals("from t_cust", sql.getPreWhere());
|
||||
assertEquals("group by id having sum(x) > ?", sql.getPreHaving());
|
||||
Assert.assertNull(sql.getOrderBy());
|
||||
Assert.assertEquals("order by", sql.getOrderByPrefix());
|
||||
assertEquals("order by", sql.getOrderByPrefix());
|
||||
|
||||
// no order by
|
||||
r = RawSqlBuilder
|
||||
.parse("select id, sum(x) from t_cust where id > ? group by id having sum(x) > ?");
|
||||
sql = r.getSql();
|
||||
Assert.assertEquals("id, sum(x)", sql.getPreFrom());
|
||||
Assert.assertEquals("from t_cust where id > ?", sql.getPreWhere());
|
||||
Assert.assertEquals("group by id having sum(x) > ?", sql.getPreHaving());
|
||||
assertEquals("id, sum(x)", sql.getPreFrom());
|
||||
assertEquals("from t_cust where id > ?", sql.getPreWhere());
|
||||
assertEquals("group by id having sum(x) > ?", sql.getPreHaving());
|
||||
Assert.assertNull(sql.getOrderBy());
|
||||
Assert.assertEquals("order by", sql.getOrderByPrefix());
|
||||
assertEquals("order by", sql.getOrderByPrefix());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,10 +112,43 @@ public class TestRawSqlBuilder extends BaseTestCase {
|
||||
RawSql rawSql = RawSqlBuilder.parse(s).create();
|
||||
|
||||
Sql sql = rawSql.getSql();
|
||||
Assert.assertEquals("ID, DESCRIPTION, NAME, PARENT_ID", sql.getPreFrom());
|
||||
Assert.assertEquals("order siblings by", sql.getOrderByPrefix());
|
||||
Assert.assertEquals("NAME", sql.getOrderBy());
|
||||
Assert.assertEquals("FROM SOME_TABLE WHERE lower(NAME) like :name START WITH ID = :parentId CONNECT BY PRIOR ID = PARENT_ID", sql.getPreWhere());
|
||||
assertEquals("ID, DESCRIPTION, NAME, PARENT_ID", sql.getPreFrom());
|
||||
assertEquals("order siblings by", sql.getOrderByPrefix());
|
||||
assertEquals("NAME", sql.getOrderBy());
|
||||
assertEquals("FROM SOME_TABLE WHERE lower(NAME) like :name START WITH ID = :parentId CONNECT BY PRIOR ID = PARENT_ID", sql.getPreWhere());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testWithAlias() {
|
||||
|
||||
String rs = "select o.id, o.status, c.id, c.name, "+
|
||||
" d.id, d.order_qty, p.id, p.name " +
|
||||
"from o_order o join o_customer c on c.id = o.kcustomer_id " +
|
||||
"join o_order_detail d on d.order_id = o.id " +
|
||||
"join o_product p on p.id = d.product_id " +
|
||||
"where o.id <= :maxOrderId and p.id = :productId "+
|
||||
"order by o.id, d.id asc";
|
||||
|
||||
|
||||
RawSql rawSql = RawSqlBuilder.parse(rs)
|
||||
.tableAliasMapping("c", "customer")
|
||||
.tableAliasMapping("d", "details")
|
||||
.tableAliasMapping("p", "details.product")
|
||||
.create();
|
||||
|
||||
RawSql.ColumnMapping columnMapping = rawSql.getColumnMapping();
|
||||
assertEquals(0, columnMapping.getIndexPosition("id"));
|
||||
assertEquals(1, columnMapping.getIndexPosition("status"));
|
||||
assertEquals(2, columnMapping.getIndexPosition("customer.id"));
|
||||
assertEquals(3, columnMapping.getIndexPosition("customer.name"));
|
||||
assertEquals(4, columnMapping.getIndexPosition("details.id"));
|
||||
assertEquals(5, columnMapping.getIndexPosition("details.orderQty"));
|
||||
assertEquals(6, columnMapping.getIndexPosition("details.product.id"));
|
||||
assertEquals(7, columnMapping.getIndexPosition("details.product.name"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,6 +47,64 @@ public class TestRawSqlMasterDetail extends BaseTestCase {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithTableAliasMapping() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
String rs = "select o.id, o.status, c.id, c.name, "+
|
||||
" d.id, d.order_qty, p.id, p.name " +
|
||||
"from o_order o join o_customer c on c.id = o.kcustomer_id " +
|
||||
"join o_order_detail d on d.order_id = o.id " +
|
||||
"join o_product p on p.id = d.product_id " +
|
||||
"where o.id <= :maxOrderId and p.id = :productId "+
|
||||
"order by o.id, d.id asc";
|
||||
|
||||
|
||||
RawSql rawSql = RawSqlBuilder.parse(rs)
|
||||
.tableAliasMapping("c", "customer")
|
||||
.tableAliasMapping("d", "details")
|
||||
.tableAliasMapping("p", "details.product")
|
||||
.create();
|
||||
|
||||
List<Order> ordersFromRaw = Ebean.find(Order.class)
|
||||
.setRawSql(rawSql)
|
||||
.setParameter("maxOrderId", 2)
|
||||
.setParameter("productId", 1)
|
||||
.findList();
|
||||
|
||||
printOrders(ordersFromRaw, "using RawSql with tableAlias mapping");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testWithMultipleManys() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
String rs = "select o.id, o.status, c.id, c.name, "+
|
||||
" d.id, d.order_qty, p.id, p.name " +
|
||||
"from o_order o join o_customer c on c.id = o.kcustomer_id " +
|
||||
"join o_order_detail d on d.order_id = o.id " +
|
||||
"join o_product p on p.id = d.product_id " +
|
||||
"order by o.id, d.id asc";
|
||||
|
||||
|
||||
RawSql rawSql = RawSqlBuilder.parse(rs)
|
||||
.tableAliasMapping("c", "customer")
|
||||
.tableAliasMapping("d", "details")
|
||||
.tableAliasMapping("p", "details.product")
|
||||
.create();
|
||||
|
||||
List<Order> ordersFromRaw = Ebean.find(Order.class)
|
||||
.setRawSql(rawSql)
|
||||
.findList();
|
||||
|
||||
printOrders(ordersFromRaw, "using RawSql with tableAlias mapping");
|
||||
|
||||
}
|
||||
|
||||
private void printOrders(List<Order> orders, String heading) {
|
||||
System.out.println("-------------- "+heading);
|
||||
for (Order order : orders) {
|
||||
|
||||
Reference in New Issue
Block a user