diff --git a/README.md b/README.md index b9123f7..cd5a079 100644 --- a/README.md +++ b/README.md @@ -21,14 +21,14 @@ Maven: <dependency> <groupId>cn.mybatisboost</groupId> <artifactId>mybatis-boost-spring-boot-starter</artifactId> - <version>2.3.1</version> + <version>2.3.2</version> </dependency> ``` Gradle: ```gradle compile 'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2' -compile 'cn.mybatisboost:mybatis-boost-spring-boot-starter:2.3.1' +compile 'cn.mybatisboost:mybatis-boost-spring-boot-starter:2.3.2' ``` 在手动创建SqlSessionFactory Bean的情况下,请确保MybatisBoost的Mybatis Plugin有被加载。 @@ -317,8 +317,6 @@ SELECT * FROM #t WHERE PostId = ? AND PostDate BETWEEN ? AND ? 只要以Mybatis的`@Mapper`注解标记的方法,MybatisBoost都会智能的生成相应SQL语句,让你的双手解放于编写千篇一律的简单SQL语句。 -> 低版本的Mybatis没有`@Mapper`注解,可以使用MybatisBoost提供的`@cn.mybatisboost.support.Mapper`注解代替。 - 下面我们就以“selectByPostIdAndPostDateBw”为例来分析下如何编写智能方法查询,分解后的单词如下:select By PostId And PostDate Bw。其中“select”称为“方法词”,“By”称为“辅助词”,“PostId”和“PostDate”为POJO中的属性,“And”和“Bw”(BETWEEN的缩写)为SQL关键字,其中,方法词和辅助词都是必须的,其他的为可选项。 目前支持的方法词:select、count、delete。 diff --git a/mybatis-boost-core/pom.xml b/mybatis-boost-core/pom.xml index 638cffe..8a43ef6 100644 --- a/mybatis-boost-core/pom.xml +++ b/mybatis-boost-core/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>cn.mybatisboost</groupId> <artifactId>mybatis-boost</artifactId> - <version>2.3.1</version> + <version>2.3.2</version> </parent> <artifactId>mybatis-boost-core</artifactId> diff --git a/mybatis-boost-core/src/main/java/cn/mybatisboost/nosql/MethodNameParser.java b/mybatis-boost-core/src/main/java/cn/mybatisboost/nosql/MethodNameParser.java index b44ce1c..6c684fe 100644 --- a/mybatis-boost-core/src/main/java/cn/mybatisboost/nosql/MethodNameParser.java +++ b/mybatis-boost-core/src/main/java/cn/mybatisboost/nosql/MethodNameParser.java @@ -6,9 +6,12 @@ import org.apache.ibatis.session.RowBounds; import java.util.*; +import java.util.regex.Pattern; public class MethodNameParser { + private static final Pattern PATTERN_ORDER_BY_SEPARATOR = Pattern.compile(" (?!ASC|DESC)"); + private final String methodName, tableName; private final boolean mapUnderscoreToCamelCase; private String parsedSql; @@ -48,9 +51,10 @@ public String toSql() { int offset = 0, predicateIndex; Iterator<String> iterator = keywordMap.values().iterator(); - Predicate predicate = null; + boolean containsOrderBy = false; + int orderByIndex = 0; while ((predicateIndex = expression.indexOf("?", offset)) >= 0) { - predicate = Predicate.of(iterator.next()); + Predicate predicate = Predicate.of(iterator.next()); if (predicateIndex > offset) { sqlBuilder.append(SqlUtils.normalizeColumn @@ -61,14 +65,24 @@ public String toSql() { } sqlBuilder.append(predicate.sqlFragment()).append(' '); offset = predicateIndex + 1; + + if (predicate == Predicate.OrderBy) { + containsOrderBy = true; + orderByIndex = sqlBuilder.length(); + } } if (offset < expression.length() - 1) { sqlBuilder.append(SqlUtils.normalizeColumn (expression.substring(offset), mapUnderscoreToCamelCase)); - if (predicate == null || predicate != Predicate.OrderBy) { + if (!containsOrderBy) { sqlBuilder.append(" = ?"); } } + if (containsOrderBy) { + String correctedOrderByExpression = PATTERN_ORDER_BY_SEPARATOR.matcher + (sqlBuilder.substring(orderByIndex).trim()).replaceAll(", "); + sqlBuilder.replace(orderByIndex, sqlBuilder.length(), correctedOrderByExpression); + } return parsedSql = sqlBuilder.toString().trim(); } @@ -80,25 +94,6 @@ public RowBounds toRowBounds() { private String prepare(StringBuilder sqlBuilder, String expression) { if (expression.startsWith("All")) { expression = expression.substring(3); - if (expression.startsWith("By")) { - sqlBuilder.append("WHERE "); - expression = expression.substring(2); - } - - Optional<BinaryTuple<String, Integer>> optional = - extractKeyNumber(expression, "Limit", true); - if (optional.isPresent()) { - BinaryTuple<String, Integer> tuple = optional.get(); - limit = tuple.second(); - expression = tuple.first(); - - optional = extractKeyNumber(expression, "Offset", true); - if (optional.isPresent()) { - tuple = optional.get(); - offset = tuple.second(); - expression = tuple.first(); - } - } } else { if (expression.startsWith("First")) { limit = 1; @@ -112,9 +107,24 @@ private String prepare(StringBuilder sqlBuilder, String expression) { expression = tuple.first(); } } - if (expression.startsWith("By")) { - sqlBuilder.append("WHERE "); - expression = expression.substring(2); + } + if (expression.startsWith("By")) { + sqlBuilder.append("WHERE "); + expression = expression.substring(2); + } + + Optional<BinaryTuple<String, Integer>> optional = + extractKeyNumber(expression, "Limit", true); + if (optional.isPresent()) { + BinaryTuple<String, Integer> tuple = optional.get(); + limit = tuple.second(); + expression = tuple.first(); + + optional = extractKeyNumber(expression, "Offset", true); + if (optional.isPresent()) { + tuple = optional.get(); + offset = tuple.second(); + expression = tuple.first(); } } return expression; diff --git a/mybatis-boost-core/src/main/java/cn/mybatisboost/util/EntityUtils.java b/mybatis-boost-core/src/main/java/cn/mybatisboost/util/EntityUtils.java index 4ba84fd..c1c51a1 100644 --- a/mybatis-boost-core/src/main/java/cn/mybatisboost/util/EntityUtils.java +++ b/mybatis-boost-core/src/main/java/cn/mybatisboost/util/EntityUtils.java @@ -8,9 +8,8 @@ import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -55,11 +54,11 @@ public static String getIdProperty(Class<?> type) { } public static List<String> getProperties(Class<?> type) { - return new ArrayList<>(propertiesCache.computeIfAbsent(type, UncheckedFunction.of(k -> - Collections.unmodifiableList(Arrays.stream(Introspector.getBeanInfo(type).getPropertyDescriptors()) - .map(PropertyDescriptor::getName) - .filter(p -> !Objects.equals(p, "class")) - .collect(Collectors.toList()))))); + return new ArrayList<>(propertiesCache.computeIfAbsent(type, k -> + Collections.unmodifiableList(Arrays.stream(type.getDeclaredFields()) + .filter(f -> !Modifier.isStatic(f.getModifiers())) + .filter(f -> !Modifier.isTransient(f.getModifiers())) + .map(Field::getName).collect(Collectors.toList())))); } public static List<String> getProperties(Object entity, boolean selective) { diff --git a/mybatis-boost-spring-boot-autoconfigure/pom.xml b/mybatis-boost-spring-boot-autoconfigure/pom.xml index f0c277d..eb7c86d 100644 --- a/mybatis-boost-spring-boot-autoconfigure/pom.xml +++ b/mybatis-boost-spring-boot-autoconfigure/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>cn.mybatisboost</groupId> <artifactId>mybatis-boost</artifactId> - <version>2.3.1</version> + <version>2.3.2</version> </parent> <artifactId>mybatis-boost-spring-boot-autoconfigure</artifactId> diff --git a/mybatis-boost-spring-boot-starter/pom.xml b/mybatis-boost-spring-boot-starter/pom.xml index 577f96c..cb41151 100644 --- a/mybatis-boost-spring-boot-starter/pom.xml +++ b/mybatis-boost-spring-boot-starter/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>cn.mybatisboost</groupId> <artifactId>mybatis-boost</artifactId> - <version>2.3.1</version> + <version>2.3.2</version> </parent> <artifactId>mybatis-boost-spring-boot-starter</artifactId> diff --git a/mybatis-boost-test/pom.xml b/mybatis-boost-test/pom.xml index c6c6110..463cb64 100644 --- a/mybatis-boost-test/pom.xml +++ b/mybatis-boost-test/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>cn.mybatisboost</groupId> <artifactId>mybatis-boost</artifactId> - <version>2.3.1</version> + <version>2.3.2</version> </parent> <artifactId>mybatis-boost-test</artifactId> diff --git a/pom.xml b/pom.xml index 1ad650e..dc40880 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ <groupId>cn.mybatisboost</groupId> <artifactId>mybatis-boost</artifactId> - <version>2.3.1</version> + <version>2.3.2</version> <packaging>pom</packaging> <name>MybatisBoost</name>