mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
bug fixed for mapping
This commit is contained in:
@@ -98,6 +98,7 @@ public class MappingEngine {
|
||||
|
||||
MappingVisitor visitor = this.createMappingVisitor(parameters);
|
||||
query.accept(visitor);
|
||||
visitor.afterResolve();
|
||||
afterResole(visitor);
|
||||
|
||||
return toSQL(query);
|
||||
@@ -116,6 +117,7 @@ public class MappingEngine {
|
||||
|
||||
MappingVisitor visitor = this.createMappingVisitor(Collections.emptyList());
|
||||
stmt.accept(visitor);
|
||||
visitor.afterResolve();
|
||||
afterResole(visitor);
|
||||
|
||||
return toSQL(stmt);
|
||||
@@ -138,6 +140,7 @@ public class MappingEngine {
|
||||
|
||||
MappingVisitor visitor = this.createMappingVisitor(Collections.emptyList());
|
||||
stmt.accept(visitor);
|
||||
visitor.afterResolve();
|
||||
afterResole(visitor);
|
||||
|
||||
return toSQL(stmt);
|
||||
@@ -152,6 +155,7 @@ public class MappingEngine {
|
||||
|
||||
MappingVisitor visitor = this.createMappingVisitor(Collections.emptyList());
|
||||
stmt.accept(visitor);
|
||||
visitor.afterResolve();
|
||||
afterResole(visitor);
|
||||
|
||||
return toSQL(stmt);
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.Map;
|
||||
import com.alibaba.druid.mapping.Entity;
|
||||
import com.alibaba.druid.mapping.MappingEngine;
|
||||
import com.alibaba.druid.mapping.Property;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
@@ -30,6 +31,7 @@ public class MSSQLServerMappingVisitor extends SQLServerASTVisitorAdapter implem
|
||||
private final List<Object> parameters;
|
||||
private final List<PropertyValue> propertyValues = new ArrayList<PropertyValue>();
|
||||
private int variantIndex = 0;
|
||||
private final List<SQLExpr> unresolveList = new ArrayList<SQLExpr>();
|
||||
|
||||
public MSSQLServerMappingVisitor(MappingEngine engine){
|
||||
this(engine, Collections.emptyList());
|
||||
@@ -81,8 +83,7 @@ public class MSSQLServerMappingVisitor extends SQLServerASTVisitorAdapter implem
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLSelectItem x) {
|
||||
x.getExpr().setParent(x);
|
||||
return true;
|
||||
return MappingVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -129,13 +130,23 @@ public class MSSQLServerMappingVisitor extends SQLServerASTVisitorAdapter implem
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
return MappingVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getAndIncrementVariantIndex() {
|
||||
return variantIndex++;
|
||||
}
|
||||
|
||||
|
||||
public int getVariantIndex() {
|
||||
return variantIndex;
|
||||
}
|
||||
|
||||
public List<SQLExpr> getUnresolveList() {
|
||||
return unresolveList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterResolve() {
|
||||
MappingVisitorUtils.afterResolve(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.Map;
|
||||
import com.alibaba.druid.mapping.Entity;
|
||||
import com.alibaba.druid.mapping.MappingEngine;
|
||||
import com.alibaba.druid.mapping.Property;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
@@ -29,4 +30,8 @@ public interface MappingVisitor extends SQLASTVisitor {
|
||||
List<PropertyValue> getPropertyValues();
|
||||
|
||||
int getAndIncrementVariantIndex();
|
||||
|
||||
List<SQLExpr> getUnresolveList();
|
||||
|
||||
void afterResolve();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.alibaba.druid.mapping.spi;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.mapping.DruidMappingException;
|
||||
@@ -74,6 +75,11 @@ public class MappingVisitorUtils {
|
||||
|
||||
Property property = null;
|
||||
Entity entity = visitor.getEntity(ownerName);
|
||||
|
||||
if (entity == null) {
|
||||
visitor.getUnresolveList().add(x);
|
||||
return false;
|
||||
}
|
||||
property = entity.getProperty(propertyName);
|
||||
|
||||
if (property == null) {
|
||||
@@ -100,16 +106,21 @@ public class MappingVisitorUtils {
|
||||
|
||||
Property property = null;
|
||||
Entity propertyEntity = null;
|
||||
for (Entity entity : visitor.getEntities().values()) {
|
||||
property = entity.getProperty(propertyName);
|
||||
if (property != null) {
|
||||
propertyEntity = entity;
|
||||
break;
|
||||
|
||||
for (SQLTableSource tableSource : visitor.getTableSources().values()) {
|
||||
Entity entity = (Entity) tableSource.getAttribute("mapping.entity");
|
||||
if (entity != null) {
|
||||
property = entity.getProperty(propertyName);
|
||||
if (property != null) {
|
||||
propertyEntity = entity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (property == null) {
|
||||
throw new DruidMappingException("property not found : " + propertyName);
|
||||
visitor.getUnresolveList().add(x);
|
||||
return false;
|
||||
}
|
||||
|
||||
String dbColumName = visitor.resovleColumnName(propertyEntity, property);
|
||||
@@ -128,6 +139,11 @@ public class MappingVisitorUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean visit(MappingVisitor visitor, SQLSelectItem x) {
|
||||
x.getExpr().setParent(x);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean visit(MappingVisitor visitor, SQLBinaryOpExpr x) {
|
||||
if (x.getOperator() == SQLBinaryOperator.Equality) {
|
||||
if (x.getLeft() instanceof SQLIdentifierExpr && isSimpleValue(visitor, x.getRight())) {
|
||||
@@ -190,6 +206,71 @@ public class MappingVisitorUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void afterResolve(MappingVisitor visitor) {
|
||||
for (Iterator<SQLExpr> iter = visitor.getUnresolveList().iterator();iter.hasNext();) {
|
||||
SQLExpr expr = iter.next();
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
if (resolve(visitor, (SQLIdentifierExpr) expr)) {
|
||||
iter.remove();
|
||||
}
|
||||
} else if (expr instanceof SQLPropertyExpr) {
|
||||
if (resolve(visitor, (SQLPropertyExpr) expr)) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean resolve(MappingVisitor visitor, SQLIdentifierExpr x) {
|
||||
String propertyName = x.getName();
|
||||
|
||||
for (SQLTableSource tableSource : visitor.getTableSources().values()) {
|
||||
Entity entity = (Entity) tableSource.getAttribute("mapping.entity");
|
||||
if (entity != null) {
|
||||
Property property = entity.getProperty(propertyName);
|
||||
if (property != null) {
|
||||
String columnName = visitor.resovleColumnName(entity, property);
|
||||
x.setName(columnName);
|
||||
|
||||
x.putAttribute("mapping.entity", entity);
|
||||
x.putAttribute("mapping.property", property);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean resolve(MappingVisitor visitor, SQLPropertyExpr x) {
|
||||
if (x.getOwner() instanceof SQLIdentifierExpr) {
|
||||
String ownerName = ((SQLIdentifierExpr) x.getOwner()).getName();
|
||||
SQLTableSource tableSource = visitor.getTableSources().get(ownerName);
|
||||
Entity entity = (Entity) tableSource.getAttribute("mapping.entity");
|
||||
|
||||
if (entity != null) {
|
||||
Property property = entity.getProperty(x.getName());
|
||||
if (property != null) {
|
||||
String columnName = visitor.resovleColumnName(entity, property);
|
||||
x.setName(columnName);
|
||||
x.putAttribute("mapping.entity", entity);
|
||||
x.putAttribute("mapping.property", property);
|
||||
|
||||
if (x.getParent() instanceof SQLSelectItem) {
|
||||
SQLSelectItem selectItem = (SQLSelectItem) x.getParent();
|
||||
if (selectItem.getAlias() == null) {
|
||||
selectItem.setAlias('"' + property.getName() + '"');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean visit(MappingVisitor visitor, SQLVariantRefExpr x) {
|
||||
Map<String, Object> attributes = x.getAttributes();
|
||||
Integer varIndex = (Integer) attributes.get("mapping.varIndex");
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.Map;
|
||||
import com.alibaba.druid.mapping.Entity;
|
||||
import com.alibaba.druid.mapping.MappingEngine;
|
||||
import com.alibaba.druid.mapping.Property;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
@@ -30,6 +31,7 @@ public class MySqlMappingVisitor extends MySqlASTVisitorAdapter implements Mappi
|
||||
private final List<Object> parameters;
|
||||
private final List<PropertyValue> propertyValues = new ArrayList<PropertyValue>();
|
||||
private int variantIndex = 0;
|
||||
private final List<SQLExpr> unresolveList = new ArrayList<SQLExpr>();
|
||||
|
||||
public MySqlMappingVisitor(MappingEngine engine){
|
||||
this(engine, Collections.emptyList());
|
||||
@@ -80,8 +82,7 @@ public class MySqlMappingVisitor extends MySqlASTVisitorAdapter implements Mappi
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLSelectItem x) {
|
||||
x.getExpr().setParent(x);
|
||||
return true;
|
||||
return MappingVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -137,4 +138,13 @@ public class MySqlMappingVisitor extends MySqlASTVisitorAdapter implements Mappi
|
||||
public int getVariantIndex() {
|
||||
return variantIndex;
|
||||
}
|
||||
|
||||
public List<SQLExpr> getUnresolveList() {
|
||||
return unresolveList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterResolve() {
|
||||
MappingVisitorUtils.afterResolve(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.Map;
|
||||
import com.alibaba.druid.mapping.Entity;
|
||||
import com.alibaba.druid.mapping.MappingEngine;
|
||||
import com.alibaba.druid.mapping.Property;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
@@ -32,6 +33,7 @@ public class OracleMappingVisitor extends OracleASTVisitorAdapter implements Map
|
||||
private final List<Object> parameters;
|
||||
private final List<PropertyValue> propertyValues = new ArrayList<PropertyValue>();
|
||||
private int variantIndex = 0;
|
||||
private final List<SQLExpr> unresolveList = new ArrayList<SQLExpr>();
|
||||
|
||||
public OracleMappingVisitor(MappingEngine engine){
|
||||
this(engine, Collections.emptyList());
|
||||
@@ -82,8 +84,7 @@ public class OracleMappingVisitor extends OracleASTVisitorAdapter implements Map
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLSelectItem x) {
|
||||
x.getExpr().setParent(x);
|
||||
return true;
|
||||
return MappingVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -150,4 +151,13 @@ public class OracleMappingVisitor extends OracleASTVisitorAdapter implements Map
|
||||
public int getVariantIndex() {
|
||||
return variantIndex;
|
||||
}
|
||||
|
||||
public List<SQLExpr> getUnresolveList() {
|
||||
return unresolveList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterResolve() {
|
||||
MappingVisitorUtils.afterResolve(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,26 @@ public class MySqlMappingShardingTest extends TestCase {
|
||||
MappingEngine engine = new ShardingMappingEngine();
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
Entity entity = new Entity();
|
||||
entity.setName("用户");
|
||||
entity.setTableName("user");
|
||||
{
|
||||
Entity entity = new Entity();
|
||||
entity.setName("用户");
|
||||
entity.setTableName("user");
|
||||
|
||||
entity.addProperty(new Property("名称", "", "uid"));
|
||||
entity.addProperty(new Property("昵称", "", "name"));
|
||||
entity.addProperty(new Property("名称", "", "uid"));
|
||||
entity.addProperty(new Property("昵称", "", "name"));
|
||||
|
||||
engine.addEntity(entity);
|
||||
}
|
||||
{
|
||||
Entity entity = new Entity();
|
||||
entity.setName("英雄");
|
||||
entity.setTableName("hero");
|
||||
|
||||
engine.addEntity(entity);
|
||||
entity.addProperty(new Property("用户名", "", "uid"));
|
||||
entity.addProperty(new Property("称号", "", "name"));
|
||||
|
||||
engine.addEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public void test_0() throws Exception {
|
||||
@@ -35,33 +47,71 @@ public class MySqlMappingShardingTest extends TestCase {
|
||||
String sql = engine.explainToSelectSQL(oql);
|
||||
|
||||
String expected = "SELECT uid AS \"名称\", name AS \"昵称\"\n" + //
|
||||
"FROM user_a u\n" + //
|
||||
"WHERE u.uid = 'a'";
|
||||
|
||||
"FROM user_a u\n" + //
|
||||
"WHERE u.uid = 'a'";
|
||||
|
||||
Assert.assertEquals(expected, sql);
|
||||
}
|
||||
|
||||
|
||||
public void test_1() throws Exception {
|
||||
String oql = "select * from 用户 u where u.名称 = ?";
|
||||
|
||||
String sql = engine.explainToSelectSQL(oql, Collections.<Object>singletonList("a"));
|
||||
String sql = engine.explainToSelectSQL(oql, Collections.<Object> singletonList("a"));
|
||||
|
||||
String expected = "SELECT uid AS \"名称\", name AS \"昵称\"\n" + //
|
||||
"FROM user_a u\n" + //
|
||||
"WHERE u.uid = ?";
|
||||
|
||||
"FROM user_a u\n" + //
|
||||
"WHERE u.uid = ?";
|
||||
|
||||
Assert.assertEquals(expected, sql);
|
||||
}
|
||||
|
||||
|
||||
public void test_2() throws Exception {
|
||||
String oql = "select * from 用户 u where u.名称 = ?";
|
||||
|
||||
String sql = engine.explainToSelectSQL(oql, Collections.<Object>singletonList("b"));
|
||||
String sql = engine.explainToSelectSQL(oql, Collections.<Object> singletonList("b"));
|
||||
|
||||
String expected = "SELECT uid AS \"名称\", name AS \"昵称\"\n" + //
|
||||
"FROM user_x u\n" + //
|
||||
"WHERE u.uid = ?";
|
||||
|
||||
"FROM user_x u\n" + //
|
||||
"WHERE u.uid = ?";
|
||||
|
||||
Assert.assertEquals(expected, sql);
|
||||
}
|
||||
|
||||
public void test_3() throws Exception {
|
||||
String oql = "select h.用户名, u.昵称 from 用户 u left join 英雄 h on h.用户名 = u.名称 where u.名称 = 2";
|
||||
|
||||
String sql = engine.explainToSelectSQL(oql, Collections.<Object> singletonList("b"));
|
||||
|
||||
String expected = "SELECT h.uid AS \"用户名\", u.name AS \"昵称\"\n" + //
|
||||
"FROM user_x u LEFT JOIN hero h ON h.uid = u.uid\n" + //
|
||||
"WHERE u.uid = 2";
|
||||
|
||||
System.out.println(sql);
|
||||
Assert.assertEquals(expected, sql);
|
||||
}
|
||||
|
||||
public void test_4() throws Exception {
|
||||
String oql = "select * from 用户 u where 名称 = ?";
|
||||
|
||||
String sql = engine.explainToSelectSQL(oql, Collections.<Object> singletonList("b"));
|
||||
|
||||
String expected = "SELECT uid AS \"名称\", name AS \"昵称\"\n" + //
|
||||
"FROM user_x u\n" + //
|
||||
"WHERE uid = ?";
|
||||
|
||||
Assert.assertEquals(expected, sql);
|
||||
}
|
||||
|
||||
public void test_5() throws Exception {
|
||||
String oql = "select h.用户名, u.昵称 from 用户 u left join 英雄 h on h.用户名 = u.名称 where 名称 = 2";
|
||||
|
||||
String sql = engine.explainToSelectSQL(oql, Collections.<Object> singletonList("b"));
|
||||
|
||||
String expected = "SELECT h.uid AS \"用户名\", u.name AS \"昵称\"\n" + //
|
||||
"FROM user_x u LEFT JOIN hero h ON h.uid = u.uid\n" + //
|
||||
"WHERE uid = 2";
|
||||
|
||||
System.out.println(sql);
|
||||
Assert.assertEquals(expected, sql);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user