提交 2ca2ee4f authored 作者: Thomas Mueller's avatar Thomas Mueller

JaQu improvements

上级 d2ab2e8e
...@@ -28,6 +28,10 @@ public class Customer { ...@@ -28,6 +28,10 @@ public class Customer {
this.region = region; this.region = region;
} }
public String toString() {
return customerId;
}
//## Java 1.5 begin ## //## Java 1.5 begin ##
public static List<Customer> getCustomerList() { public static List<Customer> getCustomerList() {
Customer[] list = new Customer[] { Customer[] list = new Customer[] {
......
...@@ -49,13 +49,19 @@ public class SamplesTest extends TestBase { ...@@ -49,13 +49,19 @@ public class SamplesTest extends TestBase {
db.insertAll(Product.getProductList()); db.insertAll(Product.getProductList());
db.insertAll(Customer.getCustomerList()); db.insertAll(Customer.getCustomerList());
db.insertAll(Order.getOrderList()); db.insertAll(Order.getOrderList());
// TODO MIN, MAX, LIKE, LIKE ESCAPE... // TODO nested AND/OR, >, <,...
// TODO +, -, *, /, ||, nested operations
// TODO nested AND/OR
// TODO NOT // TODO NOT
// TODO DELETE: FROM ... DELETE? // TODO +, -, *, /, ||, nested operations
// TODO LIKE ESCAPE...
// TODO UPDATE: FROM ... UPDATE? // TODO UPDATE: FROM ... UPDATE?
// TODO SELECT UNION // TODO SELECT UNION
// TODO DatabaseAdapter
// TODO user prepared statements
testOrAndNot();
testDelete();
testIsNull();
testLike();
testMinMax();
testSum(); testSum();
testLength(); testLength();
testCount(); testCount();
...@@ -84,11 +90,7 @@ public class SamplesTest extends TestBase { ...@@ -84,11 +90,7 @@ public class SamplesTest extends TestBase {
where(p.unitsInStock).is(0). where(p.unitsInStock).is(0).
orderBy(p.productId).select(); orderBy(p.productId).select();
String result = ""; assertEquals("[Chef Anton's Gumbo Mix: 0]", soldOutProducts.toString());
for (Product x : soldOutProducts) {
result += x.productName + ";";
}
assertEquals("Chef Anton's Gumbo Mix;", result);
} }
private void testWhereSimple3() throws Exception { private void testWhereSimple3() throws Exception {
...@@ -103,19 +105,11 @@ public class SamplesTest extends TestBase { ...@@ -103,19 +105,11 @@ public class SamplesTest extends TestBase {
List<Product> expensiveInStockProducts = List<Product> expensiveInStockProducts =
db.from(p). db.from(p).
where(p.unitsInStock).bigger(0). where(p.unitsInStock).bigger(0).
and(p.unitPrice).bigger(3.0). and(p.unitPrice).bigger(30.0).
orderBy(p.productId).select(); orderBy(p.productId).select();
String result = ""; assertEquals("[Northwoods Cranberry Sauce: 6, Mishi Kobe Niku: 29, Ikura: 31]",
for (Product x : expensiveInStockProducts) { expensiveInStockProducts.toString());
result += x.productName + ";";
}
assertEquals(
"Chai;Chang;Aniseed Syrup;Chef Anton's Cajun Seasoning;"
+ "Grandma's Boysenberry Spread;"
+ "Uncle Bob's Organic Dried Pears;"
+ "Northwoods Cranberry Sauce;Mishi Kobe Niku;Ikura;",
result);
} }
...@@ -132,9 +126,7 @@ public class SamplesTest extends TestBase { ...@@ -132,9 +126,7 @@ public class SamplesTest extends TestBase {
where(c.region).is("WA"). where(c.region).is("WA").
select(); select();
for (Customer cu : waCustomers) { assertEquals("[ALFKI, ANATR]", waCustomers.toString());
assertEquals("WA", cu.region);
}
} }
private void testSelectSimple2() throws Exception { private void testSelectSimple2() throws Exception {
...@@ -203,6 +195,9 @@ public class SamplesTest extends TestBase { ...@@ -203,6 +195,9 @@ public class SamplesTest extends TestBase {
public String customerId; public String customerId;
public Integer orderId; public Integer orderId;
public BigDecimal total; public BigDecimal total;
public String toString() {
return customerId + ":" + orderId + ":" + total;
}
} }
//## Java 1.5 begin ## //## Java 1.5 begin ##
...@@ -223,7 +218,7 @@ public class SamplesTest extends TestBase { ...@@ -223,7 +218,7 @@ public class SamplesTest extends TestBase {
List<CustOrder> orders = List<CustOrder> orders =
db.from(c). db.from(c).
innerJoin(o).on(c.customerId).is(o.customerId). innerJoin(o).on(c.customerId).is(o.customerId).
where(o.total).smaller(new BigDecimal("500.00")). where(o.total).smaller(new BigDecimal("100.00")).
orderBy(1). orderBy(1).
select(new CustOrder() { { select(new CustOrder() { {
customerId = c.customerId; customerId = c.customerId;
...@@ -231,18 +226,32 @@ public class SamplesTest extends TestBase { ...@@ -231,18 +226,32 @@ public class SamplesTest extends TestBase {
total = o.total; total = o.total;
}}); }});
StringBuilder buff = new StringBuilder(); assertEquals("[ANATR:10308:88.80]", orders.toString());
for (CustOrder co : orders) { }
buff.append("c:");
buff.append(co.customerId); private void testIsNull() throws Exception {
buff.append("/o:"); Product p = new Product();
buff.append(co.orderId); String sql = db.from(p).whereTrue(isNull(p.productName)).getSQL();
buff.append(';'); assertEquals("SELECT * FROM Product WHERE (productName IS NULL)", sql);
}
private void testDelete() throws Exception {
Product p = new Product();
int deleted = db.from(p).where(p.productName).like("A%").delete();
assertEquals(1, deleted);
deleted = db.from(p).delete();
assertEquals(9, deleted);
db.insertAll(Product.getProductList());
} }
String s = buff.toString();
assertEquals("c:ALFKI/o:10702;c:ALFKI/o:10952;c:ANATR/o:10308;" + private void testOrAndNot() throws Exception {
"c:ANATR/o:10625;c:ANATR/o:10759;c:ANTON/o:10355;" + Product p = new Product();
"c:ANTON/o:10365;c:ANTON/o:10682;", s); String sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL();
assertEquals("SELECT * FROM Product WHERE (NOT productName IS NULL)", sql);
sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL();
assertEquals("SELECT * FROM Product WHERE (NOT productName IS NULL)", sql);
sql = db.from(p).whereTrue(db.test(p.productId).is(1)).getSQL();
assertEquals("SELECT * FROM Product WHERE ((productId = 1))", sql);
} }
private void testLength() throws Exception { private void testLength() throws Exception {
...@@ -251,24 +260,40 @@ public class SamplesTest extends TestBase { ...@@ -251,24 +260,40 @@ public class SamplesTest extends TestBase {
where(length(p.productName)).smaller(10). where(length(p.productName)).smaller(10).
orderBy(1). orderBy(1).
selectDistinct(length(p.productName)); selectDistinct(length(p.productName));
String s = lengths.toString(); assertEquals("[4, 5]", lengths.toString());
assertEquals("[4, 5]", s);
} }
private void testSum() throws Exception { private void testSum() throws Exception {
Product p = new Product(); Product p = new Product();
Integer sum = db.from(p). Integer sum = db.from(p).selectFirst(sum(p.unitsInStock));
selectFirst(sum(p.unitsInStock));
assertEquals(323, sum.intValue()); assertEquals(323, sum.intValue());
Double sumPrice = db.from(p). Double sumPrice = db.from(p).selectFirst(sum(p.unitPrice));
selectFirst(sum(p.unitPrice));
assertEquals(313.35, sumPrice.doubleValue()); assertEquals(313.35, sumPrice.doubleValue());
} }
private void testMinMax() throws Exception {
Product p = new Product();
Integer min = db.from(p).selectFirst(min(p.unitsInStock));
assertEquals(0, min.intValue());
String minName = db.from(p).selectFirst(min(p.productName));
assertEquals("Aniseed Syrup", minName);
Double max = db.from(p).selectFirst(max(p.unitPrice));
assertEquals(97.0, max.doubleValue());
}
private void testLike() throws Exception {
Product p = new Product();
List<Product> aList = db.from(p).
where(p.productName).like("Cha%").
orderBy(p.productName).select();
assertEquals("[Chai: 39, Chang: 17]", aList.toString());
}
private void testCount() throws Exception { private void testCount() throws Exception {
long count = db.from(new Product()).selectCount(); long count = db.from(new Product()).selectCount();
assertEquals(10, count); assertEquals(10, count);
} }
//## Java 1.5 end ## //## Java 1.5 end ##
/** /**
...@@ -277,6 +302,9 @@ public class SamplesTest extends TestBase { ...@@ -277,6 +302,9 @@ public class SamplesTest extends TestBase {
public static class ProductGroup { public static class ProductGroup {
public String category; public String category;
public Long productCount; public Long productCount;
public String toString() {
return category + ":" + productCount;
}
} }
//## Java 1.5 begin ## //## Java 1.5 begin ##
...@@ -300,16 +328,8 @@ public class SamplesTest extends TestBase { ...@@ -300,16 +328,8 @@ public class SamplesTest extends TestBase {
productCount = count(); productCount = count();
}}); }});
StringBuilder buff = new StringBuilder(); assertEquals("[Beverages:2, Condiments:5, Meat/Poultry:1, Produce:1, Seafood:1]",
for (ProductGroup og: list) { list.toString());
buff.append(og.category);
buff.append("=");
buff.append(og.productCount);
buff.append(';');
}
String s = buff.toString();
assertEquals("Beverages=2;Condiments=5;Meat/Poultry=1;" +
"Produce=1;Seafood=1;", s);
} }
//## Java 1.5 end ## //## Java 1.5 end ##
......
...@@ -26,9 +26,9 @@ class Condition<A> implements Token { ...@@ -26,9 +26,9 @@ class Condition<A> implements Token {
public String getString(Query query) { public String getString(Query query) {
if (compareType.hasRightExpression()) { if (compareType.hasRightExpression()) {
return query.getString(x) + compareType.getString() + query.getString(y); return query.getString(x) + " " + compareType.getString() + " " + query.getString(y);
} }
return query.getString(x) + compareType.getString(); return query.getString(x) + " " + compareType.getString();
} }
} }
//## Java 1.5 end ## //## Java 1.5 end ##
...@@ -106,14 +106,6 @@ public class Db { ...@@ -106,14 +106,6 @@ public class Db {
return def; return def;
} }
// private <T> T alias(Class<T> clazz) {
// TableDefinition def = define(clazz);
// T alias = instance(clazz);
// SelectTable table = new SelectTable(this, null, alias, false);
// def.initSelectObject(table, alias, aliasMap);
// return alias;
// }
public void close() { public void close() {
try { try {
conn.close(); conn.close();
...@@ -122,6 +114,10 @@ public class Db { ...@@ -122,6 +114,10 @@ public class Db {
} }
} }
public <A> TestCondition<A> test(A x) {
return new TestCondition<A>(x);
}
public <T> void insertAll(List<T> list) { public <T> void insertAll(List<T> list) {
for (T t : list) { for (T t : list) {
insert(t); insert(t);
...@@ -156,6 +152,14 @@ public class Db { ...@@ -156,6 +152,14 @@ public class Db {
} }
} }
int executeUpdate(String sql) {
try {
return conn.createStatement().executeUpdate(sql);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
// <X> FieldDefinition<X> getFieldDefinition(X x) { // <X> FieldDefinition<X> getFieldDefinition(X x) {
// return aliasMap.get(x).getFieldDefinition(); // return aliasMap.get(x).getFieldDefinition();
// } // }
......
...@@ -18,16 +18,25 @@ public class Function implements Token { ...@@ -18,16 +18,25 @@ public class Function implements Token {
private static final Long COUNT_STAR = new Long(0); private static final Long COUNT_STAR = new Long(0);
protected Object[] x;
private String name; private String name;
private Object x;
private Function(String name, Object x) { protected Function(String name, Object... x) {
this.name = name; this.name = name;
this.x = x; this.x = x;
} }
public String getString(Query query) { public String getString(Query query) {
return name + "(" + query.getString(x) + ")"; StringBuilder buff = new StringBuilder();
buff.append(name).append('(');
for (int i = 0; i < x.length; i++) {
if (i > 0) {
buff.append(',');
}
buff.append(query.getString(x[i]));
}
buff.append(')');
return buff.toString();
} }
public static Long count() { public static Long count() {
...@@ -49,6 +58,63 @@ public class Function implements Token { ...@@ -49,6 +58,63 @@ public class Function implements Token {
Utils.newObject(Long.class), new Function("COUNT", x)); Utils.newObject(Long.class), new Function("COUNT", x));
} }
public static Boolean isNull(Object x) {
return Db.registerToken(
Utils.newObject(Boolean.class), new Function("", x) {
public String getString(Query query) {
return query.getString(x[0]) + " IS NULL";
}
});
}
public static Boolean isNotNull(Object x) {
return Db.registerToken(
Utils.newObject(Boolean.class), new Function("", x) {
public String getString(Query query) {
return query.getString(x[0]) + " IS NOT NULL";
}
});
}
public static Boolean not(Boolean x) {
return Db.registerToken(
Utils.newObject(Boolean.class), new Function("", x) {
public String getString(Query query) {
return "NOT " + query.getString(x[0]);
}
});
}
public static Boolean or(Boolean... x) {
return Db.registerToken(Utils.newObject(Boolean.class), new Function("", (Object[]) x) {
public String getString(Query query) {
StringBuilder buff = new StringBuilder();
for (int i = 0; i < x.length; i++) {
if (i > 0) {
buff.append(" OR ");
}
buff.append(query.getString(x[i]));
}
return buff.toString();
}
});
}
public static Boolean and(Boolean... x) {
return Db.registerToken(Utils.newObject(Boolean.class), new Function("", (Object[]) x) {
public String getString(Query query) {
StringBuilder buff = new StringBuilder();
for (int i = 0; i < x.length; i++) {
if (i > 0) {
buff.append(" AND ");
}
buff.append(query.getString(x[i]));
}
return buff.toString();
}
});
}
public static <X> X min(X x) { public static <X> X min(X x) {
Class<X> clazz = (Class<X>) x.getClass(); Class<X> clazz = (Class<X>) x.getClass();
X o = Utils.newObject(clazz); X o = Utils.newObject(clazz);
...@@ -61,5 +127,14 @@ public class Function implements Token { ...@@ -61,5 +127,14 @@ public class Function implements Token {
return Db.registerToken(o, new Function("MAX", x)); return Db.registerToken(o, new Function("MAX", x));
} }
public static Boolean like(String x, String pattern) {
Boolean o = Utils.newObject(Boolean.class);
return Db.registerToken(o, new Function("LIKE", x, pattern) {
public String getString(Query query) {
return "(" + query.getString(x[0]) + " LIKE " + query.getString(x[1]) + ")";
}
});
}
//## Java 1.5 end ## //## Java 1.5 end ##
} }
...@@ -68,6 +68,10 @@ public class Query<T> { ...@@ -68,6 +68,10 @@ public class Query<T> {
return list.isEmpty() ? null : list.get(0); return list.isEmpty() ? null : list.get(0);
} }
public String getSQL() {
return getSQL("*", false).trim();
}
private List<T> select(boolean distinct) { private List<T> select(boolean distinct) {
List<T> result = Utils.newArrayList(); List<T> result = Utils.newArrayList();
ResultSet rs = db.executeQuery(getSQL("*", distinct)); ResultSet rs = db.executeQuery(getSQL("*", distinct));
...@@ -83,6 +87,15 @@ public class Query<T> { ...@@ -83,6 +87,15 @@ public class Query<T> {
return result; return result;
} }
public int delete() {
StringBuilder buff = new StringBuilder();
buff.append("DELETE FROM ");
buff.append(from.getString());
buff.append(getSQLWhere());
String sql = buff.toString();
return db.executeUpdate(sql);
}
public <X, Z> List<X> selectDistinct(Z x) { public <X, Z> List<X> selectDistinct(Z x) {
return select(x, true); return select(x, true);
} }
...@@ -139,6 +152,12 @@ public class Query<T> { ...@@ -139,6 +152,12 @@ public class Query<T> {
public <A> QueryCondition<T, A> where(A x) { public <A> QueryCondition<T, A> where(A x) {
return new QueryCondition<T, A>(this, x); return new QueryCondition<T, A>(this, x);
} }
public QueryWhere<T> whereTrue(Boolean condition) {
Token token = new Function("", condition);
addConditionToken(token);
return new QueryWhere<T>(this);
}
//## Java 1.5 end ## //## Java 1.5 end ##
/** /**
...@@ -188,6 +207,18 @@ public class Query<T> { ...@@ -188,6 +207,18 @@ public class Query<T> {
conditions.add(condition); conditions.add(condition);
} }
String getSQLWhere() {
StringBuilder buff = new StringBuilder("");
if (!conditions.isEmpty()) {
buff.append(" WHERE ");
for (Token token : conditions) {
buff.append(token.getString(this));
buff.append(' ');
}
}
return buff.toString();
}
String getSQL(String selectList, boolean distinct) { String getSQL(String selectList, boolean distinct) {
StringBuilder buff = new StringBuilder("SELECT "); StringBuilder buff = new StringBuilder("SELECT ");
if (distinct) { if (distinct) {
...@@ -199,13 +230,7 @@ public class Query<T> { ...@@ -199,13 +230,7 @@ public class Query<T> {
for (SelectTable join : joins) { for (SelectTable join : joins) {
buff.append(join.getStringAsJoin(this)); buff.append(join.getStringAsJoin(this));
} }
if (!conditions.isEmpty()) { buff.append(getSQLWhere());
buff.append(" WHERE ");
for (Token token : conditions) {
buff.append(token.getString(this));
buff.append(' ');
}
}
if (groupByExpressions != null) { if (groupByExpressions != null) {
buff.append(" GROUP BY "); buff.append(" GROUP BY ");
for (int i = 0; i < groupByExpressions.length; i++) { for (int i = 0; i < groupByExpressions.length; i++) {
......
...@@ -33,10 +33,25 @@ public class QueryCondition<T, A> { ...@@ -33,10 +33,25 @@ public class QueryCondition<T, A> {
return new QueryWhere<T>(query); return new QueryWhere<T>(query);
} }
public QueryWhere<T> biggerEqual(A y) {
query.addConditionToken(new Condition<A>(query, x, y, CompareType.BIGGER_EQUAL));
return new QueryWhere<T>(query);
}
public QueryWhere<T> smaller(A y) { public QueryWhere<T> smaller(A y) {
query.addConditionToken(new Condition<A>(query, x, y, CompareType.SMALLER)); query.addConditionToken(new Condition<A>(query, x, y, CompareType.SMALLER));
return new QueryWhere<T>(query); return new QueryWhere<T>(query);
} }
public QueryWhere<T> smallerEqual(A y) {
query.addConditionToken(new Condition<A>(query, x, y, CompareType.SMALLER_EQUAL));
return new QueryWhere<T>(query);
}
public QueryWhere<T> like(A pattern) {
query.addConditionToken(new Condition<A>(query, x, pattern, CompareType.LIKE));
return new QueryWhere<T>(query);
}
} }
//## Java 1.5 end ## //## Java 1.5 end ##
...@@ -38,6 +38,10 @@ public class QueryWhere<T> { ...@@ -38,6 +38,10 @@ public class QueryWhere<T> {
return (List<X>) query.select(x); return (List<X>) query.select(x);
} }
public String getSQL() {
return query.getSQL("*", false).trim();
}
public <X, Z> List<X> selectDistinct(Z x) { public <X, Z> List<X> selectDistinct(Z x) {
return (List<X>) query.selectDistinct(x); return (List<X>) query.selectDistinct(x);
} }
...@@ -108,5 +112,9 @@ public class QueryWhere<T> { ...@@ -108,5 +112,9 @@ public class QueryWhere<T> {
return this; return this;
} }
public int delete() {
return query.delete();
}
} }
//## Java 1.5 end ## //## Java 1.5 end ##
...@@ -68,7 +68,7 @@ public class Utils { ...@@ -68,7 +68,7 @@ public class Utils {
} else if (clazz == Double.class) { } else if (clazz == Double.class) {
return (T) new Double(counter++); return (T) new Double(counter++);
} else if (clazz == Boolean.class) { } else if (clazz == Boolean.class) {
return (T) Boolean.FALSE; return (T) new Boolean(false);
} else if (clazz == BigDecimal.class) { } else if (clazz == BigDecimal.class) {
return (T) new BigDecimal(counter++); return (T) new BigDecimal(counter++);
} else if (clazz == BigInteger.class) { } else if (clazz == BigInteger.class) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论