From a54e1f6839f4f563327303e9e12d2436f91d1cbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BF=97=E4=BA=AE?= Date: Mon, 7 Sep 2015 15:46:52 +0800 Subject: [PATCH 01/17] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=85=B7=E6=9C=89?= =?UTF-8?q?=E7=BB=A7=E6=89=BF=E5=85=B3=E7=B3=BB=E7=9A=84DAO=E6=B5=8B?= =?UTF-8?q?=E8=AF=95(BaseDAO)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jade/plugin/sql/PlumUpdateTestCase.java | 37 +++++++++++++------ .../rose/jade/plugin/sql/dao/BaseDAO.java | 13 +++++++ .../rose/jade/plugin/sql/dao/UserInfoDAO.java | 3 +- 3 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 src/test/java/net/paoding/rose/jade/plugin/sql/dao/BaseDAO.java diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumUpdateTestCase.java b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumUpdateTestCase.java index 315c77c..66ca381 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumUpdateTestCase.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumUpdateTestCase.java @@ -12,6 +12,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; +import junit.framework.Assert; import net.paoding.rose.jade.plugin.sql.dao.UserInfoDAO; import net.paoding.rose.jade.plugin.sql.model.UserInfoDO; @@ -22,7 +23,7 @@ public class PlumUpdateTestCase extends AbstractTestCase { @Autowired - private UserInfoDAO purchaseContractDAO; + private UserInfoDAO userInfoDAO; public void testUpdate() { UserInfoDO contract = new UserInfoDO(); @@ -31,27 +32,39 @@ public void testUpdate() { contract.setLastUpdateTime(new Date()); contract.setName("Alan.Geng"); - System.out.println(purchaseContractDAO.update(contract)); + System.out.println(userInfoDAO.update(contract)); - UserInfoDO user = purchaseContractDAO.get(1L); + UserInfoDO user = userInfoDAO.get(1L); System.out.println(JSON.toJSONString(user, SerializerFeature.PrettyFormat)); } - - public void testSpecialUpdate() { - purchaseContractDAO.updateByGroup(null, 25, 100); - - List updated = purchaseContractDAO.findByGroupId(100L); - System.out.println(JSON.toJSONString(updated, SerializerFeature.PrettyFormat)); - } + + public void testBaseDAOUpdate() { + userInfoDAO.updateStatus(1L, 123); + + int status = userInfoDAO.getStatus(1L); + + Assert.assertEquals(123, status); + + + UserInfoDO user = userInfoDAO.get(1L); + System.out.println(JSON.toJSONString(user, SerializerFeature.PrettyFormat)); + } + + public void testSpecialUpdate() { + userInfoDAO.updateByGroup(null, 25, 100); + + List updated = userInfoDAO.findByGroupId(100L); + System.out.println(JSON.toJSONString(updated, SerializerFeature.PrettyFormat)); + } public void testSpecialInUpdate() { List groupIds = new ArrayList(); groupIds.add(100); groupIds.add(101); - purchaseContractDAO.updateByGroupIds("Alan.Geng", 29, groupIds); + userInfoDAO.updateByGroupIds("Alan.Geng", 29, groupIds); - List updated = purchaseContractDAO.findByGroupIds(groupIds); + List updated = userInfoDAO.findByGroupIds(groupIds); System.out.println(JSON.toJSONString(updated, SerializerFeature.PrettyFormat)); } } diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/dao/BaseDAO.java b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/BaseDAO.java new file mode 100644 index 0000000..b07654b --- /dev/null +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/BaseDAO.java @@ -0,0 +1,13 @@ +package net.paoding.rose.jade.plugin.sql.dao; + +import net.paoding.rose.jade.annotation.SQL; +import net.paoding.rose.jade.plugin.sql.GenericDAO; + +public interface BaseDAO extends GenericDAO { + + @SQL("update {table_name} set status=:2 where id=:1") + void updateStatus(ID id, int status); + + @SQL("select status from {table_name} where id=:1") + int getStatus(ID id); +} diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java index ad86992..c4f599d 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java @@ -7,7 +7,6 @@ import net.paoding.rose.jade.annotation.DAO; import net.paoding.rose.jade.annotation.SQLParam; -import net.paoding.rose.jade.plugin.sql.GenericDAO; import net.paoding.rose.jade.plugin.sql.Order; import net.paoding.rose.jade.plugin.sql.annotations.Ge; import net.paoding.rose.jade.plugin.sql.annotations.IgnoreNull; @@ -31,7 +30,7 @@ * spring框架将自动注入一个自动生成的实现。 */ @DAO -public interface UserInfoDAO extends GenericDAO { +public interface UserInfoDAO extends BaseDAO { /** * 指定字段查询 From 0f2a13ec5ad6e3bc57af5eb1e12ce31cf1f2f189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BF=97=E4=BA=AE?= Date: Tue, 8 Sep 2015 10:56:17 +0800 Subject: [PATCH 02/17] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E4=BD=9C=E4=B8=BASQL=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=9A=84=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jade/plugin/sql/AbstractTestCase.java | 2 + .../jade/plugin/sql/PlumInsertTestCase.java | 2 + .../jade/plugin/sql/PlumUpdateTestCase.java | 40 +++++++++++++------ .../rose/jade/plugin/sql/dao/BooleanEnum.java | 8 ++++ .../jade/plugin/sql/dao/CreateTableDAO.java | 4 +- .../rose/jade/plugin/sql/dao/UserInfoDAO.java | 10 +++++ .../jade/plugin/sql/model/UserInfoDO.java | 12 ++++++ 7 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 src/test/java/net/paoding/rose/jade/plugin/sql/dao/BooleanEnum.java diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/AbstractTestCase.java b/src/test/java/net/paoding/rose/jade/plugin/sql/AbstractTestCase.java index 1de5ecf..7736b28 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/AbstractTestCase.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/AbstractTestCase.java @@ -13,6 +13,7 @@ import com.alibaba.fastjson.JSON; import junit.framework.TestCase; +import net.paoding.rose.jade.plugin.sql.dao.BooleanEnum; import net.paoding.rose.jade.plugin.sql.dao.CreateTableDAO; import net.paoding.rose.jade.plugin.sql.dao.UserInfoDAO; import net.paoding.rose.jade.plugin.sql.model.UserInfoDO;; @@ -65,6 +66,7 @@ private static UserInfoDO createUserInfoDO(long group, int age) { userInfo.setCreateTime(new Date()); userInfo.setEditable(true); userInfo.setLastUpdateTime(new Date()); + userInfo.setBoolEnum(BooleanEnum.FALSE); return userInfo; } diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumInsertTestCase.java b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumInsertTestCase.java index eec074d..12102b5 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumInsertTestCase.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumInsertTestCase.java @@ -14,6 +14,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; +import net.paoding.rose.jade.plugin.sql.dao.BooleanEnum; import net.paoding.rose.jade.plugin.sql.dao.UserInfoDAO; import net.paoding.rose.jade.plugin.sql.model.UserInfoDO; @@ -62,6 +63,7 @@ private static UserInfoDO createUserInfoDO(long group, int age) { userInfo.setCreateTime(new Date()); userInfo.setEditable(true); userInfo.setLastUpdateTime(new Date()); + userInfo.setBoolEnum(BooleanEnum.TRUE); return userInfo; } diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumUpdateTestCase.java b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumUpdateTestCase.java index 66ca381..7b64c97 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumUpdateTestCase.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumUpdateTestCase.java @@ -13,6 +13,7 @@ import com.alibaba.fastjson.serializer.SerializerFeature; import junit.framework.Assert; +import net.paoding.rose.jade.plugin.sql.dao.BooleanEnum; import net.paoding.rose.jade.plugin.sql.dao.UserInfoDAO; import net.paoding.rose.jade.plugin.sql.model.UserInfoDO; @@ -24,19 +25,32 @@ public class PlumUpdateTestCase extends AbstractTestCase { @Autowired private UserInfoDAO userInfoDAO; - - public void testUpdate() { - UserInfoDO contract = new UserInfoDO(); - - contract.setId(1L); - contract.setLastUpdateTime(new Date()); - contract.setName("Alan.Geng"); - - System.out.println(userInfoDAO.update(contract)); - - UserInfoDO user = userInfoDAO.get(1L); - System.out.println(JSON.toJSONString(user, SerializerFeature.PrettyFormat)); - } + + public void testUpdate() { + UserInfoDO contract = new UserInfoDO(); + + contract.setId(1L); + contract.setLastUpdateTime(new Date()); + contract.setName("Alan.Geng"); + + System.out.println(userInfoDAO.update(contract)); + + UserInfoDO user = userInfoDAO.get(1L); + System.out.println(JSON.toJSONString(user, SerializerFeature.PrettyFormat)); + } + + public void testUpdateEnum() { + + userInfoDAO.updateBoolEnum(1, BooleanEnum.TRUE); + + UserInfoDO user = userInfoDAO.get(1L); + System.out.println(JSON.toJSONString(user, SerializerFeature.PrettyFormat)); + // + userInfoDAO.updateBoolEnum(1, BooleanEnum.FALSE); + + UserInfoDO user2 = userInfoDAO.get(1L); + System.out.println(JSON.toJSONString(user2, SerializerFeature.PrettyFormat)); + } public void testBaseDAOUpdate() { userInfoDAO.updateStatus(1L, 123); diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/dao/BooleanEnum.java b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/BooleanEnum.java new file mode 100644 index 0000000..59fdef0 --- /dev/null +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/BooleanEnum.java @@ -0,0 +1,8 @@ +package net.paoding.rose.jade.plugin.sql.dao; + +public enum BooleanEnum { + + TRUE, + + FALSE +} diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/dao/CreateTableDAO.java b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/CreateTableDAO.java index cdab330..f290937 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/dao/CreateTableDAO.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/CreateTableDAO.java @@ -18,7 +18,9 @@ public interface CreateTableDAO { + ",create_time datetime not null" + ",last_update_time timestamp not null" + ",status int not null" - + ",editable int not null" + ");"; + + ",editable int not null" + + ",bool_enum varchar(10) not null" + + ");"; @SQL(create_user_info_table) public void createUserInfoTable(); diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java index c4f599d..2b2fa23 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java @@ -6,6 +6,7 @@ import java.util.List; import net.paoding.rose.jade.annotation.DAO; +import net.paoding.rose.jade.annotation.SQL; import net.paoding.rose.jade.annotation.SQLParam; import net.paoding.rose.jade.plugin.sql.Order; import net.paoding.rose.jade.plugin.sql.annotations.Ge; @@ -116,4 +117,13 @@ public void updateByGroupIds( */ public void deleteByGroupId( @SQLParam("groupId") Integer groupId); + + /** + * 测试更新枚举类型(实际存储枚举类型的name值) + * @param id + * @param bool + * @return + */ + @SQL("update {table_name} set bool_enum=:2 where id=:1") + public boolean updateBoolEnum(int id, BooleanEnum bool); } diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/model/UserInfoDO.java b/src/test/java/net/paoding/rose/jade/plugin/sql/model/UserInfoDO.java index 860b245..4bc2951 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/model/UserInfoDO.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/model/UserInfoDO.java @@ -10,6 +10,7 @@ import net.paoding.rose.jade.plugin.sql.Order.Direction; import net.paoding.rose.jade.plugin.sql.annotations.Column; import net.paoding.rose.jade.plugin.sql.annotations.Table; +import net.paoding.rose.jade.plugin.sql.dao.BooleanEnum; /** * @author Alan.Geng[gengzhi718@gmail.com] @@ -59,6 +60,9 @@ public class UserInfoDO implements Serializable { @Column private Boolean editable; + @Column + private BooleanEnum boolEnum; + // Getter & Setter public Long getId() { @@ -141,4 +145,12 @@ public void setLastUpdateTime(Date lastUpdateTime) { this.lastUpdateTime = lastUpdateTime; } + public void setBoolEnum(BooleanEnum boolEnum) { + this.boolEnum = boolEnum; + } + + public BooleanEnum getBoolEnum() { + return boolEnum; + } + } From b7b66396e9b5c3d32a6e4a7322474158aaa7f5e3 Mon Sep 17 00:00:00 2001 From: "Alan.Geng" Date: Tue, 8 Sep 2015 17:04:00 +0800 Subject: [PATCH 03/17] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=B9DO=E7=BB=A7?= =?UTF-8?q?=E6=89=BF=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rose/jade/plugin/sql/mapper/EntityMapper.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java index f11f808..c69031e 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java @@ -59,14 +59,17 @@ protected void doMap() { } protected List generateColumns() { - Field[] fields = original.getDeclaredFields(); + Class entityClass = original; List columns = new ArrayList(); - - for(Field field : fields) { - if(field.isAnnotationPresent(Column.class)) { - columns.add(createColumnMapper(field)); + while(entityClass != Object.class) { + Field[] entityFields = entityClass.getDeclaredFields(); + for(Field entityField : entityFields) { + if(entityField.isAnnotationPresent(Column.class)) { + columns.add(createColumnMapper(entityField)); + } } + entityClass = entityClass.getSuperclass(); } if(columns.size() == 0) { From 265bd3225f75644ef17265f58edb074ce2d43704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BF=97=E4=BA=AE?= Date: Tue, 8 Sep 2015 19:42:11 +0800 Subject: [PATCH 04/17] =?UTF-8?q?table=5Fname=E3=80=81primary=5Fkey?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E4=BD=BF=E7=94=A8jade=E7=9A=84attribute?= =?UTF-8?q?=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../jade/plugin/sql/PlumSQLInterpreter.java | 109 ++++++++---------- .../jade/plugin/sql/PlumUpdateTestCase.java | 7 +- .../rose/jade/plugin/sql/dao/UserInfoDAO.java | 3 + 4 files changed, 55 insertions(+), 66 deletions(-) diff --git a/pom.xml b/pom.xml index 9702732..ee123d0 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ net.paoding paoding-rose-parent - 2.0.u04 + 2.0.u05 diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java b/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java index 121683c..96b5709 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java @@ -92,13 +92,16 @@ public void interpret(StatementRuntime runtime) { if (interpreter == null) { interpreter = PassThroughInterpreter; if (GenericDAO.class.isAssignableFrom(smd.getDAOMetaData().getDAOClass())) { - interpreter = VariableResolverInterpreter; SQL sqlAnnotation = smd.getMethod().getAnnotation(SQL.class); if (sqlAnnotation == null // 没有注解@SQL || PlumUtils.isBlank(sqlAnnotation.value()) // 虽注解但没有写SQL || "jade-plugin-sql".equals(sqlAnnotation.value())) // 明确表示使用jade-plugin-sql { + // 将表名、主键名放入DAO的attributes中 + putExtraAttributes(smd.getDAOMetaData()); + // 创建 IOperationMapper IOperationMapper mapper = operationMapperManager.create(smd); + // 生成最后的解析器 interpreter = new SQLGeneratorInterpreter(mapper); } } @@ -150,81 +153,63 @@ public void interpret(StatementRuntime runtime) { }; + // 以下是临时代码 @Alan /** * 变量解析器(表名、主键名等) - * -- 以下为临时性hardcode代码,不可维护的代码,不和谐的代码,搬到哪里去才能漂亮呢?@Alan */ - private static final Interpreter VariableResolverInterpreter = new Interpreter() { - - @Override - public void interpret(StatementRuntime runtime) { - // 临时hard代码2-1:获取table_name替换原始SQL中的{table_name}变量 - String sql = runtime.getSQL(); - // 替换表名 - if (sql.contains("{table_name}")) { - StatementMetaData smd = runtime.getMetaData(); - DAOMetaData dmd = smd.getDAOMetaData(); - final String tableNameAttribute = "jade-plugin-sql.interpreter"; - String tableName = dmd.getAttribute(tableNameAttribute); - if (tableName == null) { - Class entityType = smd.getDAOMetaData().resolveTypeVariable(// - GenericDAO.class, "E"); - Table tableAnnotation = entityType.getAnnotation(Table.class); - if (tableAnnotation != null) { - tableName = tableAnnotation.value(); - } - if (PlumUtils.isBlank(tableName)) { - tableName = entityType.getSimpleName().substring(0, - entityType.getSimpleName().length() - 2); - tableName = generateName(tableName); - } - dmd.setAttribute(tableNameAttribute, tableName); - } - sql = sql.replace("{table_name}", tableName); - runtime.setSQL(sql); + protected void putExtraAttributes(DAOMetaData md) { + synchronized (md) { + if (md.getAttribute("table_name") != null) { + return; } - // 替换主键 - if (sql.contains("{primary_key}")) { - //TODO: 假装pk都是“id” - sql = sql.replace("{primary_key}", "id"); - runtime.setSQL(sql); + Class entityType = md.resolveTypeVariable(// + GenericDAO.class, "E"); + Table tableAnnotation = entityType.getAnnotation(Table.class); + String tableName = null; + if (tableAnnotation != null) { + tableName = tableAnnotation.value(); } - - // 临时hard代码2-1结束 - + if (PlumUtils.isBlank(tableName)) { + tableName = entityType.getSimpleName().substring(0, + entityType.getSimpleName().length() - 2); + tableName = generateName(tableName); + } + md.setAttribute("{table_name}", tableName); + md.setAttribute("{primary_key}", "id"); // 当前阶段,假装primary_key都是id } + } - // 临时代码2-2,copied from AbstractMapper#generateName - private String generateName(String source) { - if (PlumUtils.isBlank(source)) { - return null; - } + // 以下是临时代码 + // copied from AbstractMapper#generateName + protected String generateName(String source) { + if (PlumUtils.isBlank(source)) { + return null; + } - if (source.matches("^[a-zA-Z\\\\.]+$")) { - StringBuilder result = new StringBuilder(); + if (source.matches("^[a-zA-Z\\\\.]+$")) { + StringBuilder result = new StringBuilder(); - for (int i = 0; i < source.length(); i++) { - char c = source.charAt(i); + for (int i = 0; i < source.length(); i++) { + char c = source.charAt(i); - if (Character.isWhitespace(c)) { - continue; - } + if (Character.isWhitespace(c)) { + continue; + } - if (Character.isUpperCase(c)) { - if (result.length() > 0) { - result.append("_"); - } - result.append(Character.toLowerCase(c)); - } else { - result.append(c); + if (Character.isUpperCase(c)) { + if (result.length() > 0) { + result.append("_"); } + result.append(Character.toLowerCase(c)); + } else { + result.append(c); } - - return result.toString(); - } else { - throw new IllegalArgumentException("Illegal naming conventions."); } + + return result.toString(); + } else { + throw new IllegalArgumentException("Illegal naming conventions."); } - }; + } } diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumUpdateTestCase.java b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumUpdateTestCase.java index 7b64c97..21057ce 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumUpdateTestCase.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumUpdateTestCase.java @@ -53,14 +53,15 @@ public void testUpdateEnum() { } public void testBaseDAOUpdate() { - userInfoDAO.updateStatus(1L, 123); + UserInfoDO user = userInfoDAO.findAll().get(0); + userInfoDAO.updateStatus(user.getId(), 123); - int status = userInfoDAO.getStatus(1L); + int status = userInfoDAO.getStatus(user.getId()); Assert.assertEquals(123, status); - UserInfoDO user = userInfoDAO.get(1L); + user = userInfoDAO.get(user.getId()); System.out.println(JSON.toJSONString(user, SerializerFeature.PrettyFormat)); } diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java index 2b2fa23..044a4ab 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java @@ -126,4 +126,7 @@ public void deleteByGroupId( */ @SQL("update {table_name} set bool_enum=:2 where id=:1") public boolean updateBoolEnum(int id, BooleanEnum bool); + + @SQL("select * from {table_name} ") + public List findAll(); } From 93c3d3e457725d4cbf63a7591d8a6e28a4b1a666 Mon Sep 17 00:00:00 2001 From: "Alan.Geng" Date: Sat, 12 Sep 2015 17:10:22 +0800 Subject: [PATCH 05/17] =?UTF-8?q?=E5=A2=9E=E5=8A=A0IDGenerator=E4=B8=8Ecou?= =?UTF-8?q?nt=E6=94=AF=E6=8C=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jade/plugin/sql/annotations/Column.java | 11 ++++- .../sql/dialect/mysql/InsertGenerator.java | 35 ++++++++++++++ .../sql/dialect/mysql/SelectGenerator.java | 29 +++++++---- .../sql/id/CachedIDGeneratorManager.java | 48 +++++++++++++++++++ .../rose/jade/plugin/sql/id/IDGenerator.java | 14 ++++++ .../plugin/sql/id/IDGeneratorManager.java | 16 +++++++ .../jade/plugin/sql/id/ManualGenerator.java | 20 ++++++++ .../jade/plugin/sql/id/NativeGenerator.java | 17 +++++++ .../rose/jade/plugin/sql/id/NonID.java | 20 ++++++++ .../plugin/sql/id/UUIDStringGenerator.java | 22 +++++++++ .../jade/plugin/sql/mapper/ColumnMapper.java | 10 +++- .../jade/plugin/sql/mapper/IColumnMapper.java | 3 ++ .../plugin/sql/mapper/IOperationMapper.java | 2 + .../plugin/sql/mapper/OperationMapper.java | 21 ++++---- .../jade/plugin/sql/PlumInsertTestCase.java | 4 +- .../jade/plugin/sql/PlumSelectTestCase.java | 4 ++ .../rose/jade/plugin/sql/dao/UserInfoDAO.java | 2 + 17 files changed, 256 insertions(+), 22 deletions(-) create mode 100644 src/main/java/net/paoding/rose/jade/plugin/sql/id/CachedIDGeneratorManager.java create mode 100644 src/main/java/net/paoding/rose/jade/plugin/sql/id/IDGenerator.java create mode 100644 src/main/java/net/paoding/rose/jade/plugin/sql/id/IDGeneratorManager.java create mode 100644 src/main/java/net/paoding/rose/jade/plugin/sql/id/ManualGenerator.java create mode 100644 src/main/java/net/paoding/rose/jade/plugin/sql/id/NativeGenerator.java create mode 100644 src/main/java/net/paoding/rose/jade/plugin/sql/id/NonID.java create mode 100644 src/main/java/net/paoding/rose/jade/plugin/sql/id/UUIDStringGenerator.java diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/annotations/Column.java b/src/main/java/net/paoding/rose/jade/plugin/sql/annotations/Column.java index 51b9f31..f0d826e 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/annotations/Column.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/annotations/Column.java @@ -7,6 +7,8 @@ import java.lang.annotation.Target; import net.paoding.rose.jade.plugin.sql.Order.Direction; +import net.paoding.rose.jade.plugin.sql.id.IDGenerator; +import net.paoding.rose.jade.plugin.sql.id.NonID; import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy; @@ -26,9 +28,16 @@ String value() default ""; /** - * 是否为主键,默认false。 + * 主键 * @return */ + Class> id() default NonID.class; + + /** + * 是否为主键 + * @return + */ + @Deprecated boolean pk() default false; /** diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/InsertGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/InsertGenerator.java index a297860..098ca2e 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/InsertGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/InsertGenerator.java @@ -6,6 +6,13 @@ import java.util.List; import net.paoding.rose.jade.plugin.sql.dialect.ISQLGenerator; +import net.paoding.rose.jade.plugin.sql.id.CachedIDGeneratorManager; +import net.paoding.rose.jade.plugin.sql.id.IDGenerator; +import net.paoding.rose.jade.plugin.sql.id.IDGeneratorManager; +import net.paoding.rose.jade.plugin.sql.id.ManualGenerator; +import net.paoding.rose.jade.plugin.sql.id.NativeGenerator; +import net.paoding.rose.jade.plugin.sql.id.NonID; +import net.paoding.rose.jade.plugin.sql.mapper.IColumnMapper; import net.paoding.rose.jade.plugin.sql.mapper.IEntityMapper; import net.paoding.rose.jade.plugin.sql.mapper.IExpandableParameterMapper; import net.paoding.rose.jade.plugin.sql.mapper.IOperationMapper; @@ -13,6 +20,7 @@ import net.paoding.rose.jade.plugin.sql.mapper.OperationMapper; import net.paoding.rose.jade.statement.StatementRuntime; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.util.CollectionUtils; /** @@ -20,6 +28,8 @@ * */ public class InsertGenerator implements ISQLGenerator { + + private IDGeneratorManager idGeneratorManager = new CachedIDGeneratorManager(); /* (non-Javadoc) * @see com.cainiao.depot.project.biz.common.jade.dialect.ISQLGenerator#generate(com.cainiao.depot.project.biz.common.jade.mapper.IOperationMapper) @@ -48,6 +58,31 @@ public String generate(OperationMapper operationMapper, StatementRuntime runtime sql.append("("); for(IParameterMapper param : expandParams) { + IColumnMapper columnMapper = param.getColumnMapper(); + if(columnMapper.isPrimaryKey()) { + Class> idGeneratorType = columnMapper.getIDGeneratorType(); + + if(idGeneratorType == NativeGenerator.class + // 兼容pk属性 + || idGeneratorType == NonID.class) { + // 数据库自增型ID在插入时不做任何处理,也不参与插入字段。 + continue; + } else if(idGeneratorType != ManualGenerator.class){ + // 非手动设置ID,则需要生成值。 + IDGenerator idGenerator = idGeneratorManager.get(idGeneratorType); + if(idGenerator != null) { + Object entity = runtime.getParameters().get(":1"); + Object idValue = idGenerator.generate(entity); + + try { + columnMapper.getOriginal().set(entity, idValue); + } catch (Exception e) { + throw new InvalidDataAccessApiUsageException("Cannot set id to entity property."); + } + } + } + } + sql.append(param.getColumnMapper().getName()); sql.append(","); diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/SelectGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/SelectGenerator.java index f100ca2..187f5e2 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/SelectGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/SelectGenerator.java @@ -36,18 +36,23 @@ public class SelectGenerator extends ConditionalGenerator { protected void beforeApplyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { super.beforeApplyConditions(operationMapper, runtime, sql); IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); - List columns = targetEntityMapper.getColumns(); - sql.append(operationMapper.getName()); sql.append(" "); - for(IColumnMapper col : columns) { - String name = col.getName(); - sql.append(name); - sql.append(","); + if(operationMapper.isCountQuery()) { + sql.append(" COUNT(*)"); + } else { + List columns = targetEntityMapper.getColumns(); + + for(IColumnMapper col : columns) { + String name = col.getName(); + sql.append(name); + sql.append(","); + } + + sql.setLength(sql.length() - 1); } - sql.setLength(sql.length() - 1); sql.append(" FROM "); sql.append(targetEntityMapper.getName()); } @@ -55,12 +60,18 @@ protected void beforeApplyConditions(ConditionalOperationMapper operationMapper, @Override protected void afterApplyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { super.afterApplyConditions(operationMapper, runtime, sql); - applyOrderBy(operationMapper, runtime, sql); + + if(!operationMapper.isCountQuery()) { + // 节省数据库性能开销,count操作不需要orderBy。 + applyOrderBy(operationMapper, runtime, sql); + } + applyRange(operationMapper, runtime, sql); } protected void applyOrderBy(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { - if(operationMapper.containsOrder()) { + if(operationMapper.containsOrder() + && !operationMapper.isPrimaryKeyMode()) { IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); Order order = null; diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/id/CachedIDGeneratorManager.java b/src/main/java/net/paoding/rose/jade/plugin/sql/id/CachedIDGeneratorManager.java new file mode 100644 index 0000000..d597e65 --- /dev/null +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/id/CachedIDGeneratorManager.java @@ -0,0 +1,48 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql.id; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + +/** + * @author Alan + * + */ +public class CachedIDGeneratorManager implements IDGeneratorManager { + + private final CacheLoader>, IDGenerator> loader = new CacheLoader>, IDGenerator>() { + + @Override + public IDGenerator load(Class> key) + throws Exception { + return create(key); + } + }; + + private LoadingCache>, IDGenerator> cache = CacheBuilder.newBuilder().build(loader); + + /* (non-Javadoc) + * @see net.paoding.rose.jade.plugin.sql.id.IDGeneratorManager#get(java.lang.Class) + */ + @Override + public IDGenerator get(Class> type) { + try { + return cache.get(type); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public IDGenerator create(Class> type) { + try { + return type.newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/id/IDGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/id/IDGenerator.java new file mode 100644 index 0000000..2713625 --- /dev/null +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/id/IDGenerator.java @@ -0,0 +1,14 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql.id; + +/** + * @author Alan + * + */ +public interface IDGenerator { + + public T generate(Object entity); + +} diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/id/IDGeneratorManager.java b/src/main/java/net/paoding/rose/jade/plugin/sql/id/IDGeneratorManager.java new file mode 100644 index 0000000..524d7e4 --- /dev/null +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/id/IDGeneratorManager.java @@ -0,0 +1,16 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql.id; + +/** + * @author Alan + * + */ +public interface IDGeneratorManager { + + IDGenerator create(Class> type); + + IDGenerator get(Class> type); + +} diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/id/ManualGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/id/ManualGenerator.java new file mode 100644 index 0000000..2b13d7c --- /dev/null +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/id/ManualGenerator.java @@ -0,0 +1,20 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql.id; + +/** + * @author Alan + * + */ +public final class ManualGenerator implements IDGenerator { + + /* (non-Javadoc) + * @see net.paoding.rose.jade.plugin.sql.util.IDGenerator#generate(java.lang.Object) + */ + @Override + public Void generate(Object entity) { + return null; + } + +} diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/id/NativeGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/id/NativeGenerator.java new file mode 100644 index 0000000..a42bdc8 --- /dev/null +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/id/NativeGenerator.java @@ -0,0 +1,17 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql.id; + +/** + * @author Alan + * + */ +public final class NativeGenerator implements IDGenerator { + + @Override + public Void generate(Object entity) { + return null; + } + +} diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/id/NonID.java b/src/main/java/net/paoding/rose/jade/plugin/sql/id/NonID.java new file mode 100644 index 0000000..8bae3d0 --- /dev/null +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/id/NonID.java @@ -0,0 +1,20 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql.id; + +/** + * @author Alan + * + */ +public final class NonID implements IDGenerator { + + /* (non-Javadoc) + * @see net.paoding.rose.jade.plugin.sql.util.IDGenerator#generate(java.lang.Object) + */ + @Override + public Void generate(Object entity) { + return null; + } + +} diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/id/UUIDStringGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/id/UUIDStringGenerator.java new file mode 100644 index 0000000..5b91462 --- /dev/null +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/id/UUIDStringGenerator.java @@ -0,0 +1,22 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql.id; + +import java.util.UUID; + +/** + * @author Alan + * + */ +public class UUIDStringGenerator implements IDGenerator { + + /* (non-Javadoc) + * @see net.paoding.rose.jade.plugin.sql.util.IDGenerator#generate(java.lang.Object) + */ + @Override + public String generate(Object entity) { + return UUID.randomUUID().toString(); + } + +} diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ColumnMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ColumnMapper.java index 0bd3421..98ed108 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ColumnMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ColumnMapper.java @@ -7,6 +7,8 @@ import net.paoding.rose.jade.plugin.sql.Order.Direction; import net.paoding.rose.jade.plugin.sql.annotations.Column; +import net.paoding.rose.jade.plugin.sql.id.IDGenerator; +import net.paoding.rose.jade.plugin.sql.id.NonID; import net.paoding.rose.jade.plugin.sql.util.PlumUtils; /** @@ -44,13 +46,19 @@ public String generateName(String source) { return super.generateName(source); } + @SuppressWarnings("deprecation") @Override public boolean isPrimaryKey() { - return annotation.pk(); + return annotation.id() != NonID.class || annotation.pk(); } public Direction getDefaultOrderDirection() { return defaultOrderDirection; } + + @Override + public Class> getIDGeneratorType() { + return annotation != null ? annotation.id() : null; + } } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IColumnMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IColumnMapper.java index f7e221a..d283337 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IColumnMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IColumnMapper.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import net.paoding.rose.jade.plugin.sql.Order.Direction; +import net.paoding.rose.jade.plugin.sql.id.IDGenerator; /** * @author Alan.Geng[gengzhi718@gmail.com] @@ -16,4 +17,6 @@ public interface IColumnMapper extends IMapper { boolean isPrimaryKey(); Direction getDefaultOrderDirection(); + + Class> getIDGeneratorType(); } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IOperationMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IOperationMapper.java index e0b4258..feddf3f 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IOperationMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IOperationMapper.java @@ -45,4 +45,6 @@ public interface IOperationMapper extends IMapper { IgnoreNull getIgnoreNull(); + boolean isCountQuery(); + } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java index c78b846..4e04a4f 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java @@ -38,6 +38,8 @@ public class OperationMapper extends AbstractMapper implement private IgnoreNull ignoreNull; + private boolean countQuery; + public static final List NO_PARAMETER = Collections.unmodifiableList(new ArrayList()); public OperationMapper(StatementMetaData original) { @@ -52,6 +54,12 @@ public IEntityMapper getTargetEntityMapper() { @Override protected void doMap() { ignoreNull = original.getAnnotation(IgnoreNull.class); + + if(original.getMethod().getName().startsWith("count") + && Number.class.isAssignableFrom(original.getReturnType())) { + countQuery = true; + } + mapGenericEntityType(); mapTargetEntityMapper(); mapParameters(); @@ -135,15 +143,6 @@ protected Class resolveParameterType(Type type) { throw new MappingException("Unknown type \"" + type + "\"."); } - protected Type[] getCollectionTypeBounds(Class collectionType) { - TypeVariable[] typeParameters = collectionType.getTypeParameters(); - if(typeParameters.length == 0) { - throw new MappingException("The generic type of collection must be specified."); - } - TypeVariable typeVariable = collectionType.getTypeParameters()[0]; - return typeVariable.getBounds(); - } - protected IParameterMapper createParameterMapper(Class type, Annotation[] annotations, int index) { SQLParam sp = null; @@ -224,5 +223,9 @@ public boolean isIgnoreNull() { public IgnoreNull getIgnoreNull() { return ignoreNull; } + + public boolean isCountQuery() { + return countQuery; + } } diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumInsertTestCase.java b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumInsertTestCase.java index 12102b5..ae8fb56 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumInsertTestCase.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumInsertTestCase.java @@ -36,10 +36,10 @@ protected void setUp() throws Exception { public void testInsert() { UserInfoDO userInfo = createUserInfoDO(102, 30); - Long id = userInfoDAO.save(userInfo); + userInfoDAO.save(userInfo); - System.out.println(JSON.toJSONString(userInfoDAO.get(id), SerializerFeature.PrettyFormat)); + System.out.println(JSON.toJSONString(userInfoDAO.findByGroupId(102L), SerializerFeature.PrettyFormat)); } public void testBatchInsert() { diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumSelectTestCase.java b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumSelectTestCase.java index 09951d8..fed110e 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumSelectTestCase.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumSelectTestCase.java @@ -72,4 +72,8 @@ public void testFindByGroupIds() { System.out.println(JSON.toJSONString(userInfos, SerializerFeature.PrettyFormat)); } + public void testCountByGroupId() { + System.out.println(userInfoDAO.countByGroupId(100)); + } + } diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java index 044a4ab..ad3fed9 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/dao/UserInfoDAO.java @@ -129,4 +129,6 @@ public void deleteByGroupId( @SQL("select * from {table_name} ") public List findAll(); + + public Long countByGroupId(@SQLParam("groupId") Integer groupId); } From 5627e0a37a55b29ea01669af4dd8e5a43c5ea265 Mon Sep 17 00:00:00 2001 From: "Alan.Geng" Date: Sat, 12 Sep 2015 19:49:35 +0800 Subject: [PATCH 06/17] =?UTF-8?q?=E5=A4=9A=E4=BA=86=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E7=A9=BA=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rose/jade/plugin/sql/dialect/mysql/SelectGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/SelectGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/SelectGenerator.java index 187f5e2..07e2f07 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/SelectGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/SelectGenerator.java @@ -40,7 +40,7 @@ protected void beforeApplyConditions(ConditionalOperationMapper operationMapper, sql.append(" "); if(operationMapper.isCountQuery()) { - sql.append(" COUNT(*)"); + sql.append("COUNT(*)"); } else { List columns = targetEntityMapper.getColumns(); From 81cbb61e27818a0c2873b85893f44f1619445999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BF=97=E4=BA=AE?= Date: Mon, 21 Sep 2015 13:43:25 +0800 Subject: [PATCH 07/17] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E5=AD=97=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java b/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java index 96b5709..c245899 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java @@ -79,7 +79,7 @@ public void afterPropertiesSet() throws Exception { } /** - * 对 {@link GenericDAO} 及其子DAO接口中没有注解®SQL或仅仅®SQL("")的方法进行解析,根据实际参数情况自动动态生成SQL语句 + * 对 {@link GenericDAO} 及其子DAO接口中没有注解@SQL或仅仅@SQL("")的方法进行解析,根据实际参数情况自动动态生成SQL语句 */ @Override public void interpret(StatementRuntime runtime) { From 8a181bf2a94ff5bbdf943506fea01646aed4570f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BF=97=E4=BA=AE?= Date: Mon, 21 Sep 2015 13:53:10 +0800 Subject: [PATCH 08/17] update jade version to 2.0.u06 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ee123d0..f0c2136 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ net.paoding paoding-rose-parent - 2.0.u05 + 2.0.u06 From 50624a8d35b0950516406d287da2f50fdc1638be Mon Sep 17 00:00:00 2001 From: "Alan.Geng" Date: Tue, 22 Sep 2015 14:53:34 +0800 Subject: [PATCH 09/17] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=87=AA=E5=A2=9Eid?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/sql/id/AutoIncrementProcessor.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java b/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java new file mode 100644 index 0000000..549e143 --- /dev/null +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java @@ -0,0 +1,23 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql.id; + +import net.paoding.rose.jade.statement.AfterInvocationCallback; +import net.paoding.rose.jade.statement.StatementRuntime; + +/** + * @author cunxin.gz + * + */ +public class AutoIncrementProcessor implements AfterInvocationCallback { + + /* (non-Javadoc) + * @see net.paoding.rose.jade.statement.AfterInvocationCallback#execute(net.paoding.rose.jade.statement.StatementRuntime, java.lang.Object) + */ + @Override + public Object execute(StatementRuntime runtime, Object returnValue) { + return returnValue; + } + +} From 49ab4342777ba1a3e3eccc8ae381de5c2f8d7385 Mon Sep 17 00:00:00 2001 From: "Alan.Geng" Date: Tue, 22 Sep 2015 16:26:45 +0800 Subject: [PATCH 10/17] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=87=AA=E5=A2=9EID?= =?UTF-8?q?=E6=8F=92=E5=85=A5=E5=90=8E=E5=B0=86=E5=80=BC=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E5=88=B0=E5=AE=9E=E4=BD=93=E7=B1=BB=E4=B8=AD=E7=9A=84=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rose/jade/plugin/sql/GenericDAO.java | 3 ++ .../jade/plugin/sql/PlumSQLInterpreter.java | 23 +++++++----- .../plugin/sql/id/AutoIncrementProcessor.java | 35 +++++++++++++++++++ 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/GenericDAO.java b/src/main/java/net/paoding/rose/jade/plugin/sql/GenericDAO.java index 542673c..3dc2efc 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/GenericDAO.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/GenericDAO.java @@ -5,9 +5,11 @@ import java.util.List; +import net.paoding.rose.jade.annotation.AfterInvocation; import net.paoding.rose.jade.annotation.ReturnGeneratedKeys; import net.paoding.rose.jade.annotation.SQL; import net.paoding.rose.jade.annotation.SQLParam; +import net.paoding.rose.jade.plugin.sql.id.AutoIncrementProcessor; /** * @author Alan.Geng[gengzhi718@gmail.com] @@ -28,6 +30,7 @@ public interface GenericDAO { * @return auto increment id */ @ReturnGeneratedKeys + @AfterInvocation(AutoIncrementProcessor.class) ID save(@SQLParam("entity") E entity); /** diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java b/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java index c245899..666276b 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java @@ -44,6 +44,10 @@ public class PlumSQLInterpreter implements Interpreter, InitializingBean, Applic private OperationMapperManager operationMapperManager; private IDialect dialect; + + public static final String ATTRIBUTE_NAME_INTERPRETER = "jade-plugin-sql.interpreter"; + + public static final String SQL_ANNOTATION_MARKUP = "jade-plugin-sql"; public void setDialect(IDialect dialect) { this.dialect = dialect; @@ -83,19 +87,18 @@ public void afterPropertiesSet() throws Exception { */ @Override public void interpret(StatementRuntime runtime) { - final String interpreterAttribute = "jade-plugin-sql.interpreter"; - Interpreter interpreter = runtime.getMetaData().getAttribute(interpreterAttribute); + Interpreter interpreter = runtime.getMetaData().getAttribute(ATTRIBUTE_NAME_INTERPRETER); if (interpreter == null) { StatementMetaData smd = runtime.getMetaData(); synchronized (smd) { - interpreter = smd.getAttribute(interpreterAttribute); + interpreter = smd.getAttribute(ATTRIBUTE_NAME_INTERPRETER); if (interpreter == null) { - interpreter = PassThroughInterpreter; + interpreter = PASS_THROUGH_INTERPRETER; if (GenericDAO.class.isAssignableFrom(smd.getDAOMetaData().getDAOClass())) { SQL sqlAnnotation = smd.getMethod().getAnnotation(SQL.class); if (sqlAnnotation == null // 没有注解@SQL || PlumUtils.isBlank(sqlAnnotation.value()) // 虽注解但没有写SQL - || "jade-plugin-sql".equals(sqlAnnotation.value())) // 明确表示使用jade-plugin-sql + || SQL_ANNOTATION_MARKUP.equals(sqlAnnotation.value())) // 明确表示使用jade-plugin-sql { // 将表名、主键名放入DAO的attributes中 putExtraAttributes(smd.getDAOMetaData()); @@ -105,7 +108,7 @@ public void interpret(StatementRuntime runtime) { interpreter = new SQLGeneratorInterpreter(mapper); } } - smd.setAttribute(interpreterAttribute, interpreter); + smd.setAttribute(ATTRIBUTE_NAME_INTERPRETER, interpreter); } } } @@ -115,7 +118,7 @@ public void interpret(StatementRuntime runtime) { /** * 透传SQL解析器 */ - private static final Interpreter PassThroughInterpreter = new Interpreter() { + private static final Interpreter PASS_THROUGH_INTERPRETER = new Interpreter() { @Override public void interpret(StatementRuntime runtime) { @@ -128,7 +131,7 @@ public void interpret(StatementRuntime runtime) { * 实际SQL解析器 * */ - private class SQLGeneratorInterpreter implements Interpreter { + public class SQLGeneratorInterpreter implements Interpreter { final IOperationMapper operationMapper; @@ -151,6 +154,10 @@ public void interpret(StatementRuntime runtime) { } } + public IOperationMapper getOperationMapper() { + return operationMapper; + } + }; // 以下是临时代码 @Alan diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java b/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java index 549e143..e3c5c10 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java @@ -3,6 +3,16 @@ */ package net.paoding.rose.jade.plugin.sql.id; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import net.paoding.rose.jade.plugin.sql.PlumSQLInterpreter; +import net.paoding.rose.jade.plugin.sql.PlumSQLInterpreter.SQLGeneratorInterpreter; +import net.paoding.rose.jade.plugin.sql.mapper.IColumnMapper; +import net.paoding.rose.jade.plugin.sql.mapper.IEntityMapper; +import net.paoding.rose.jade.plugin.sql.mapper.IOperationMapper; import net.paoding.rose.jade.statement.AfterInvocationCallback; import net.paoding.rose.jade.statement.StatementRuntime; @@ -11,12 +21,37 @@ * */ public class AutoIncrementProcessor implements AfterInvocationCallback { + + private Log logger = LogFactory.getLog(getClass()); /* (non-Javadoc) * @see net.paoding.rose.jade.statement.AfterInvocationCallback#execute(net.paoding.rose.jade.statement.StatementRuntime, java.lang.Object) */ @Override public Object execute(StatementRuntime runtime, Object returnValue) { + SQLGeneratorInterpreter attribute = runtime.getMetaData().getAttribute(PlumSQLInterpreter.ATTRIBUTE_NAME_INTERPRETER); + if(attribute != null) { + IOperationMapper operationMapper = attribute.getOperationMapper(); + + if(IOperationMapper.OPERATION_INSERT.equals(operationMapper.getName())) { + IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); + String paramName = operationMapper.getParameters().get(0).getName(); + + if(returnValue.getClass().isArray()) { + + } else { + Object param = runtime.getParameters().get(paramName); + List primaryKey = targetEntityMapper.getPrimaryKey(); + IColumnMapper iColumnMapper = primaryKey.get(0); + try { + iColumnMapper.getOriginal().set(param, returnValue); + } catch (Exception e) { + logger.error("Error to set auto increment value to entity object.", e); + } + } + } + + } return returnValue; } From 62f3d7fbda49d892c523f8befeba392c3b870f17 Mon Sep 17 00:00:00 2001 From: "Alan.Geng" Date: Tue, 22 Sep 2015 21:29:13 +0800 Subject: [PATCH 11/17] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../paoding/rose/jade/plugin/sql/mapper/AbstractMapper.java | 5 +++++ .../paoding/rose/jade/plugin/sql/mapper/EntityMapper.java | 4 ++++ .../paoding/rose/jade/plugin/sql/mapper/OperationMapper.java | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/AbstractMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/AbstractMapper.java index 2a8f2f5..04137cc 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/AbstractMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/AbstractMapper.java @@ -3,6 +3,9 @@ */ package net.paoding.rose.jade.plugin.sql.mapper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import net.paoding.rose.jade.plugin.sql.util.PlumUtils; /** @@ -21,6 +24,8 @@ public abstract class AbstractMapper implements IMapper { public static final char SEPARATOR = '_'; + protected static Log logger = LogFactory.getLog(IMapper.class); + public AbstractMapper(O original) { this.original = original; } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java index c69031e..642dcbc 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java @@ -44,6 +44,10 @@ protected void doMap() { this.primaryKey = new ArrayList(1); for(IColumnMapper col : columns) { + if(this.columnsMap.containsKey(col.getOriginal().getName())) { + logger.info("More than one name is " + col.getOriginal().getName() + " field was found, the nearest will be received."); + } + if(col.isPrimaryKey()) { primaryKey.add(col); } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java index 4e04a4f..0667f15 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java @@ -121,7 +121,7 @@ protected Class resolveParameterType(Type type) { // GenericDAO中的非集合泛型参数,或许是主键或许是实体。 GenericDeclaration genericDeclaration = ((TypeVariable) type).getGenericDeclaration(); - if(genericDeclaration == GenericDAO.class) { + if(GenericDAO.class.isAssignableFrom((Class)genericDeclaration)) { Type[] bounds = ((TypeVariable) type).getBounds(); if(bounds[0] == Object.class) { From 8d8a6b6b23c5c2f9b0386afd37c4706a2fdbb18a Mon Sep 17 00:00:00 2001 From: "Alan.Geng" Date: Fri, 25 Sep 2015 02:05:32 +0800 Subject: [PATCH 12/17] =?UTF-8?q?=E5=A2=9E=E5=8A=A0oracle=E6=94=AF?= =?UTF-8?q?=E6=8C=81=EF=BC=8C=E8=BF=98=E5=AD=98=E5=9C=A8bug=EF=BC=8C?= =?UTF-8?q?=E6=AD=A3=E5=9C=A8=E4=BF=AE=E5=A4=8D=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 135 ++++++++------- .../rose/jade/plugin/sql/GenericDAO.java | 2 +- .../jade/plugin/sql/annotations/Offset.java | 2 +- .../jade/plugin/sql/dialect/MySQLDialect.java | 6 +- .../plugin/sql/dialect/OracleDialect.java | 45 +++++ .../sql/dialect/mysql/SelectGenerator.java | 126 ++------------ .../sql/dialect/oracle/SelectGenerator.java | 82 +++++++++ .../standard/AbstractSelectGenerator.java | 159 ++++++++++++++++++ .../ConditionalGenerator.java | 19 ++- .../{mysql => standard}/DeleteGenerator.java | 8 +- .../{mysql => standard}/InsertGenerator.java | 2 +- .../{mysql => standard}/UpdateGenerator.java | 95 +---------- .../plugin/sql/id/AutoIncrementProcessor.java | 53 ++++-- .../jade/plugin/sql/mapper/EntityMapper.java | 10 ++ .../jade/plugin/sql/mapper/IEntityMapper.java | 2 + .../plugin/sql/PlumOracleSelectTestCase.java | 30 ++++ .../jade/plugin/sql/oracle/dao/ItemDAO.java | 26 +++ .../jade/plugin/sql/oracle/model/Item.java | 38 +++++ src/test/resources/junit-test.spring.xml | 9 +- 19 files changed, 557 insertions(+), 292 deletions(-) create mode 100644 src/main/java/net/paoding/rose/jade/plugin/sql/dialect/OracleDialect.java create mode 100644 src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java create mode 100644 src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/AbstractSelectGenerator.java rename src/main/java/net/paoding/rose/jade/plugin/sql/dialect/{mysql => standard}/ConditionalGenerator.java (85%) rename src/main/java/net/paoding/rose/jade/plugin/sql/dialect/{mysql => standard}/DeleteGenerator.java (71%) rename src/main/java/net/paoding/rose/jade/plugin/sql/dialect/{mysql => standard}/InsertGenerator.java (98%) rename src/main/java/net/paoding/rose/jade/plugin/sql/dialect/{mysql => standard}/UpdateGenerator.java (60%) create mode 100644 src/test/java/net/paoding/rose/jade/plugin/sql/PlumOracleSelectTestCase.java create mode 100644 src/test/java/net/paoding/rose/jade/plugin/sql/oracle/dao/ItemDAO.java create mode 100644 src/test/java/net/paoding/rose/jade/plugin/sql/oracle/model/Item.java diff --git a/pom.xml b/pom.xml index f0c2136..c618997 100644 --- a/pom.xml +++ b/pom.xml @@ -1,66 +1,81 @@ - - - 4.0.0 - net.paoding - jade-plugin-sql - jar - 0.0.1-SNAPSHOT - jade-plugin-sql + + + 4.0.0 + net.paoding + jade-plugin-sql + jar + 0.0.1-SNAPSHOT + jade-plugin-sql - - - net.paoding - paoding-rose-parent - 2.0.u06 - + + + net.paoding + paoding-rose-parent + 2.0.u08 + - - - - 耿直Alan.Geng - gengzhi718@gmail.com - - - + + + + 耿直Alan.Geng + gengzhi718@gmail.com + + - - - scm:git:git@github.com:paoding-code/jade-plugin-sql.git - scm:git:git@github.com:paoding-code/jade-plugin-sql.git - git@github.com:paoding-code/jade-plugin-sql.git - - - - - - 18.0 - 1.2.6 - - - - - net.paoding - paoding-rose-jade - - - com.google.guava - guava - ${guava.version} - + + + scm:git:git@github.com:paoding-code/jade-plugin-sql.git + scm:git:git@github.com:paoding-code/jade-plugin-sql.git + git@github.com:paoding-code/jade-plugin-sql.git + - - - com.alibaba - fastjson - ${fastjson.version} - test - - - org.hsqldb - hsqldb - ${hsqldb.version} - test - - + + + + 18.0 + 1.2.6 + 11.2.0.3 + + + + + + net.paoding + paoding-rose-jade + + + com.google.guava + guava + ${guava.version} + + + + + com.alibaba + fastjson + ${fastjson.version} + test + + + org.hsqldb + hsqldb + ${hsqldb.version} + test + + + com.oracle + ojdbc6 + ${oracle.version} + test + + + + + + codelds + https://code.lds.org/nexus/content/groups/main-repo + + diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/GenericDAO.java b/src/main/java/net/paoding/rose/jade/plugin/sql/GenericDAO.java index 3dc2efc..141f363 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/GenericDAO.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/GenericDAO.java @@ -29,7 +29,7 @@ public interface GenericDAO { * * @return auto increment id */ - @ReturnGeneratedKeys + @ReturnGeneratedKeys(AutoIncrementProcessor.class) @AfterInvocation(AutoIncrementProcessor.class) ID save(@SQLParam("entity") E entity); diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/annotations/Offset.java b/src/main/java/net/paoding/rose/jade/plugin/sql/annotations/Offset.java index 75c0528..60a1007 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/annotations/Offset.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/annotations/Offset.java @@ -9,7 +9,7 @@ import java.lang.annotation.Target; /** - * 查询数据的偏移量 + * 查询数据的偏移量,从0开始。 * @author Alan.Geng[gengzhi718@gmail.com] */ @Target(ElementType.PARAMETER) diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/MySQLDialect.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/MySQLDialect.java index 2c50bb7..e007382 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/MySQLDialect.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/MySQLDialect.java @@ -6,10 +6,10 @@ import java.util.HashMap; import java.util.Map; -import net.paoding.rose.jade.plugin.sql.dialect.mysql.DeleteGenerator; -import net.paoding.rose.jade.plugin.sql.dialect.mysql.InsertGenerator; import net.paoding.rose.jade.plugin.sql.dialect.mysql.SelectGenerator; -import net.paoding.rose.jade.plugin.sql.dialect.mysql.UpdateGenerator; +import net.paoding.rose.jade.plugin.sql.dialect.standard.DeleteGenerator; +import net.paoding.rose.jade.plugin.sql.dialect.standard.InsertGenerator; +import net.paoding.rose.jade.plugin.sql.dialect.standard.UpdateGenerator; import net.paoding.rose.jade.plugin.sql.mapper.IOperationMapper; import net.paoding.rose.jade.statement.StatementRuntime; diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/OracleDialect.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/OracleDialect.java new file mode 100644 index 0000000..87580d7 --- /dev/null +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/OracleDialect.java @@ -0,0 +1,45 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql.dialect; + +import java.util.HashMap; +import java.util.Map; + +import net.paoding.rose.jade.plugin.sql.dialect.oracle.SelectGenerator; +import net.paoding.rose.jade.plugin.sql.dialect.standard.DeleteGenerator; +import net.paoding.rose.jade.plugin.sql.dialect.standard.InsertGenerator; +import net.paoding.rose.jade.plugin.sql.dialect.standard.UpdateGenerator; +import net.paoding.rose.jade.plugin.sql.mapper.IOperationMapper; +import net.paoding.rose.jade.statement.StatementRuntime; + +/** + * @author Alan + * + */ +public class OracleDialect implements IDialect { + +private Map> generators; + + public OracleDialect() { + generators = new HashMap>(); + generators.put(IOperationMapper.OPERATION_SELECT, new SelectGenerator()); + generators.put(IOperationMapper.OPERATION_INSERT, new InsertGenerator()); + generators.put(IOperationMapper.OPERATION_UPDATE, new UpdateGenerator()); + generators.put(IOperationMapper.OPERATION_DELETE, new DeleteGenerator()); + } + + /* (non-Javadoc) + * @see com.cainiao.depot.project.biz.common.jade.dialect.IDialect#translate(com.cainiao.depot.project.biz.common.jade.mapper.IOperationMapper) + */ + @SuppressWarnings("unchecked") + @Override + public String translate(T operation, StatementRuntime runtime) { + ISQLGenerator gen = (ISQLGenerator) generators.get(operation.getName()); + if(gen != null) { + return gen.generate(operation, runtime); + } + return null; + } + +} diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/SelectGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/SelectGenerator.java index 07e2f07..d6b61d9 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/SelectGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/SelectGenerator.java @@ -3,133 +3,25 @@ */ package net.paoding.rose.jade.plugin.sql.dialect.mysql; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; import java.util.Map; -import net.paoding.rose.jade.plugin.sql.Order; -import net.paoding.rose.jade.plugin.sql.Order.Direction; -import net.paoding.rose.jade.plugin.sql.Order.Group; +import net.paoding.rose.jade.plugin.sql.dialect.standard.AbstractSelectGenerator; import net.paoding.rose.jade.plugin.sql.mapper.ConditionalOperationMapper; -import net.paoding.rose.jade.plugin.sql.mapper.IColumnMapper; -import net.paoding.rose.jade.plugin.sql.mapper.IEntityMapper; import net.paoding.rose.jade.statement.StatementRuntime; /** * @author Alan.Geng[gengzhi718@gmail.com] * */ -public class SelectGenerator extends ConditionalGenerator { +public class SelectGenerator extends AbstractSelectGenerator { - private static final Map DIRECTIONS; - - static { - Map directions = new HashMap(2); - directions.put(Direction.ASC, "ASC"); - directions.put(Direction.DESC, "DESC"); - - DIRECTIONS = Collections.unmodifiableMap(directions); - } - - @Override - protected void beforeApplyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { - super.beforeApplyConditions(operationMapper, runtime, sql); - IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); - sql.append(operationMapper.getName()); - sql.append(" "); - - if(operationMapper.isCountQuery()) { - sql.append("COUNT(*)"); - } else { - List columns = targetEntityMapper.getColumns(); - - for(IColumnMapper col : columns) { - String name = col.getName(); - sql.append(name); - sql.append(","); - } - - sql.setLength(sql.length() - 1); - } - - sql.append(" FROM "); - sql.append(targetEntityMapper.getName()); - } - - @Override - protected void afterApplyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { - super.afterApplyConditions(operationMapper, runtime, sql); - - if(!operationMapper.isCountQuery()) { - // 节省数据库性能开销,count操作不需要orderBy。 - applyOrderBy(operationMapper, runtime, sql); - } - - applyRange(operationMapper, runtime, sql); - } - - protected void applyOrderBy(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { - if(operationMapper.containsOrder() - && !operationMapper.isPrimaryKeyMode()) { - IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); - - Order order = null; - Integer orderParameterIndex = operationMapper.getOrderParameterIndex(); - - if(orderParameterIndex == -1) { - order = targetEntityMapper.getDefaultOrder(); - } else { - Object value = runtime.getParameters().get(":" + (operationMapper.getOrderParameterIndex() + 1)); - order = (Order) value; - } - - sql.append(" ORDER BY "); - - List groups = order.getGroups(); - - if(groups.size() > 0) { - for(Group group : groups) { - String[] fields = group.getFields(); - - for(String field : fields) { - IColumnMapper col = targetEntityMapper.getColumnMapperByFieldName(field); - - if(col != null) { - - sql.append(col.getName()); - sql.append(" "); - sql.append(DIRECTIONS.get(group.getDirection())); - sql.append(","); - } else { - throw new IllegalArgumentException("Cannot find column by field name \"" + field + "\"."); - } - } - } - - sql.setLength(sql.length() - 1); - } - } - } - - protected void applyRange(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { + protected StringBuilder applyRange(ConditionalOperationMapper operationMapper, + StatementRuntime runtime, + StringBuilder sql, + Long offset, + Long limit) { Map parameters = runtime.getParameters(); - Number offset = null; - Number limit = null; - - if(operationMapper.containsOffset()) { - offset = (Number) parameters.get(":" + (operationMapper.getOffsetParameterIndex() + 1)); - } - - if(operationMapper.containsLimit()) { - limit = (Number) parameters.get(":" + (operationMapper.getLimitParameterIndex() + 1)); - } - - if(limit == null && offset == null) { - return; - } - sql.append(" LIMIT :__offset, :__limit"); if(limit != null && offset != null) { @@ -138,9 +30,11 @@ protected void applyRange(ConditionalOperationMapper operationMapper, StatementR } else if(offset != null) { parameters.put("__offset", offset); parameters.put("__limit", -1); - } else if(limit != null && limit.longValue() >= 0) { + } else if(limit != null && limit >= 0) { parameters.put("__offset", 0); parameters.put("__limit", limit); } + + return sql; } } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java new file mode 100644 index 0000000..123e7c5 --- /dev/null +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java @@ -0,0 +1,82 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql.dialect.oracle; + +import java.util.Map; + +import net.paoding.rose.jade.plugin.sql.dialect.standard.AbstractSelectGenerator; +import net.paoding.rose.jade.plugin.sql.mapper.ConditionalOperationMapper; +import net.paoding.rose.jade.statement.StatementRuntime; + +/** + * @author Alan + * + */ +public class SelectGenerator extends AbstractSelectGenerator { + + protected static final String ROWNUM_ALIAS = "RN"; + + /* (non-Javadoc) + * @see net.paoding.rose.jade.plugin.sql.dialect.standard.AbstractSelectGenerator#applyRange(net.paoding.rose.jade.plugin.sql.mapper.ConditionalOperationMapper, net.paoding.rose.jade.statement.StatementRuntime, java.lang.StringBuilder, java.lang.Number, java.lang.Number) + */ + @Override + protected StringBuilder applyRange(ConditionalOperationMapper operationMapper, + StatementRuntime runtime, StringBuilder sql, Long offset, + Long limit) { + + Map parameters = runtime.getParameters(); + + // 在Oracle数据库版本12g之前,limit与offset通过ROWNUM计算,且offset必须使用子查询。 + Long realOffset = null; + Long realLimit = null; + + if(offset != null) { + realOffset = offset + 1; + } + if(limit != null) { + realLimit = limit + 1; + } + + if(limit != null && limit > 0) { + sql.append(" ROWNUM < :__limit"); + parameters.put("__limit", realLimit); + } + + if(offset != null && offset > 1) { + StringBuilder outerSql = new StringBuilder(operationMapper.getName()); + outerSql.append(" "); + applyColumns(operationMapper.getTargetEntityMapper(), outerSql); + + outerSql.append(" FROM ("); + outerSql.append(sql); + outerSql.append(") WHERE "); + outerSql.append(ROWNUM_ALIAS); + outerSql.append(" >= :__offset"); + + parameters.put("__offset", realOffset + realLimit); + + sql = outerSql; + } + + return sql; + } + + @Override + protected void applyColumns(ConditionalOperationMapper operationMapper, StatementRuntime runtime, + StringBuilder sql) { + super.applyColumns(operationMapper, runtime, sql); + + if(!operationMapper.isCountQuery() + && operationMapper.containsOffset()) { + Number val = (Number) runtime.getParameters().get(":" + (operationMapper.getOffsetParameterIndex() + 1)); + if(val != null + && val.longValue() > 1) { + // 提供给外部查询做偏移量判定 + sql.append(", ROWNUM "); + sql.append(ROWNUM_ALIAS); + } + } + } + +} diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/AbstractSelectGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/AbstractSelectGenerator.java new file mode 100644 index 0000000..e4904f0 --- /dev/null +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/AbstractSelectGenerator.java @@ -0,0 +1,159 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql.dialect.standard; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.paoding.rose.jade.plugin.sql.Order; +import net.paoding.rose.jade.plugin.sql.Order.Direction; +import net.paoding.rose.jade.plugin.sql.Order.Group; +import net.paoding.rose.jade.plugin.sql.dialect.standard.ConditionalGenerator; +import net.paoding.rose.jade.plugin.sql.mapper.ConditionalOperationMapper; +import net.paoding.rose.jade.plugin.sql.mapper.IColumnMapper; +import net.paoding.rose.jade.plugin.sql.mapper.IEntityMapper; +import net.paoding.rose.jade.statement.StatementRuntime; + +/** + * @author Alan.Geng[gengzhi718@gmail.com] + * + */ +public abstract class AbstractSelectGenerator extends ConditionalGenerator { + + private static final Map DIRECTIONS; + + static { + Map directions = new HashMap(2); + directions.put(Direction.ASC, "ASC"); + directions.put(Direction.DESC, "DESC"); + + DIRECTIONS = Collections.unmodifiableMap(directions); + } + + @Override + protected StringBuilder beforeApplyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { + super.beforeApplyConditions(operationMapper, runtime, sql); + IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); + sql.append(operationMapper.getName()); + sql.append(" "); + + applyColumns(operationMapper, runtime, sql); + + sql.append(" FROM "); + sql.append(targetEntityMapper.getName()); + + return sql; + } + + protected void applyColumns(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { + IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); + if(operationMapper.isCountQuery()) { + sql.append("COUNT(*)"); + } else { + applyColumns(targetEntityMapper, sql); + } + } + + protected void applyColumns(IEntityMapper targetEntityMapper, StringBuilder sql) { + List columns = targetEntityMapper.getColumns(); + + for(IColumnMapper col : columns) { + String name = col.getName(); + sql.append(name); + sql.append(" "); + sql.append(col.getOriginal().getName()); + sql.append(","); + } + + sql.setLength(sql.length() - 1); + } + + @Override + protected StringBuilder afterApplyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { + super.afterApplyConditions(operationMapper, runtime, sql); + + if(!operationMapper.isCountQuery()) { + // 节省数据库性能开销,count操作不需要orderBy。 + sql = applyOrderBy(operationMapper, runtime, sql); + } + + Map parameters = runtime.getParameters(); + + Long offset = null; + Long limit = null; + + if(operationMapper.containsOffset()) { + Number val = (Number) parameters.get(":" + (operationMapper.getOffsetParameterIndex() + 1)); + if(val != null) { + offset = val.longValue(); + } + } + + if(operationMapper.containsLimit()) { + Number val = (Number) parameters.get(":" + (operationMapper.getLimitParameterIndex() + 1)); + if(val != null) { + limit = val.longValue(); + } + } + + if(limit != null || offset != null) { + sql = applyRange(operationMapper, runtime, sql, offset, limit); + } + + return sql; + } + + protected StringBuilder applyOrderBy(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { + if(operationMapper.containsOrder() + && !operationMapper.isPrimaryKeyMode()) { + IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); + + Order order = null; + Integer orderParameterIndex = operationMapper.getOrderParameterIndex(); + + if(orderParameterIndex == -1) { + order = targetEntityMapper.getDefaultOrder(); + } else { + Object value = runtime.getParameters().get(":" + (operationMapper.getOrderParameterIndex() + 1)); + order = (Order) value; + } + + sql.append(" ORDER BY "); + + List groups = order.getGroups(); + + if(groups.size() > 0) { + for(Group group : groups) { + String[] fields = group.getFields(); + + for(String field : fields) { + IColumnMapper col = targetEntityMapper.getColumnMapperByFieldName(field); + + if(col != null) { + + sql.append(col.getName()); + sql.append(" "); + sql.append(DIRECTIONS.get(group.getDirection())); + sql.append(","); + } else { + throw new IllegalArgumentException("Cannot find column by field name \"" + field + "\"."); + } + } + } + + sql.setLength(sql.length() - 1); + } + } + + return sql; + } + + protected abstract StringBuilder applyRange(ConditionalOperationMapper operationMapper, + StatementRuntime runtime, + StringBuilder sql, + Long offset, + Long limit); +} diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/ConditionalGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/ConditionalGenerator.java similarity index 85% rename from src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/ConditionalGenerator.java rename to src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/ConditionalGenerator.java index 6668939..e991a8c 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/ConditionalGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/ConditionalGenerator.java @@ -1,7 +1,7 @@ /** * */ -package net.paoding.rose.jade.plugin.sql.dialect.mysql; +package net.paoding.rose.jade.plugin.sql.dialect.standard; import java.util.Collections; import java.util.HashMap; @@ -41,13 +41,13 @@ public abstract class ConditionalGenerator implements ISQLGenerator primaryKey = operationMapper.getTargetEntityMapper().getPrimaryKey(); @@ -92,6 +92,7 @@ protected void applyConditions(ConditionalOperationMapper operationMapper, State } else { throw new UnsupportedOperationException("Unknown condition mode."); } + return sql; } protected String generateCondition(ConditionalOperationMapper operationMapper, IParameterMapper param, StatementRuntime runtime, int index) { @@ -146,12 +147,12 @@ protected String generateCondition(ConditionalOperationMapper operationMapper, I return sql.toString(); } - protected void beforeApplyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { - + protected StringBuilder beforeApplyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { + return sql; } - protected void afterApplyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { - + protected StringBuilder afterApplyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { + return sql; } } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/DeleteGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/DeleteGenerator.java similarity index 71% rename from src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/DeleteGenerator.java rename to src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/DeleteGenerator.java index 2340783..1c0fb50 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/DeleteGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/DeleteGenerator.java @@ -1,7 +1,7 @@ /** * */ -package net.paoding.rose.jade.plugin.sql.dialect.mysql; +package net.paoding.rose.jade.plugin.sql.dialect.standard; import net.paoding.rose.jade.plugin.sql.mapper.ConditionalOperationMapper; import net.paoding.rose.jade.statement.StatementRuntime; @@ -13,13 +13,15 @@ public class DeleteGenerator extends ConditionalGenerator { @Override - protected void beforeApplyConditions( + protected StringBuilder beforeApplyConditions( ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { - super.beforeApplyConditions(operationMapper, runtime, sql); + sql = super.beforeApplyConditions(operationMapper, runtime, sql); sql.append("DELETE FROM "); sql.append(operationMapper.getTargetEntityMapper().getName()); + + return sql; } } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/InsertGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/InsertGenerator.java similarity index 98% rename from src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/InsertGenerator.java rename to src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/InsertGenerator.java index 098ca2e..0b89394 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/InsertGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/InsertGenerator.java @@ -1,7 +1,7 @@ /** * */ -package net.paoding.rose.jade.plugin.sql.dialect.mysql; +package net.paoding.rose.jade.plugin.sql.dialect.standard; import java.util.List; diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/UpdateGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/UpdateGenerator.java similarity index 60% rename from src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/UpdateGenerator.java rename to src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/UpdateGenerator.java index d394856..3ed7678 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/UpdateGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/UpdateGenerator.java @@ -1,7 +1,7 @@ /** * */ -package net.paoding.rose.jade.plugin.sql.dialect.mysql; +package net.paoding.rose.jade.plugin.sql.dialect.standard; import java.lang.reflect.Field; import java.util.List; @@ -25,17 +25,19 @@ public class UpdateGenerator extends ConditionalGenerator { @Override - protected void beforeApplyConditions( + protected StringBuilder beforeApplyConditions( ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { - super.beforeApplyConditions(operationMapper, runtime, sql); + sql = super.beforeApplyConditions(operationMapper, runtime, sql); sql.append("UPDATE "); sql.append(operationMapper.getTargetEntityMapper().getName()); + + return sql; } @Override - public void applyConditions(ConditionalOperationMapper operationMapper, + public StringBuilder applyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { if(operationMapper.isEntityMode() || operationMapper.isEntityCollectionMode()) { @@ -144,89 +146,10 @@ public void applyConditions(ConditionalOperationMapper operationMapper, if(sql.charAt(sql.length() - 1) == ',') { sql.setLength(sql.length() - 1); } - super.applyConditions(operationMapper, runtime, sql); - } - } - - /* (non-Javadoc) - * @see com.cainiao.depot.project.biz.common.jade.dialect.ISQLGenerator#generate(com.cainiao.depot.project.biz.common.jade.mapper.IOperationMapper) - */ - /* - @Override - public String generate(OperationMapper operationMapper, StatementRuntime runtime) { - Map params = runtime.getParameters(); - if(!operationMapper.getName().equals(IOperationMapper.OPERATION_UPDATE)) { - throw new InvalidDataAccessApiUsageException("Operation mapper must be a update."); - } - - List parameters = operationMapper.getParameters(); - if(MyLangUtils.isEmpty(parameters)) { - throw new InvalidDataAccessApiUsageException("Update operation must have parameters."); + sql = super.applyConditions(operationMapper, runtime, sql); } - IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); - - if(parameters.size() == 1 && parameters.get(0).getType().equals(targetEntityMapper.getOriginal())) { - StringBuilder sql = new StringBuilder(256); - sql.append("UPDATE "); - StringBuilder where = new StringBuilder(32); - sql.append(targetEntityMapper.getName()); - - IParameterMapper param = parameters.get(0); - - if(param instanceof IExpandableParameterMapper) { - List expandParams = ((IExpandableParameterMapper) param).expand(); - Object entityObject = params.entrySet().iterator().next().getValue(); - - sql.append(" SET"); - try { - for(IParameterMapper p : expandParams) { - IColumnMapper columnMapper = p.getColumnMapper(); - if(columnMapper != null) { - Field field = p.getColumnMapper().getOriginal(); - Object value = field.get(entityObject); - if(p.getColumnMapper().isPrimaryKey()) { - // 主键视为条件 - if(value == null) { - throw new IllegalArgumentException("Cannot execute update, primary key \"" + p.getColumnMapper().getName() + "\" must not be null."); - } - - if(where.length() > 0) { - where.append(" AND "); - } else { - where.append(" WHERE "); - } - - where.append(p.getName()); - where.append(" = :"); - where.append(p.getOriginalName()); - } else { - if(value != null) { - sql.append(" "); - sql.append(p.getName()); - sql.append(" = "); - sql.append(":"); - sql.append(p.getOriginalName()); - sql.append(","); - } - } - } - } - sql.setLength(sql.length() - 1); - sql.append(where); - } catch(IllegalArgumentException e) { - throw new InvalidDataAccessApiUsageException("", e); - } catch (Exception e) { - throw new InvalidDataAccessApiUsageException("Cannot generate sql.", e); - } - } else { - throw new InvalidDataAccessApiUsageException("Auto update operation parameter must be a expandable."); - } - - return sql.toString(); - } else { - throw new InvalidDataAccessApiUsageException("Please use the entity object to update."); - } + return sql; } - */ + } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java b/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java index e3c5c10..d8fe822 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java @@ -14,13 +14,15 @@ import net.paoding.rose.jade.plugin.sql.mapper.IEntityMapper; import net.paoding.rose.jade.plugin.sql.mapper.IOperationMapper; import net.paoding.rose.jade.statement.AfterInvocationCallback; +import net.paoding.rose.jade.statement.DynamicReturnGeneratedKeys; +import net.paoding.rose.jade.statement.StatementMetaData; import net.paoding.rose.jade.statement.StatementRuntime; /** * @author cunxin.gz * */ -public class AutoIncrementProcessor implements AfterInvocationCallback { +public class AutoIncrementProcessor extends DynamicReturnGeneratedKeys implements AfterInvocationCallback { private Log logger = LogFactory.getLog(getClass()); @@ -35,18 +37,21 @@ public Object execute(StatementRuntime runtime, Object returnValue) { if(IOperationMapper.OPERATION_INSERT.equals(operationMapper.getName())) { IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); - String paramName = operationMapper.getParameters().get(0).getName(); - if(returnValue.getClass().isArray()) { + if(targetEntityMapper.containsAutoIncrementPrimaryKey()) { + String paramName = operationMapper.getParameters().get(0).getName(); - } else { - Object param = runtime.getParameters().get(paramName); - List primaryKey = targetEntityMapper.getPrimaryKey(); - IColumnMapper iColumnMapper = primaryKey.get(0); - try { - iColumnMapper.getOriginal().set(param, returnValue); - } catch (Exception e) { - logger.error("Error to set auto increment value to entity object.", e); + if(returnValue.getClass().isArray()) { + + } else { + Object param = runtime.getParameters().get(paramName); + List primaryKey = targetEntityMapper.getPrimaryKey(); + IColumnMapper iColumnMapper = primaryKey.get(0); + try { + iColumnMapper.getOriginal().set(param, returnValue); + } catch (Exception e) { + logger.error("Error to set auto increment value to entity object.", e); + } } } } @@ -55,4 +60,30 @@ public Object execute(StatementRuntime runtime, Object returnValue) { return returnValue; } + @Override + public boolean shouldReturnGerneratedKeys(StatementRuntime runtime) { + return isAutoIncrementPrimaryKey(runtime.getMetaData()); + } + + @Override + public void checkMethodReturnType(Class returnType, StatementMetaData metaData) { + if(isAutoIncrementPrimaryKey(metaData)) { + super.checkMethodReturnType(returnType, metaData); + } + } + + private boolean isAutoIncrementPrimaryKey(StatementMetaData metaData) { + SQLGeneratorInterpreter attribute = metaData.getAttribute(PlumSQLInterpreter.ATTRIBUTE_NAME_INTERPRETER); + + if(attribute != null) { + IOperationMapper operationMapper = attribute.getOperationMapper(); + + if(IOperationMapper.OPERATION_INSERT.equals(operationMapper.getName())) { + IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); + return targetEntityMapper.containsAutoIncrementPrimaryKey(); + } + } + return false; + } + } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java index 642dcbc..fedc2c7 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java @@ -14,6 +14,7 @@ import net.paoding.rose.jade.plugin.sql.Plum; import net.paoding.rose.jade.plugin.sql.annotations.Column; import net.paoding.rose.jade.plugin.sql.annotations.Table; +import net.paoding.rose.jade.plugin.sql.id.NativeGenerator; import net.paoding.rose.jade.plugin.sql.util.PlumUtils; /** @@ -32,6 +33,8 @@ public class EntityMapper extends AbstractMapper> implements IEntityMap private Order defaultOrder; + private boolean containsAutoIncrementPrimaryKey; + public EntityMapper(Class from) { super(from); } @@ -50,6 +53,9 @@ protected void doMap() { if(col.isPrimaryKey()) { primaryKey.add(col); + if(col.getIDGeneratorType() == NativeGenerator.class) { + containsAutoIncrementPrimaryKey = true; + } } if(col.getDefaultOrderDirection() != Direction.NONE) { if(defaultOrder == null) { @@ -126,4 +132,8 @@ public Order getDefaultOrder() { return defaultOrder; } + public boolean containsAutoIncrementPrimaryKey() { + return containsAutoIncrementPrimaryKey; + } + } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IEntityMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IEntityMapper.java index abe73a4..3965cb2 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IEntityMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IEntityMapper.java @@ -20,4 +20,6 @@ public interface IEntityMapper extends IMapper> { IColumnMapper getColumnMapperByFieldName(String fieldName); Order getDefaultOrder(); + + boolean containsAutoIncrementPrimaryKey(); } diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumOracleSelectTestCase.java b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumOracleSelectTestCase.java new file mode 100644 index 0000000..365d7db --- /dev/null +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumOracleSelectTestCase.java @@ -0,0 +1,30 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql; + +import java.util.List; + +import net.paoding.rose.jade.plugin.sql.oracle.dao.ItemDAO; +import net.paoding.rose.jade.plugin.sql.oracle.model.Item; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.alibaba.fastjson.JSON; + +/** + * @author Alan + * + */ +public class PlumOracleSelectTestCase extends AbstractTestCase { + + @Autowired + private ItemDAO itemDAO; + + public void testFindByName() { + String name = "%可乐%"; + List items = itemDAO.findByName(name, 10L, 10L); + + System.out.println(JSON.toJSONString(items)); + } +} diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/oracle/dao/ItemDAO.java b/src/test/java/net/paoding/rose/jade/plugin/sql/oracle/dao/ItemDAO.java new file mode 100644 index 0000000..371f3f2 --- /dev/null +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/oracle/dao/ItemDAO.java @@ -0,0 +1,26 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql.oracle.dao; + +import java.util.List; + +import net.paoding.rose.jade.annotation.DAO; +import net.paoding.rose.jade.annotation.SQLParam; +import net.paoding.rose.jade.plugin.sql.GenericDAO; +import net.paoding.rose.jade.plugin.sql.annotations.Limit; +import net.paoding.rose.jade.plugin.sql.annotations.Offset; +import net.paoding.rose.jade.plugin.sql.oracle.model.Item; + +/** + * @author Alan + * + */ +@DAO +public interface ItemDAO extends GenericDAO { + + List findByName( + @SQLParam("color") String name, + @Offset Long offset, + @Limit Long limit); +} diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/oracle/model/Item.java b/src/test/java/net/paoding/rose/jade/plugin/sql/oracle/model/Item.java new file mode 100644 index 0000000..5b51d6f --- /dev/null +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/oracle/model/Item.java @@ -0,0 +1,38 @@ +/** + * + */ +package net.paoding.rose.jade.plugin.sql.oracle.model; + +import net.paoding.rose.jade.plugin.sql.annotations.Column; +import net.paoding.rose.jade.plugin.sql.annotations.Table; + +/** + * @author Alan + * + */ +@Table("\"MIRACLE\".\"goods_details\"") +public class Item { + + @Column("\"id\"") + private Long id; + + @Column("\"color\"") + private String color; + + public void setId(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + +} diff --git a/src/test/resources/junit-test.spring.xml b/src/test/resources/junit-test.spring.xml index 5f9a0c2..d1a5cf4 100644 --- a/src/test/resources/junit-test.spring.xml +++ b/src/test/resources/junit-test.spring.xml @@ -14,6 +14,13 @@ + + + + + + + @@ -21,7 +28,7 @@ - + From 9c7d5734b6d9b0c81826637faf5a61c8742ff6f8 Mon Sep 17 00:00:00 2001 From: "Alan.Geng" Date: Sun, 27 Sep 2015 22:49:48 +0800 Subject: [PATCH 13/17] =?UTF-8?q?=E5=A2=9E=E5=8A=A0package=E5=9F=9F?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E8=A8=80=E6=94=AF=E6=8C=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jade/plugin/sql/PlumSQLInterpreter.java | 38 +++++++++++++++++++ .../sql/dialect/oracle/SelectGenerator.java | 21 +++++++--- .../standard/AbstractSelectGenerator.java | 6 ++- .../standard/ConditionalGenerator.java | 9 +++++ .../sql/mapper/ExpandableParameterMapper.java | 21 ++++------ .../mapper/IExpandableParameterMapper.java | 1 - .../plugin/sql/mapper/IParameterMapper.java | 3 ++ .../plugin/sql/mapper/OperationMapper.java | 17 ++------- .../plugin/sql/mapper/ParameterMapper.java | 24 ++++++++++-- .../plugin/sql/mapper/ParameterOriginal.java | 12 +++++- .../jade/plugin/sql/oracle/dao/ItemDAO.java | 7 +++- src/test/resources/junit-test.spring.xml | 5 ++- 12 files changed, 120 insertions(+), 44 deletions(-) diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java b/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java index 666276b..de05a65 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java @@ -4,6 +4,8 @@ package net.paoding.rose.jade.plugin.sql; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -45,6 +47,8 @@ public class PlumSQLInterpreter implements Interpreter, InitializingBean, Applic private IDialect dialect; + private Map packageScopeDialect; + public static final String ATTRIBUTE_NAME_INTERPRETER = "jade-plugin-sql.interpreter"; public static final String SQL_ANNOTATION_MARKUP = "jade-plugin-sql"; @@ -72,6 +76,9 @@ public void afterPropertiesSet() throws Exception { // 将来可能扩展点:不同的DAO可以有不同的Dialect哦,而且是自动知道,不需要外部设置。 dialect = new MySQLDialect(); } + + this.loadPackageRegionDialect(); + // if (logger.isInfoEnabled()) { String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(// @@ -81,6 +88,19 @@ public void afterPropertiesSet() throws Exception { } } + + public void loadPackageRegionDialect() { + String[] dialectBeanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext, IDialect.class); + for(String beanName : dialectBeanNames) { + if(packageScopeDialect == null) { + packageScopeDialect = new HashMap(); + } + + String packageName = beanName.substring("plum.dialect.".length()); + + packageScopeDialect.put(packageName, (IDialect) applicationContext.getBean(beanName)); + } + } /** * 对 {@link GenericDAO} 及其子DAO接口中没有注解@SQL或仅仅@SQL("")的方法进行解析,根据实际参数情况自动动态生成SQL语句 @@ -134,9 +154,27 @@ public void interpret(StatementRuntime runtime) { public class SQLGeneratorInterpreter implements Interpreter { final IOperationMapper operationMapper; + + private IDialect dialect; public SQLGeneratorInterpreter(IOperationMapper operationMapper) { this.operationMapper = operationMapper; + + if(packageScopeDialect != null) { + Class daoClass = operationMapper.getOriginal().getDAOMetaData().getDAOClass(); + String daoPkg = daoClass.getPackage().getName(); + while(daoPkg.contains(".") + && (dialect = packageScopeDialect.get(daoPkg)) == null) { + + // Find the package region dialect layer by layer. + daoPkg = daoPkg.substring(0, daoPkg.lastIndexOf(".")); + } + } + + if(dialect == null) { + // When miss the dialect in package region, use default. + dialect = PlumSQLInterpreter.this.dialect; + } } @Override diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java index 123e7c5..484ea1c 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java @@ -7,6 +7,7 @@ import net.paoding.rose.jade.plugin.sql.dialect.standard.AbstractSelectGenerator; import net.paoding.rose.jade.plugin.sql.mapper.ConditionalOperationMapper; +import net.paoding.rose.jade.plugin.sql.mapper.IColumnMapper; import net.paoding.rose.jade.statement.StatementRuntime; /** @@ -29,18 +30,17 @@ protected StringBuilder applyRange(ConditionalOperationMapper operationMapper, // 在Oracle数据库版本12g之前,limit与offset通过ROWNUM计算,且offset必须使用子查询。 Long realOffset = null; - Long realLimit = null; if(offset != null) { realOffset = offset + 1; } - if(limit != null) { - realLimit = limit + 1; - } if(limit != null && limit > 0) { + if(containsConditions()) { + sql.append(" AND "); + } sql.append(" ROWNUM < :__limit"); - parameters.put("__limit", realLimit); + parameters.put("__limit", realOffset + limit); } if(offset != null && offset > 1) { @@ -54,7 +54,7 @@ protected StringBuilder applyRange(ConditionalOperationMapper operationMapper, outerSql.append(ROWNUM_ALIAS); outerSql.append(" >= :__offset"); - parameters.put("__offset", realOffset + realLimit); + parameters.put("__offset", realOffset); sql = outerSql; } @@ -78,5 +78,14 @@ protected void applyColumns(ConditionalOperationMapper operationMapper, Statemen } } } + + @Override + protected String getColumnAlias(IColumnMapper column) { + if(column.getName().startsWith("\"") + && column.getName().endsWith("\"")) { + return "\"" + super.getColumnAlias(column) + "\""; + } + return super.getColumnAlias(column); + } } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/AbstractSelectGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/AbstractSelectGenerator.java index e4904f0..8ac9d37 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/AbstractSelectGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/AbstractSelectGenerator.java @@ -64,12 +64,16 @@ protected void applyColumns(IEntityMapper targetEntityMapper, StringBuilder sql) String name = col.getName(); sql.append(name); sql.append(" "); - sql.append(col.getOriginal().getName()); + sql.append(getColumnAlias(col)); sql.append(","); } sql.setLength(sql.length() - 1); } + + protected String getColumnAlias(IColumnMapper column) { + return column.getOriginalName(); + } @Override protected StringBuilder afterApplyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/ConditionalGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/ConditionalGenerator.java index e991a8c..0c3a556 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/ConditionalGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/ConditionalGenerator.java @@ -24,6 +24,8 @@ public abstract class ConditionalGenerator implements ISQLGenerator OPERATORS; + private boolean containsConditions = false; + static { Map operators = new HashMap(Operator.values().length); operators.put(Operator.EQ, " = "); @@ -65,6 +67,8 @@ protected StringBuilder applyConditions(ConditionalOperationMapper operationMapp // TODO:当实体为符合主键并且参数列表中的顺序与实体中字段顺序不一致,则会发生错误。 sql.append(i + 1); } + + containsConditions = true; } else if(operationMapper.isComplexMode()) { List parameters = operationMapper.getParameters(); if(PlumUtils.isNotEmpty(parameters)) { @@ -82,6 +86,7 @@ protected StringBuilder applyConditions(ConditionalOperationMapper operationMapp if(condition != null) { if(and.length() == 0) { sql.append(" WHERE "); + containsConditions = true; } sql.append(and); sql.append(condition); @@ -154,5 +159,9 @@ protected StringBuilder beforeApplyConditions(ConditionalOperationMapper operati protected StringBuilder afterApplyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { return sql; } + + protected boolean containsConditions() { + return containsConditions; + } } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ExpandableParameterMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ExpandableParameterMapper.java index 16935e8..7ef9624 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ExpandableParameterMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ExpandableParameterMapper.java @@ -3,25 +3,23 @@ */ package net.paoding.rose.jade.plugin.sql.mapper; +import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.List; -import net.paoding.rose.jade.annotation.SQLParam; - /** * @author Alan.Geng[gengzhi718@gmail.com] * */ public class ExpandableParameterMapper extends ParameterMapper implements IExpandableParameterMapper { - private EntityMapperManager entityMapperManager; - - private List expendedParameters; - - public ExpandableParameterMapper(IOperationMapper operationMapper, SQLParam original, Class type) { - super(operationMapper, original, type, null); + public ExpandableParameterMapper(IOperationMapper operationMapper, + Class type, Annotation[] annotations) { + super(operationMapper, type, annotations); } + private List expendedParameters; + @Override public void doMap() { super.doMap(); @@ -33,7 +31,7 @@ public void doMap() { } protected void mapExpendedParameterMapper() throws Exception { - IEntityMapper entityMapper = entityMapperManager.createGet((Class) getType()); + IEntityMapper entityMapper = getOperationMapper().getTargetEntityMapper(); if(entityMapper != null) { List columns = entityMapper.getColumns(); expendedParameters = new ArrayList(columns.size()); @@ -49,11 +47,6 @@ protected ParameterMapper createExpendedParameterMapper(IColumnMapper col) { return expended; } - @Override - public void setEntityMapperManager(EntityMapperManager entityMapperManager) { - this.entityMapperManager = entityMapperManager; - } - @Override public List expand() { return expendedParameters; diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IExpandableParameterMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IExpandableParameterMapper.java index 82e2c68..ba0f727 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IExpandableParameterMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IExpandableParameterMapper.java @@ -13,5 +13,4 @@ public interface IExpandableParameterMapper extends IParameterMapper { List expand(); - void setEntityMapperManager(EntityMapperManager entityMapperManager); } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IParameterMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IParameterMapper.java index 3354af6..f70bd2d 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IParameterMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IParameterMapper.java @@ -25,4 +25,7 @@ public interface IParameterMapper extends IMapper { boolean isIgnoreNull(); IgnoreNull getIgnoreNull(); + + IOperationMapper getOperationMapper(); + } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java index 0667f15..c06c83e 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java @@ -14,7 +14,6 @@ import java.util.Collections; import java.util.List; -import net.paoding.rose.jade.annotation.SQLParam; import net.paoding.rose.jade.plugin.sql.GenericDAO; import net.paoding.rose.jade.plugin.sql.Plum; import net.paoding.rose.jade.plugin.sql.annotations.IgnoreNull; @@ -144,24 +143,14 @@ protected Class resolveParameterType(Type type) { } protected IParameterMapper createParameterMapper(Class type, Annotation[] annotations, int index) { - SQLParam sp = null; - - if(annotations != null && annotations.length > 0) { - for(Annotation annotation : annotations) { - if(annotation.annotationType().equals(SQLParam.class)) { - sp = (SQLParam) annotation; - break; - } - } - } IParameterMapper param = null; if(isExpandableParameterType(type)) { - param = new ExpandableParameterMapper(this, sp, (Class) type); - ((ExpandableParameterMapper) param).setEntityMapperManager(entityMapperManager); + param = new ExpandableParameterMapper(this, type, annotations); } else { - param = new ParameterMapper(this, sp, type, annotations); + param = new ParameterMapper(this, type, annotations); } + param.map(); return param; diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ParameterMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ParameterMapper.java index 1799cb2..6cd2b1b 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ParameterMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ParameterMapper.java @@ -8,7 +8,6 @@ import java.util.HashMap; import java.util.Map; -import net.paoding.rose.jade.annotation.SQLParam; import net.paoding.rose.jade.plugin.sql.Plum; import net.paoding.rose.jade.plugin.sql.Plum.Operator; import net.paoding.rose.jade.plugin.sql.annotations.Eq; @@ -61,14 +60,18 @@ public class ParameterMapper extends AbstractMapper implement } public ParameterMapper(IParameterMapper parent, IColumnMapper columnMapper) { - super(new ParameterOriginal(null, columnMapper.getOriginal().getType(), null)); + super(new ParameterOriginal(columnMapper.getOriginal().getType(), null)); this.parent = parent; this.columnMapper = columnMapper; } - public ParameterMapper(IOperationMapper operationMapper, SQLParam original, Class type, Annotation[] annotations) { - super(new ParameterOriginal(original, type, annotations)); + public ParameterMapper(IOperationMapper operationMapper, Class type, Annotation[] annotations) { + super(new ParameterOriginal(type, annotations)); this.operationMapper = operationMapper; + + if(getOriginal().getSqlParam() != null) { + this.columnMapper = operationMapper.getTargetEntityMapper().getColumnMapperByFieldName(getOriginal().getName()); + } } @Override @@ -139,5 +142,18 @@ public IgnoreNull getIgnoreNull() { } return null; } + + @Override + public IOperationMapper getOperationMapper() { + return parent != null ? parent.getOperationMapper() : operationMapper; + } + + @Override + public String getName() { + if(columnMapper != null) { + return columnMapper.getName(); + } + return super.getName(); + } } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ParameterOriginal.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ParameterOriginal.java index c4b7bcc..6980f6c 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ParameterOriginal.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ParameterOriginal.java @@ -19,10 +19,18 @@ public class ParameterOriginal { private Annotation[] annotations; - public ParameterOriginal(SQLParam sqlParam, Class type, Annotation[] annotations) { - this.sqlParam = sqlParam; + public ParameterOriginal(Class type, Annotation[] annotations) { this.type = type; this.annotations = annotations; + + if(annotations != null && annotations.length > 0) { + for(Annotation annotation : annotations) { + if(annotation.annotationType().equals(SQLParam.class)) { + sqlParam = (SQLParam) annotation; + break; + } + } + } } public Class getType() { diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/oracle/dao/ItemDAO.java b/src/test/java/net/paoding/rose/jade/plugin/sql/oracle/dao/ItemDAO.java index 371f3f2..6215f4d 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/oracle/dao/ItemDAO.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/oracle/dao/ItemDAO.java @@ -8,6 +8,7 @@ import net.paoding.rose.jade.annotation.DAO; import net.paoding.rose.jade.annotation.SQLParam; import net.paoding.rose.jade.plugin.sql.GenericDAO; +import net.paoding.rose.jade.plugin.sql.annotations.Like; import net.paoding.rose.jade.plugin.sql.annotations.Limit; import net.paoding.rose.jade.plugin.sql.annotations.Offset; import net.paoding.rose.jade.plugin.sql.oracle.model.Item; @@ -20,7 +21,11 @@ public interface ItemDAO extends GenericDAO { List findByName( - @SQLParam("color") String name, + @SQLParam("color") @Like String name, @Offset Long offset, @Limit Long limit); + + List findByName( + @SQLParam("color") @Like String name, + @Limit Long limit); } diff --git a/src/test/resources/junit-test.spring.xml b/src/test/resources/junit-test.spring.xml index d1a5cf4..d36f5e2 100644 --- a/src/test/resources/junit-test.spring.xml +++ b/src/test/resources/junit-test.spring.xml @@ -28,8 +28,11 @@ - + + + \ No newline at end of file From f6ae070592972f612abe6b5e072efc49c2632aeb Mon Sep 17 00:00:00 2001 From: "Alan.Geng" Date: Sun, 27 Sep 2015 23:15:25 +0800 Subject: [PATCH 14/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BD=93offset?= =?UTF-8?q?=E4=B8=8D=E6=8C=87=E5=AE=9A=E6=97=B6=EF=BC=8C=E7=A9=BA=E6=8C=87?= =?UTF-8?q?=E9=92=88=E7=9A=84bug=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/sql/dialect/oracle/SelectGenerator.java | 4 ++++ .../rose/jade/plugin/sql/PlumOracleSelectTestCase.java | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java index 484ea1c..aa64386 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java @@ -31,6 +31,10 @@ protected StringBuilder applyRange(ConditionalOperationMapper operationMapper, // 在Oracle数据库版本12g之前,limit与offset通过ROWNUM计算,且offset必须使用子查询。 Long realOffset = null; + if(offset == null) { + offset = 0L; + } + if(offset != null) { realOffset = offset + 1; } diff --git a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumOracleSelectTestCase.java b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumOracleSelectTestCase.java index 365d7db..4588eb8 100644 --- a/src/test/java/net/paoding/rose/jade/plugin/sql/PlumOracleSelectTestCase.java +++ b/src/test/java/net/paoding/rose/jade/plugin/sql/PlumOracleSelectTestCase.java @@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; /** * @author Alan @@ -25,6 +26,13 @@ public void testFindByName() { String name = "%可乐%"; List items = itemDAO.findByName(name, 10L, 10L); - System.out.println(JSON.toJSONString(items)); + System.out.println(JSON.toJSONString(items, SerializerFeature.PrettyFormat)); + } + + public void testFindByName2() { + String name = "%可乐%"; + List items = itemDAO.findByName(name, 10L); + + System.out.println(JSON.toJSONString(items, SerializerFeature.PrettyFormat)); } } From 6edd6d1c4cd28c6915b7ff8bab63db53a4c7555c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BF=97=E4=BA=AE?= Date: Thu, 26 May 2016 14:28:35 +0800 Subject: [PATCH 15/17] =?UTF-8?q?Where=E4=B8=BB=E9=94=AE=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E7=9A=84=E5=A4=8D=E5=90=88=E4=B8=BB=E9=94=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E9=87=87=E7=94=A8=E5=8F=82=E6=95=B0=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原先在DAO方法中,参数的顺序关系和DO的列的关系要一致 现在改为使用参数名的方式指定,参数名要和DO中的字段名一致 --- .../plugin/sql/dialect/mysql/ConditionalGenerator.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/ConditionalGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/ConditionalGenerator.java index 6668939..1a3fc60 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/ConditionalGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/mysql/ConditionalGenerator.java @@ -62,8 +62,12 @@ protected void applyConditions(ConditionalOperationMapper operationMapper, State sql.append(" = "); sql.append(":"); - // TODO:当实体为符合主键并且参数列表中的顺序与实体中字段顺序不一致,则会发生错误。 - sql.append(i + 1); + // 复合主键一定要在DAO方法中的指明各个参数名,并与Bean的字段名(field.getName)一致 + if (primaryKey.size() > 1) { + sql.append(col.getOriginal().getName()); + } else { + sql.append(i + 1); + } } } else if(operationMapper.isComplexMode()) { List parameters = operationMapper.getParameters(); From d8c083b895702662d8dfb5e371296200d40dde33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BF=97=E4=BA=AE?= Date: Thu, 26 May 2016 17:51:27 +0800 Subject: [PATCH 16/17] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=B1=BB=E7=9A=84?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jade/plugin/sql/PlumSQLInterpreter.java | 15 ++++--- .../jade/plugin/sql/dialect/IDialect.java | 2 +- .../plugin/sql/dialect/ISQLGenerator.java | 18 ++++++-- .../jade/plugin/sql/dialect/MySQLDialect.java | 9 ++-- .../plugin/sql/dialect/OracleDialect.java | 19 ++++----- .../sql/dialect/oracle/SelectGenerator.java | 6 +-- .../standard/AbstractSelectGenerator.java | 8 ++-- .../standard/ConditionalGenerator.java | 15 +++---- .../sql/dialect/standard/DeleteGenerator.java | 3 +- .../sql/dialect/standard/InsertGenerator.java | 19 ++++----- .../sql/dialect/standard/UpdateGenerator.java | 16 +++---- .../plugin/sql/id/AutoIncrementProcessor.java | 6 +-- .../plugin/sql/mapper/AbstractMapper.java | 24 ++++------- .../jade/plugin/sql/mapper/ColumnMapper.java | 4 +- .../mapper/ConditionalOperationMapper.java | 7 +--- .../jade/plugin/sql/mapper/EntityMapper.java | 8 ++-- .../sql/mapper/EntityMapperManager.java | 2 +- .../sql/mapper/ExpandableParameterMapper.java | 6 +-- .../jade/plugin/sql/mapper/IColumnMapper.java | 17 ++++++++ .../rose/jade/plugin/sql/mapper/IMapper.java | 42 +++++++++++++++---- .../plugin/sql/mapper/OperationMapper.java | 10 ++--- .../sql/mapper/OperationMapperManager.java | 2 +- .../plugin/sql/mapper/ParameterMapper.java | 10 ++--- 23 files changed, 155 insertions(+), 113 deletions(-) diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java b/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java index de05a65..16fbbad 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/PlumSQLInterpreter.java @@ -39,9 +39,9 @@ @Order(-1) public class PlumSQLInterpreter implements Interpreter, InitializingBean, ApplicationContextAware { - private static final Log logger = LogFactory.getLog(PlumSQLInterpreter.class); + private static final Log logger = LogFactory.getLog(PlumSQLInterpreter.class); - private ApplicationContext applicationContext; + private ApplicationContext applicationContext; private OperationMapperManager operationMapperManager; @@ -53,6 +53,7 @@ public class PlumSQLInterpreter implements Interpreter, InitializingBean, Applic public static final String SQL_ANNOTATION_MARKUP = "jade-plugin-sql"; + public void setDialect(IDialect dialect) { this.dialect = dialect; } @@ -81,10 +82,12 @@ public void afterPropertiesSet() throws Exception { // if (logger.isInfoEnabled()) { - String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(// - applicationContext, GenericDAO.class); - logger.info("[jade-plugin-sql] found " + beanNames.length + " GenericDAOs: " - + Arrays.toString(beanNames)); + if (applicationContext != null) { + String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(// + applicationContext, GenericDAO.class); + logger.info("[jade-plugin-sql] found " + beanNames.length + " GenericDAOs: " + + Arrays.toString(beanNames)); + } } } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/IDialect.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/IDialect.java index 2f0980a..76e3375 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/IDialect.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/IDialect.java @@ -22,5 +22,5 @@ public interface IDialect { * @see IOperationMapper * @see StatementRuntime */ - public String translate(T operation, StatementRuntime runtime); + public String translate(IOperationMapper operation, StatementRuntime runtime); } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/ISQLGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/ISQLGenerator.java index 5a26307..1a9a1e9 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/ISQLGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/ISQLGenerator.java @@ -3,14 +3,26 @@ */ package net.paoding.rose.jade.plugin.sql.dialect; +import net.paoding.rose.jade.plugin.sql.dialect.mysql.SelectGenerator; +import net.paoding.rose.jade.plugin.sql.dialect.standard.DeleteGenerator; +import net.paoding.rose.jade.plugin.sql.dialect.standard.InsertGenerator; +import net.paoding.rose.jade.plugin.sql.dialect.standard.UpdateGenerator; import net.paoding.rose.jade.plugin.sql.mapper.IOperationMapper; import net.paoding.rose.jade.statement.StatementRuntime; /** - * 查询语句生成器 + * SQL语句生成器

+ * + * 以 MySQL 的实现为例,SQL语句分为2大类,第一大类是条件语句,第二类是插入语句。其中条件语句详细分为查询语句、更新语句、删除语句。 + * + * @see SelectGenerator + * @see UpdateGenerator + * @see DeleteGenerator + * @see InsertGenerator + * * @author Alan.Geng[gengzhi718@gmail.com] */ -public interface ISQLGenerator { +public interface ISQLGenerator { /** * 将某种操作生成SQL @@ -18,6 +30,6 @@ public interface ISQLGenerator { * @param runtime * @return */ - String generate(T operationMapper, StatementRuntime runtime); + String generate(IOperationMapper operationMapper, StatementRuntime runtime); } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/MySQLDialect.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/MySQLDialect.java index e007382..b59faad 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/MySQLDialect.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/MySQLDialect.java @@ -19,10 +19,10 @@ */ public class MySQLDialect implements IDialect { - private Map> generators; + private Map generators; public MySQLDialect() { - generators = new HashMap>(); + generators = new HashMap(); generators.put(IOperationMapper.OPERATION_SELECT, new SelectGenerator()); generators.put(IOperationMapper.OPERATION_INSERT, new InsertGenerator()); generators.put(IOperationMapper.OPERATION_UPDATE, new UpdateGenerator()); @@ -32,10 +32,9 @@ public MySQLDialect() { /* (non-Javadoc) * @see com.cainiao.depot.project.biz.common.jade.dialect.IDialect#translate(com.cainiao.depot.project.biz.common.jade.mapper.IOperationMapper) */ - @SuppressWarnings("unchecked") @Override - public String translate(T operation, StatementRuntime runtime) { - ISQLGenerator gen = (ISQLGenerator) generators.get(operation.getName()); + public String translate(IOperationMapper operation, StatementRuntime runtime) { + ISQLGenerator gen = (ISQLGenerator) generators.get(operation.getDestName()); if(gen != null) { return gen.generate(operation, runtime); } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/OracleDialect.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/OracleDialect.java index 87580d7..7f5522a 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/OracleDialect.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/OracleDialect.java @@ -19,10 +19,10 @@ */ public class OracleDialect implements IDialect { -private Map> generators; +private Map generators; public OracleDialect() { - generators = new HashMap>(); + generators = new HashMap(); generators.put(IOperationMapper.OPERATION_SELECT, new SelectGenerator()); generators.put(IOperationMapper.OPERATION_INSERT, new InsertGenerator()); generators.put(IOperationMapper.OPERATION_UPDATE, new UpdateGenerator()); @@ -32,14 +32,13 @@ public OracleDialect() { /* (non-Javadoc) * @see com.cainiao.depot.project.biz.common.jade.dialect.IDialect#translate(com.cainiao.depot.project.biz.common.jade.mapper.IOperationMapper) */ - @SuppressWarnings("unchecked") @Override - public String translate(T operation, StatementRuntime runtime) { - ISQLGenerator gen = (ISQLGenerator) generators.get(operation.getName()); - if(gen != null) { - return gen.generate(operation, runtime); - } - return null; - } + public String translate(IOperationMapper operation, StatementRuntime runtime) { + ISQLGenerator gen = (ISQLGenerator) generators.get(operation.getDestName()); + if(gen != null) { + return gen.generate(operation, runtime); + } + return null; + } } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java index aa64386..e70e66c 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/oracle/SelectGenerator.java @@ -48,7 +48,7 @@ protected StringBuilder applyRange(ConditionalOperationMapper operationMapper, } if(offset != null && offset > 1) { - StringBuilder outerSql = new StringBuilder(operationMapper.getName()); + StringBuilder outerSql = new StringBuilder(operationMapper.getDestName()); outerSql.append(" "); applyColumns(operationMapper.getTargetEntityMapper(), outerSql); @@ -85,8 +85,8 @@ protected void applyColumns(ConditionalOperationMapper operationMapper, Statemen @Override protected String getColumnAlias(IColumnMapper column) { - if(column.getName().startsWith("\"") - && column.getName().endsWith("\"")) { + if(column.getDestName().startsWith("\"") + && column.getDestName().endsWith("\"")) { return "\"" + super.getColumnAlias(column) + "\""; } return super.getColumnAlias(column); diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/AbstractSelectGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/AbstractSelectGenerator.java index 8ac9d37..9413685 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/AbstractSelectGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/AbstractSelectGenerator.java @@ -37,13 +37,13 @@ public abstract class AbstractSelectGenerator extends ConditionalGenerator { protected StringBuilder beforeApplyConditions(ConditionalOperationMapper operationMapper, StatementRuntime runtime, StringBuilder sql) { super.beforeApplyConditions(operationMapper, runtime, sql); IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); - sql.append(operationMapper.getName()); + sql.append(operationMapper.getDestName()); sql.append(" "); applyColumns(operationMapper, runtime, sql); sql.append(" FROM "); - sql.append(targetEntityMapper.getName()); + sql.append(targetEntityMapper.getDestName()); return sql; } @@ -61,7 +61,7 @@ protected void applyColumns(IEntityMapper targetEntityMapper, StringBuilder sql) List columns = targetEntityMapper.getColumns(); for(IColumnMapper col : columns) { - String name = col.getName(); + String name = col.getDestName(); sql.append(name); sql.append(" "); sql.append(getColumnAlias(col)); @@ -138,7 +138,7 @@ protected StringBuilder applyOrderBy(ConditionalOperationMapper operationMapper, if(col != null) { - sql.append(col.getName()); + sql.append(col.getDestName()); sql.append(" "); sql.append(DIRECTIONS.get(group.getDirection())); sql.append(","); diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/ConditionalGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/ConditionalGenerator.java index 7e286ef..457f63c 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/ConditionalGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/ConditionalGenerator.java @@ -12,6 +12,7 @@ import net.paoding.rose.jade.plugin.sql.dialect.ISQLGenerator; import net.paoding.rose.jade.plugin.sql.mapper.ConditionalOperationMapper; import net.paoding.rose.jade.plugin.sql.mapper.IColumnMapper; +import net.paoding.rose.jade.plugin.sql.mapper.IOperationMapper; import net.paoding.rose.jade.plugin.sql.mapper.IParameterMapper; import net.paoding.rose.jade.plugin.sql.util.PlumUtils; import net.paoding.rose.jade.statement.StatementRuntime; @@ -20,7 +21,7 @@ * @author Alan.Geng[gengzhi718@gmail.com] * */ -public abstract class ConditionalGenerator implements ISQLGenerator { +public abstract class ConditionalGenerator implements ISQLGenerator { private static final Map OPERATORS; @@ -41,11 +42,11 @@ public abstract class ConditionalGenerator implements ISQLGenerator { +public class InsertGenerator implements ISQLGenerator { private IDGeneratorManager idGeneratorManager = new CachedIDGeneratorManager(); @@ -35,8 +34,8 @@ public class InsertGenerator implements ISQLGenerator { * @see com.cainiao.depot.project.biz.common.jade.dialect.ISQLGenerator#generate(com.cainiao.depot.project.biz.common.jade.mapper.IOperationMapper) */ @Override - public String generate(OperationMapper operationMapper, StatementRuntime runtime) { - if(!operationMapper.getName().equals(IOperationMapper.OPERATION_INSERT)) { + public String generate(IOperationMapper operationMapper, StatementRuntime runtime) { + if(!operationMapper.getDestName().equals(IOperationMapper.OPERATION_INSERT)) { throw new IllegalArgumentException("Operation mapper must be a insert."); } @@ -54,7 +53,7 @@ public String generate(OperationMapper operationMapper, StatementRuntime runtime List expandParams = ((IExpandableParameterMapper) entityParam).expand(); StringBuilder sql = new StringBuilder("INSERT INTO "); StringBuilder values = new StringBuilder(); - sql.append(targetEntityMapper.getName()); + sql.append(targetEntityMapper.getDestName()); sql.append("("); for(IParameterMapper param : expandParams) { @@ -83,11 +82,11 @@ public String generate(OperationMapper operationMapper, StatementRuntime runtime } } - sql.append(param.getColumnMapper().getName()); + sql.append(param.getColumnMapper().getDestName()); sql.append(","); values.append(":"); - values.append(entityParam.getName()); + values.append(entityParam.getDestName()); values.append("."); values.append(param.getColumnMapper().getOriginalName()); values.append(","); diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/UpdateGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/UpdateGenerator.java index 3ed7678..100a27d 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/UpdateGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/UpdateGenerator.java @@ -31,7 +31,7 @@ protected StringBuilder beforeApplyConditions( sql = super.beforeApplyConditions(operationMapper, runtime, sql); sql.append("UPDATE "); - sql.append(operationMapper.getTargetEntityMapper().getName()); + sql.append(operationMapper.getTargetEntityMapper().getDestName()); return sql; } @@ -44,7 +44,7 @@ public StringBuilder applyConditions(ConditionalOperationMapper operationMapper, // 通过实体或实体集合更新 Map parametersValue = runtime.getParameters(); - if(!operationMapper.getName().equals(IOperationMapper.OPERATION_UPDATE)) { + if(!operationMapper.getDestName().equals(IOperationMapper.OPERATION_UPDATE)) { throw new InvalidDataAccessApiUsageException("Operation mapper must be a update."); } @@ -77,7 +77,7 @@ public StringBuilder applyConditions(ConditionalOperationMapper operationMapper, if(p.getColumnMapper().isPrimaryKey()) { // 主键视为条件 if(value == null) { - throw new IllegalArgumentException("Cannot execute update, primary key \"" + p.getColumnMapper().getName() + "\" must not be null."); + throw new IllegalArgumentException("Cannot execute update, primary key \"" + p.getColumnMapper().getDestName() + "\" must not be null."); } if(where.length() > 0) { @@ -86,9 +86,9 @@ public StringBuilder applyConditions(ConditionalOperationMapper operationMapper, where.append(" WHERE "); } - where.append(p.getColumnMapper().getName()); + where.append(p.getColumnMapper().getDestName()); where.append(" = :"); - where.append(param.getName()); + where.append(param.getDestName()); where.append("."); where.append(p.getColumnMapper().getOriginalName()); } else { @@ -96,10 +96,10 @@ public StringBuilder applyConditions(ConditionalOperationMapper operationMapper, && value == null) { continue; } else { - sql.append(p.getColumnMapper().getName()); + sql.append(p.getColumnMapper().getDestName()); sql.append(" = "); sql.append(":"); - sql.append(param.getName()); + sql.append(param.getDestName()); sql.append("."); sql.append(p.getColumnMapper().getOriginalName()); sql.append(","); @@ -133,7 +133,7 @@ public StringBuilder applyConditions(ConditionalOperationMapper operationMapper, if(sql.length() == start) { sql.append(" SET "); } - sql.append(param.getName()); + sql.append(param.getDestName()); sql.append(" = :"); sql.append(param.getOriginalName()); sql.append(","); diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java b/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java index d8fe822..3d12cbc 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java @@ -35,11 +35,11 @@ public Object execute(StatementRuntime runtime, Object returnValue) { if(attribute != null) { IOperationMapper operationMapper = attribute.getOperationMapper(); - if(IOperationMapper.OPERATION_INSERT.equals(operationMapper.getName())) { + if(IOperationMapper.OPERATION_INSERT.equals(operationMapper.getDestName())) { IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); if(targetEntityMapper.containsAutoIncrementPrimaryKey()) { - String paramName = operationMapper.getParameters().get(0).getName(); + String paramName = operationMapper.getParameters().get(0).getDestName(); if(returnValue.getClass().isArray()) { @@ -78,7 +78,7 @@ private boolean isAutoIncrementPrimaryKey(StatementMetaData metaData) { if(attribute != null) { IOperationMapper operationMapper = attribute.getOperationMapper(); - if(IOperationMapper.OPERATION_INSERT.equals(operationMapper.getName())) { + if(IOperationMapper.OPERATION_INSERT.equals(operationMapper.getDestName())) { IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); return targetEntityMapper.containsAutoIncrementPrimaryKey(); } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/AbstractMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/AbstractMapper.java index 04137cc..9e6f38f 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/AbstractMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/AbstractMapper.java @@ -20,25 +20,20 @@ public abstract class AbstractMapper implements IMapper { private String originalName; - private boolean mapped; - public static final char SEPARATOR = '_'; protected static Log logger = LogFactory.getLog(IMapper.class); public AbstractMapper(O original) { this.original = original; + this.originalName = generateOriginalName(); + this.name = generateName(getOriginalName()); } + - @Override - public void map() { - if(!mapped) { - this.originalName = generateOriginalName(); - this.name = generateName(getOriginalName()); - doMap(); - mapped = true; - } - } + @Override + public void init() { + } public O getOriginal() { return original; @@ -82,12 +77,9 @@ public String generateName(String source) { throw new IllegalArgumentException("Illegal naming conventions."); } } - - protected void doMap() { - - }; - public String getName() { + @Override + public String getDestName() { return name; } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ColumnMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ColumnMapper.java index 98ed108..4c36d63 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ColumnMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ColumnMapper.java @@ -33,9 +33,9 @@ protected String generateOriginalName() { } @Override - protected void doMap() { + public void init() { defaultOrderDirection = annotation.order(); - super.doMap(); + super.init(); } @Override diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ConditionalOperationMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ConditionalOperationMapper.java index c65bbd6..fb8e82e 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ConditionalOperationMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ConditionalOperationMapper.java @@ -91,7 +91,7 @@ && getPrimaryKeyType().isAssignableFrom(type) } limitParameterIndex = index; } else if(annotation.annotationType() == Where.class - && OPERATION_UPDATE.equals(getName())) { + && OPERATION_UPDATE.equals(getDestName())) { // Where条件的位置,用于更新操作,其他操作该注解无任何意义。 if(index == 0) { // 如果该注解被标记在第一个参数前,证明该操作没有任何值用于更新。 @@ -107,11 +107,6 @@ && getPrimaryKeyType().isAssignableFrom(type) // :) Have to say, [Casablanca - Bertie Higgins] very nice! } - @Override - protected void doMap() { - super.doMap(); - } - public boolean containsOrder() { return orderParameterIndex != -1 || getTargetEntityMapper().getDefaultOrder() != null; } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java index fedc2c7..916144f 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java @@ -40,8 +40,8 @@ public EntityMapper(Class from) { } @Override - protected void doMap() { - super.doMap(); + public void init() { + super.init(); this.columns = generateColumns(); this.columnsMap = new HashMap(this.columns.size()); this.primaryKey = new ArrayList(1); @@ -61,7 +61,7 @@ protected void doMap() { if(defaultOrder == null) { defaultOrder = Plum.orderBy(col.getDefaultOrderDirection(), col.getOriginal().getName()); } else { - defaultOrder.orderBy(col.getDefaultOrderDirection(), col.getName()); + defaultOrder.orderBy(col.getDefaultOrderDirection(), col.getDestName()); } } this.columnsMap.put(col.getOriginal().getName(), col); @@ -91,7 +91,7 @@ protected List generateColumns() { protected IColumnMapper createColumnMapper(Field field) { IColumnMapper cm = new ColumnMapper(field); - cm.map(); + cm.init(); return cm; } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapperManager.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapperManager.java index 6a1057a..88225b2 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapperManager.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapperManager.java @@ -11,7 +11,7 @@ public class EntityMapperManager extends AbstractCachedMapperManager, I public IEntityMapper create(Class clazz) { IEntityMapper entityMapper = new EntityMapper(clazz); - entityMapper.map(); + entityMapper.init(); return entityMapper; } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ExpandableParameterMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ExpandableParameterMapper.java index 7ef9624..867cee0 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ExpandableParameterMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ExpandableParameterMapper.java @@ -21,8 +21,8 @@ public ExpandableParameterMapper(IOperationMapper operationMapper, private List expendedParameters; @Override - public void doMap() { - super.doMap(); + public void init() { + super.init(); try { mapExpendedParameterMapper(); } catch (Exception e) { @@ -43,7 +43,7 @@ protected void mapExpendedParameterMapper() throws Exception { protected ParameterMapper createExpendedParameterMapper(IColumnMapper col) { ParameterMapper expended = new ParameterMapper(this, col); - expended.map(); + expended.init(); return expended; } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IColumnMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IColumnMapper.java index d283337..f854b8a 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IColumnMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IColumnMapper.java @@ -9,14 +9,31 @@ import net.paoding.rose.jade.plugin.sql.id.IDGenerator; /** + * 负责列的映射。 + * * @author Alan.Geng[gengzhi718@gmail.com] * */ public interface IColumnMapper extends IMapper { + /** + * 该列是否是表的主键? + * + * @return + */ boolean isPrimaryKey(); + /** + * 该列的默认排序规则,可用在SQL查询语句 + * + * @return + */ Direction getDefaultOrderDirection(); + /** + * 主键生成器 + * + * @return + */ Class> getIDGeneratorType(); } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IMapper.java index 9fb86a1..e9ff431 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/IMapper.java @@ -3,18 +3,44 @@ */ package net.paoding.rose.jade.plugin.sql.mapper; +import net.paoding.rose.jade.statement.StatementMetaData; + /** + * + * {@link IMapper}用以封装提取的一些信息,用于生成SQL、设置参数或解析结果。 + * + * {@link IEntityMapper}用以封装实体类的信息(对应DO类)。

+ * {@link IOperationMapper}用以封装语句信息(对应DAO的方法) + * * @author Alan.Geng[gengzhi718@gmail.com] * */ public interface IMapper { - public O getOriginal(); - - void map(); - - String getOriginalName(); - - String getName(); - + /** + * 信息的原始起源地,比如某个DO实例或{@link StatementMetaData}实例等等 + * + * @return + */ + public O getOriginal(); + + /** + * 原始起源地名称(比如类名、字段名等) + * + * @return + */ + String getOriginalName(); + + /** + * 初始化 (此时 {@link #getOriginal()}和 {@link #getOriginalName()}应该已就绪) + */ + void init(); + + /** + * + * + * @return + */ + String getDestName(); + } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java index c06c83e..8cdee42 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java @@ -51,7 +51,7 @@ public IEntityMapper getTargetEntityMapper() { } @Override - protected void doMap() { + public void init() { ignoreNull = original.getAnnotation(IgnoreNull.class); if(original.getMethod().getName().startsWith("count") @@ -85,9 +85,9 @@ protected void mapParameters() { || parameterTypes.length == 0) { parameters = NO_PARAMETER; - if((getName() == OPERATION_INSERT - || getName() == OPERATION_DELETE - || getName() == OPERATION_UPDATE) + if((getDestName().equals(OPERATION_INSERT) + || getDestName().equals(OPERATION_DELETE) + || getDestName().equals(OPERATION_UPDATE)) && parameters == NO_PARAMETER) { // 写操作必须存在参数 throw new MappingException("The insert operation must has least 1 parameters."); @@ -151,7 +151,7 @@ protected IParameterMapper createParameterMapper(Class type, Annotation[] ann param = new ParameterMapper(this, type, annotations); } - param.map(); + param.init(); return param; } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapperManager.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapperManager.java index 0d7a73b..c3165d8 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapperManager.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapperManager.java @@ -28,7 +28,7 @@ public IOperationMapper create(StatementMetaData source) { } mapper.setEntityMapperManager(entityMapperManager); - mapper.map(); + mapper.init(); return mapper; } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ParameterMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ParameterMapper.java index 6cd2b1b..b058d9c 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ParameterMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ParameterMapper.java @@ -75,8 +75,8 @@ public ParameterMapper(IOperationMapper operationMapper, Class type, Annotati } @Override - protected void doMap() { - super.doMap(); + public void init() { + super.init(); Annotation[] annotations = original.getAnnotations(); if(annotations != null && annotations.length > 0) { for(Annotation annotation : annotations) { @@ -149,11 +149,11 @@ public IOperationMapper getOperationMapper() { } @Override - public String getName() { + public String getDestName() { if(columnMapper != null) { - return columnMapper.getName(); + return columnMapper.getDestName(); } - return super.getName(); + return super.getDestName(); } } From f11e439172e93b92109bb37408d5e6e0f9d0e362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BF=97=E4=BA=AE?= Date: Fri, 27 May 2016 10:47:06 +0800 Subject: [PATCH 17/17] =?UTF-8?q?=E8=AF=AD=E5=8F=A5=E7=94=9F=E6=88=90?= =?UTF-8?q?=E5=99=A8=E4=B8=AD=E5=AF=B9SQL=E5=AE=9E=E4=BD=93=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=BC=95=E7=94=A8=E6=94=B9=E4=B8=BA=E5=BC=95=E7=94=A8?= =?UTF-8?q?:1=E7=9A=84=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/sql/dialect/standard/InsertGenerator.java | 11 +++++------ .../plugin/sql/dialect/standard/UpdateGenerator.java | 10 +++------- .../jade/plugin/sql/id/AutoIncrementProcessor.java | 4 +--- .../rose/jade/plugin/sql/mapper/AbstractMapper.java | 8 ++++---- .../rose/jade/plugin/sql/mapper/ColumnMapper.java | 4 ++-- .../rose/jade/plugin/sql/mapper/EntityMapper.java | 4 ++-- .../rose/jade/plugin/sql/mapper/OperationMapper.java | 2 +- 7 files changed, 18 insertions(+), 25 deletions(-) diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/InsertGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/InsertGenerator.java index 9f3efbc..c094ac3 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/InsertGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/InsertGenerator.java @@ -51,8 +51,9 @@ public String generate(IOperationMapper operationMapper, StatementRuntime runtim if(entityParam instanceof IExpandableParameterMapper) { List expandParams = ((IExpandableParameterMapper) entityParam).expand(); - StringBuilder sql = new StringBuilder("INSERT INTO "); - StringBuilder values = new StringBuilder(); + StringBuilder sql = new StringBuilder(500); + StringBuilder values = new StringBuilder(); + sql.append("INSERT INTO "); sql.append(targetEntityMapper.getDestName()); sql.append("("); @@ -85,9 +86,7 @@ public String generate(IOperationMapper operationMapper, StatementRuntime runtim sql.append(param.getColumnMapper().getDestName()); sql.append(","); - values.append(":"); - values.append(entityParam.getDestName()); - values.append("."); + values.append(":1."); values.append(param.getColumnMapper().getOriginalName()); values.append(","); } @@ -95,7 +94,7 @@ public String generate(IOperationMapper operationMapper, StatementRuntime runtim values.setLength(values.length() - 1); sql.append(")VALUES("); - sql.append(values.toString()); + sql.append(values); sql.append(")"); return sql.toString(); diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/UpdateGenerator.java b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/UpdateGenerator.java index 100a27d..170b8e9 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/UpdateGenerator.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/dialect/standard/UpdateGenerator.java @@ -61,7 +61,7 @@ public StringBuilder applyConditions(ConditionalOperationMapper operationMapper, if(param instanceof IExpandableParameterMapper) { List expandParams = ((IExpandableParameterMapper) param).expand(); - Object parameterValue = parametersValue.entrySet().iterator().next().getValue(); + Object parameterValue = parametersValue.get(":1"); sql.append(" SET "); for(IParameterMapper p : expandParams) { @@ -87,9 +87,7 @@ public StringBuilder applyConditions(ConditionalOperationMapper operationMapper, } where.append(p.getColumnMapper().getDestName()); - where.append(" = :"); - where.append(param.getDestName()); - where.append("."); + where.append(" = :1."); where.append(p.getColumnMapper().getOriginalName()); } else { if(param.isIgnoreNull() @@ -98,9 +96,7 @@ public StringBuilder applyConditions(ConditionalOperationMapper operationMapper, } else { sql.append(p.getColumnMapper().getDestName()); sql.append(" = "); - sql.append(":"); - sql.append(param.getDestName()); - sql.append("."); + sql.append(":1."); sql.append(p.getColumnMapper().getOriginalName()); sql.append(","); } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java b/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java index 3d12cbc..0bef11f 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/id/AutoIncrementProcessor.java @@ -39,12 +39,10 @@ public Object execute(StatementRuntime runtime, Object returnValue) { IEntityMapper targetEntityMapper = operationMapper.getTargetEntityMapper(); if(targetEntityMapper.containsAutoIncrementPrimaryKey()) { - String paramName = operationMapper.getParameters().get(0).getDestName(); - if(returnValue.getClass().isArray()) { } else { - Object param = runtime.getParameters().get(paramName); + Object param = runtime.getParameters().get(":1"); List primaryKey = targetEntityMapper.getPrimaryKey(); IColumnMapper iColumnMapper = primaryKey.get(0); try { diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/AbstractMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/AbstractMapper.java index 9e6f38f..631c0b3 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/AbstractMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/AbstractMapper.java @@ -16,7 +16,7 @@ public abstract class AbstractMapper implements IMapper { protected O original; - private String name; + private String destName; private String originalName; @@ -27,7 +27,7 @@ public abstract class AbstractMapper implements IMapper { public AbstractMapper(O original) { this.original = original; this.originalName = generateOriginalName(); - this.name = generateName(getOriginalName()); + this.destName = generateDestName(getOriginalName()); } @@ -47,7 +47,7 @@ protected String generateOriginalName() { return original.toString(); } - public String generateName(String source) { + public String generateDestName(String source) { if(PlumUtils.isBlank(source)) { return null; } @@ -80,7 +80,7 @@ public String generateName(String source) { @Override public String getDestName() { - return name; + return destName; } } diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ColumnMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ColumnMapper.java index 4c36d63..1f048da 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ColumnMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/ColumnMapper.java @@ -39,11 +39,11 @@ public void init() { } @Override - public String generateName(String source) { + public String generateDestName(String source) { if(PlumUtils.isNotBlank(annotation.value())) { return annotation.value(); } - return super.generateName(source); + return super.generateDestName(source); } @SuppressWarnings("deprecation") diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java index 916144f..8802c0d 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/EntityMapper.java @@ -110,12 +110,12 @@ protected String generateOriginalName() { } @Override - public String generateName(String source) { + public String generateDestName(String source) { Table table = original.getAnnotation(Table.class); if(table != null && PlumUtils.isNotBlank(table.value())) { return table.value(); } - return super.generateName(source); + return super.generateDestName(source); } @Override diff --git a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java index 8cdee42..7d7415e 100644 --- a/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java +++ b/src/main/java/net/paoding/rose/jade/plugin/sql/mapper/OperationMapper.java @@ -174,7 +174,7 @@ protected String generateOriginalName() { } @Override - public String generateName(String source) { + public String generateDestName(String source) { for(int i = 0; i < OPERATION_PREFIX.length; i++) { String[] prefixs = OPERATION_PREFIX[i]; for(int j = 0; j < prefixs.length; j++) {