From 69b738a9a19ad6677baca480e3b49b91ef4bbbcf Mon Sep 17 00:00:00 2001 From: Shaun Chyxion Date: Thu, 5 Oct 2017 11:55:07 +0800 Subject: [PATCH] add method parse --- tigon-codegen-spring-boot-test | 1 - tigon-codegen-war-test | 1 - tigon-mybatis/pom.xml | 8 +- .../tigon/mybatis/test/TestDriver.java | 272 +++++++++++++++++- .../tigon/mybatis/test/UserMapperTest.java | 52 ++++ .../mybatis/test/mapper/ActivityMapper.java | 2 + .../tigon/mybatis/test/mapper/UserMapper.java | 24 ++ .../tigon/mybatis/test/model/User.java | 50 ++++ .../resources/mybatis/mappers/user-mapper.xml | 45 +++ .../test/resources/spring/config.properties | 4 +- 10 files changed, 449 insertions(+), 10 deletions(-) delete mode 160000 tigon-codegen-spring-boot-test delete mode 160000 tigon-codegen-war-test create mode 100644 tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/UserMapperTest.java create mode 100644 tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/mapper/UserMapper.java create mode 100644 tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/model/User.java create mode 100644 tigon-mybatis/src/test/resources/mybatis/mappers/user-mapper.xml diff --git a/tigon-codegen-spring-boot-test b/tigon-codegen-spring-boot-test deleted file mode 160000 index a7c6906..0000000 --- a/tigon-codegen-spring-boot-test +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a7c690619e09fae1d48584794d68d1b8ee78c197 diff --git a/tigon-codegen-war-test b/tigon-codegen-war-test deleted file mode 160000 index a7c6906..0000000 --- a/tigon-codegen-war-test +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a7c690619e09fae1d48584794d68d1b8ee78c197 diff --git a/tigon-mybatis/pom.xml b/tigon-mybatis/pom.xml index 2a226ec..314863e 100644 --- a/tigon-mybatis/pom.xml +++ b/tigon-mybatis/pom.xml @@ -38,7 +38,13 @@ org.springframework.data spring-data-commons - 1.13.1.RELEASE + 2.0.0.RELEASE + + + + org.springframework.data + spring-data-jpa + 2.0.0.RELEASE diff --git a/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/TestDriver.java b/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/TestDriver.java index b955734..4c63ff7 100644 --- a/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/TestDriver.java +++ b/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/TestDriver.java @@ -2,15 +2,19 @@ package me.chyxion.tigon.mybatis.test; import lombok.extern.slf4j.Slf4j; import me.chyxion.tigon.mybatis.test.model.Activity; +import org.apache.commons.lang3.StringUtils; import org.junit.Test; +import org.springframework.data.domain.Sort; +import org.springframework.data.mapping.PropertyPath; import org.springframework.data.repository.query.parser.Part; +import static org.springframework.data.repository.query.parser.Part.Type.*; import org.springframework.data.repository.query.parser.PartTree; import org.w3c.dom.Document; import org.xml.sax.SAXException; import javax.xml.parsers.*; import java.io.IOException; -import java.util.Iterator; -import java.util.Map; +import java.util.*; + import org.xml.sax.helpers.DefaultHandler; import me.chyxion.tigon.mybatis.BaseMapper; import org.apache.ibatis.parsing.XPathParser; @@ -82,15 +86,273 @@ public class TestDriver { @Test public void testParse() { - PartTree tree = new PartTree("findByIdAndHoldingDateOrderById", Activity.class); + final PartTree tree = new PartTree("findByIdLessThanAndIdStartsWithAndIdInAndIdNotInOrIdAndHoldingDateOrIdBetweenOrderById", Activity.class); + final Iterator itOrParts = tree.iterator(); + + List sqlFrags = new LinkedList(); + int paramIndex = 0; + while (itOrParts.hasNext()) { + final PartTree.OrPart orPart = itOrParts.next(); + log.info("Or part [{}] found.", orPart); + final Iterator itOrPart = orPart.iterator(); + List andParts = new LinkedList(); + int orPartIndex = 0; + while (itOrPart.hasNext()) { + final Part part = itOrPart.next(); + final PropertyPath prop = part.getProperty(); + final Part.Type type = part.getType(); + final int numArgs = part.getNumberOfArguments(); + andParts.add(buildSQL(part, paramIndex, orPartIndex == 0)); + log.info("Part [{}], path [{}], number of arg [{}], type [{}].", part, prop.toDotPath(), numArgs, type.name()); + paramIndex += numArgs; + ++orPartIndex; + } + log.info("[{}] and parts found.", andParts.size()); + sqlFrags.add(new StringBuilder(StringUtils.join(andParts, " "))); + } + log.info("SQL [{}].", StringUtils.join(sqlFrags, " ")); + final Sort sort = tree.getSort(); + if (sort != null) { + Iterator itSort = sort.iterator(); + while (itSort.hasNext()) { + Sort.Order order = itSort.next(); + log.info("Order [{}] [{}]", order.getProperty(), order.getDirection()); + } + } + } + + private String buildSQL(Part part, final int paramIndex, boolean orClause) { + final PropertyPath prop = part.getProperty(); + final Part.Type type = part.getType(); + final String col = prop.toDotPath(); + + if (BETWEEN.equals(type)) { + // + return col + " between #{param" + paramIndex + "} and #{param" + (paramIndex + 1) + "}"; + } + else if (CONTAINING.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, true, col + " like #{param" + paramIndex + "}"); + } + else if (ENDING_WITH.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, true, col + " like #{param" + paramIndex + "}"); + } + else if (FALSE.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, false, col + " is false"); + } + else if (GREATER_THAN.equals(type) || AFTER.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, true, col + " > #{param" + paramIndex + "}"); + } + else if (GREATER_THAN_EQUAL.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, true, col + " >= #{param" + paramIndex + "}"); + } + else if (IN.equals(type)) { + return ifNotNullTag(paramIndex, true, orClause, true, col + " in " + buildArray(paramIndex)); + } + else if (IS_NOT_NULL.equals(type) || EXISTS.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, false, col + " is not null"); + } + else if (IS_NULL.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, false, col + " is null"); + } + else if (LESS_THAN.equals(type) || BEFORE.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, true, col + " < #{param" + paramIndex + "}"); + } + else if (LESS_THAN_EQUAL.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, true, col + " <= #{param" + paramIndex + "}"); + } + else if (LIKE.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, true, col + " like #{param" + paramIndex + "}"); + } + else if (NEGATING_SIMPLE_PROPERTY.equals(type)) { + return col + " <> #{param" + paramIndex + "}"; + } + else if (NOT_IN.equals(type)) { + return ifNotNullTag(paramIndex, true, orClause, true, col + " not in " + buildArray(paramIndex)); + } + else if (NOT_LIKE.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, true, col + " not like #{param" + paramIndex + "}"); + } + else if (REGEX.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, true, col + " regexp #{param" + paramIndex + "}"); + } + else if (SIMPLE_PROPERTY.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, true, col + " = #{param" + paramIndex + "}"); + } + else if (STARTING_WITH.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, true, + bindTag("param" + paramIndex + "_var", "param" + paramIndex + " + '%'") + + col + " like #{param" + paramIndex + "_var}"); + } + else if (TRUE.equals(type)) { + return ifNotNullTag(paramIndex, false, orClause, false, col + " is true"); + } + else if (NOT_CONTAINING.equals(type)) { + // TODO + return col + " not like #{param" + paramIndex + "}"; + } + // redis + else if (NEAR.equals(type)) { + } + // redis + else if (WITHIN.equals(type)) { + return col + " like #{param" + paramIndex + "}"; + } + return null; + } + + String ifNotNullTag(int paramIndex, boolean collection, boolean orClause, boolean wrapIf, String sql) { + if (wrapIf) { + return ifNotNullTag(paramIndex, collection, orClause, sql); + } + return (orClause ? " or " : " and ") + sql; + } + + String bindTag(final String name, final String value) { + return ""; + } + + String buildArray(int paramIndex) { + return new StringBuilder("\n") + .append("#{__val__}") + .append("\n") + .toString(); + } + + String ifNotNullTag(int paramIndex, boolean orClause, String innerTag) { + return new StringBuilder("\n") + .append(orClause ? " or " : " and ") + .append(innerTag) + .append("\n") + .toString(); + } + + String ifNotEmptyTag(int paramIndex, boolean orClause, String innerTag) { + return new StringBuilder("\n") + .append(orClause ? " or " : " and ") + .append(innerTag) + .append("\n") + .toString(); + } + + String ifNotNullTag(int paramIndex, boolean collection, boolean orClause, String innerTag) { + StringBuilder sbRtn = new StringBuilder("\n"); + } + else { + sbRtn.append("param") + .append(paramIndex) + .append(" != null\">\n"); + } + return sbRtn.append(orClause ? " or " : " and ") + .append(innerTag) + .append("\n").toString(); + } + + String ifNotNullTag(int paramIndex, boolean collection, boolean orClause, InnerTag innerTag) { + StringBuilder sbRtn = new StringBuilder("\n"); + } + else { + sbRtn.append("param") + .append(paramIndex) + .append(" != null\">\n"); + } + return sbRtn.append(orClause ? " or " : " and ") + .append(innerTag.tag()) + .append("\n").toString(); + } + + interface InnerTag { + String tag(); + } + + @Test + public void testParse1() { + PartTree tree = new PartTree("findIdById", Activity.class); + log.info("tree to string: [{}].", tree); Iterator iterator = tree.iterator(); while (iterator.hasNext()) { - log.info("OrPart [{}].", iterator.next()); + PartTree.OrPart next = iterator.next(); + log.info("OrPart [{}].", next); + Iterator iterator1 = next.iterator(); + while (iterator1.hasNext()) { + Part next1 = iterator1.next(); + + PropertyPath property = next1.getProperty(); + Part.Type type = next1.getType(); + Collection keywords = type.getKeywords(); + log.info("Part [{}], path [{}], number of arg [{}], type [{}].", next1, property.toDotPath(), next1.getNumberOfArguments(), type.name()); + } } + + log.info("join or part [{}].", StringUtils.join(tree.iterator(), " or ")); + System.err.println(""); + for (Part part : tree.getParts()) { System.err.println(part); } - System.err.println(tree); + // System.err.println(tree); + +// Iterator iterator1 = tree.getSort().iterator(); +// while (iterator1.hasNext()) { +// System.err.println(iterator1.next()); +// } // tree = new PartTree("listByIdOrLastName", Customer.class); // System.err.println(tree); } diff --git a/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/UserMapperTest.java b/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/UserMapperTest.java new file mode 100644 index 0000000..d34521f --- /dev/null +++ b/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/UserMapperTest.java @@ -0,0 +1,52 @@ +package me.chyxion.tigon.mybatis.test; + +import me.chyxion.tigon.mybatis.test.mapper.UserMapper; +import me.chyxion.tigon.mybatis.test.model.User; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.lang.reflect.Method; +import java.util.List; + +/** + * @version 0.0.1 + * @since 0.0.1 + * @author Auto Generated
+ * Tech Support Shaun Chyxion
+ * May 17, 2016 9:54:18 AM + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath*:spring/spring-*.xml") +public class UserMapperTest { + @Autowired + private UserMapper mapper; + + @Test + public void testList() { + List list = mapper.list(null); + System.err.println(list); + } + + + @Test + public void testListByGender() { + List list = mapper.findByGender("M"); + System.err.println(list); + } + + + @Test + public void testGetAllMethod() { + Method[] declaredMethods = UserMapper.class.getDeclaredMethods(); + for (Method declaredMethod : declaredMethods) { + System.err.println("Declared Method: " + declaredMethod.getName()); + } + + for (Method declaredMethod : UserMapper.class.getMethods()) { + System.err.println("Method: " + declaredMethod.getName()); + } + } +} diff --git a/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/mapper/ActivityMapper.java b/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/mapper/ActivityMapper.java index 562d562..1575312 100644 --- a/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/mapper/ActivityMapper.java +++ b/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/mapper/ActivityMapper.java @@ -1,5 +1,6 @@ package me.chyxion.tigon.mybatis.test.mapper; +import java.util.Date; import me.chyxion.tigon.mybatis.BaseMapper; import me.chyxion.tigon.mybatis.test.model.Activity; @@ -11,4 +12,5 @@ import me.chyxion.tigon.mybatis.test.model.Activity; * May 17, 2016 9:54:18 AM */ public interface ActivityMapper extends BaseMapper { + Activity findByIdAndHoldingDateOrderById(Long id, Date holdingDate); } diff --git a/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/mapper/UserMapper.java b/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/mapper/UserMapper.java new file mode 100644 index 0000000..f87eb36 --- /dev/null +++ b/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/mapper/UserMapper.java @@ -0,0 +1,24 @@ +package me.chyxion.tigon.mybatis.test.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import me.chyxion.tigon.mybatis.BaseMapper; +import me.chyxion.tigon.mybatis.test.model.User; +import org.hibernate.validator.constraints.NotBlank; + +/** + * @version 0.0.1 + * @author Auto Generated
+ * Tech Support Shaun Chyxion
+ * Jun 7, 2017 8:55:14 PM + */ +public interface UserMapper extends BaseMapper { + + List listByCustomerId( + @NotBlank + @Param("customerId") + String customerId); + + + List findByGender(String gender); +} diff --git a/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/model/User.java b/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/model/User.java new file mode 100644 index 0000000..5a5d93e --- /dev/null +++ b/tigon-mybatis/src/test/java/me/chyxion/tigon/mybatis/test/model/User.java @@ -0,0 +1,50 @@ +package me.chyxion.tigon.mybatis.test.model; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Getter; +import lombok.Setter; +import me.chyxion.tigon.model.M3; +import me.chyxion.tigon.mybatis.NotUpdate; +import me.chyxion.tigon.mybatis.NotUpdateWhenNull; +import me.chyxion.tigon.mybatis.Table; + +/** + * @version 0.0.1 + * @author Auto Generated
+ * Tech Support Shaun Chyxion
+ * Jun 7, 2017 8:43:52 PM + */ +@Getter +@Setter +@Table("crm_user") +public class User extends M3 { + private static final long serialVersionUID = 1L; + + // roles + public static final String ROLE_ADMIN = "ADMIN"; + + // Column Names + public static final String ACCOUNT = "account"; + public static final String EMPLOYEE_ID = "employee_id"; + public static final String PASSWORD = "password"; + public static final String MOBILE = "mobile"; + public static final String EMAIL = "email"; + public static final String NAME = "name"; + public static final String EN_NAME = "en_name"; + public static final String GENDER = "gender"; + public static final String ADMIN = "admin"; + + // Properties + private String account; + @NotUpdate + private String employeeId; + @NotUpdateWhenNull + @JSONField(serialize = false) + private String password; + private String mobile; + private String email; + private String name; + private String enName; + private String gender; + private boolean admin; +} diff --git a/tigon-mybatis/src/test/resources/mybatis/mappers/user-mapper.xml b/tigon-mybatis/src/test/resources/mybatis/mappers/user-mapper.xml new file mode 100644 index 0000000..3399578 --- /dev/null +++ b/tigon-mybatis/src/test/resources/mybatis/mappers/user-mapper.xml @@ -0,0 +1,45 @@ + + + + + + + + + diff --git a/tigon-mybatis/src/test/resources/spring/config.properties b/tigon-mybatis/src/test/resources/spring/config.properties index dd9db2c..2c0b3a6 100644 --- a/tigon-mybatis/src/test/resources/spring/config.properties +++ b/tigon-mybatis/src/test/resources/spring/config.properties @@ -1,9 +1,9 @@ # Config Dev # Database -db.url=jdbc:mysql://127.0.0.1:3306/summer_mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC +db.url=jdbc:mysql://127.0.0.1:43306/ambition_crm?useUnicode=true&characterEncoding=utf-8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC db.user=root -db.password=12345678 +db.password=696@2^~)oZ@^#*Q redis.host=127.0.0.1 redis.password=0211