Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit db6e1e7

Browse files
Merge pull request #18 from VonChange/develop
Develop
2 parents 4ae793f + 91b304e commit db6e1e7

File tree

150 files changed

+3478
-3661
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

150 files changed

+3478
-3661
lines changed

‎README.md‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,19 @@ SELECT [@id column] FROM user_base
2626
</where>
2727
```
2828
## see [easy-dynamic-sql.md](easy-dynamic-sql.md)
29+
30+
* extend findByExample,findByBeanProperties [UserExample.java](spring-data-jdbc-mybatis-demo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fvonchange%2Fnine%2Fdemo%2Fdao%2FUserExample.java)
31+
```
32+
userInfoMethodDao.findAll(UserExample.builder()
33+
.userCodeIn(Arrays.asList("u001","u002"))
34+
.userNameLike("ch%")
35+
.createTimeDesc(true).build());
36+
```
37+
2938
## Features
3039
* method name query [method-name-query.md](method-name-query.md)
3140
* @Id @Table @Column
32-
* extend CrudJdbcRepository not CrudRepository,because [curd-repository.md](curd-repository.md)
41+
* recommend CrudExtendRepository not CrudRepository,because [curd-repository.md](curd-repository.md)
3342
* not support @Query or QueryDSL, sql must be written in markdown
3443
* batch update [bach-update.md](bach-update.md)
3544
* [multi-datasource.md](multi-datasource.md)
@@ -38,7 +47,7 @@ SELECT [@id column] FROM user_base
3847

3948
[UserInfoRepository.java](spring-data-jdbc-mybatis-demo%2Fsrc%2Fmain%2Fjava%2Fcom%2Fvonchange%2Fnine%2Fdemo%2Fdao%2FUserInfoRepository.java)
4049
```java
41-
public interface UserInfoRepository extends CrudJdbcRepository<UserInfoDO, Long> {
50+
public interface UserInfoRepository extends CrudExtendRepository<UserInfoDO, Long> {
4251
List<UserInfoDO> findByUserCodes(@Param("userCodes") List<String> userCodes);
4352
List<UserInfoDO> findUserBySearchParam(@Param("param") SearchParam searchParam);
4453
}

‎README.zh-CN.md‎

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99

1010
**spring data jdbc 扩展 mybatis 动态sql能力**
1111
## What Is This?
12+
* 底层 jdbcTemplate 复杂SQL才需要mybatis动态模板能力 无QueryDSL 提供crudClient 和jdbcClient
13+
1214
* 和spring data jdbc一样的追求简单,使用jdbcTemplate,调用jdbc。不提供缓存、延迟加载、QueryDSL等JPA或mybatis的许多特性。一个简单、有限、固执己见的ORM
1315

14-
* 扩展mybatis动态sql能力(不依赖mybatis!提取了动态sql代码),可以应对复杂sql,如果换其他模板引擎或自己实现也是可以的,但有一定的学习成本,使用mybatis动态sql已比较成熟
16+
* 扩展mybatis动态sql能力(不依赖mybatis!提取了动态sql代码),可以应对复杂sql,如果换其他模板引擎也是可以的,但有学习成本
1517

16-
* SQL统一写在Markdown里,不提供@Query或QueryDSL
18+
* 复杂的SQL写在Markdown的代码片段中,不提供@Query和QueryDSL写法,但按方法名查找和扩展的findByExample可以应付大部分单表查询需求
1719

18-
* 扩展简易动态sql写法 [easy-dynamic-sql.md](easy-dynamic-sql.md)
20+
* 简化mybatis动态sql写法 [easy-dynamic-sql.md](easy-dynamic-sql.md)
1921

2022
[UserInfoRepository.md](spring-data-jdbc-mybatis-demo%2Fsrc%2Fmain%2Fresources%2Fsql%2FUserInfoRepository.md)
2123

@@ -29,18 +31,26 @@ SELECT [@id column] FROM user_info
2931
<if test="null!=createTime"> and create_time < #{createTime} </if>
3032
</where>
3133
```
34+
* 扩展findByExample 按实体属性名查询扩展 入参是任意符合规范的实体 但请慎用 传入实体不可过多字段
35+
```
36+
userInfoMethodDao.findAll(UserExample.builder()
37+
.userCodeIn(Arrays.asList("u001","u002"))
38+
.userNameLike("ch%")
39+
.createTimeDesc(true).build());
40+
```
41+
3242
## 特性
33-
* 支持按方法名查询 但不推荐过度使用 [method-name-query.md](method-name-query.md)
34-
* @Id @Table @Column 极少的注解
35-
* crud 继成 CrudJdbcRepository 不是CrudRepository 因为需要新增和去掉部分方法
43+
* 支持按方法名查询 [method-name-query.md](method-name-query.md) 以及扩展版findByExample
44+
* @Id @Table @Column @Version@Transient极少的注解
45+
* 请使用CrudExtendRepository 新增insert update insertBatch updateBatch 扩展版findByExample
3646
* 不提供@Query或QueryDSL,sql统一写在markdown文件里面
3747
* 批量更新 [bach-update.md](bach-update.md)
3848
* [多数据源.md](multi-datasource.md)
3949

4050
## Getting Started with JDBC mybatis
4151

4252
```java
43-
public interface UserInfoRepository extends CrudJdbcRepository<UserInfoDO, Long> {
53+
public interface UserInfoRepository extends CrudExtendRepository<UserInfoDO, Long> {
4454
List<UserInfoDO> findByUserCodes(@Param("userCodes") List<String> userCodes);
4555
List<UserInfoDO> findUserBySearchParam(@Param("param") SearchParam searchParam);
4656
}

‎common-util/pom.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<modelVersion>4.0.0</modelVersion>
1111

1212
<artifactId>common-util</artifactId>
13-
<version>2.5.0</version>
13+
<version>2.5.0.1</version>
1414

1515
<dependencies>
1616

‎common-util/src/main/java/com/vonchange/common/util/ClazzUtils.java‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
import com.vonchange.common.util.bean.convert.Converter;
44

5+
import java.net.URI;
6+
import java.net.URL;
7+
import java.util.Collection;
8+
import java.util.Locale;
9+
510
public class ClazzUtils {
611
private ClazzUtils() {
712
throw new IllegalStateException("Utility class");
@@ -12,7 +17,16 @@ private ClazzUtils() {
1217
*/
1318
public static boolean isBaseType(Class<?> clazz) {
1419
// ||clazz== Time.class||clazz == Timestamp.class
15-
return Converter.hasConvertKey(clazz) || clazz.isPrimitive() || clazz.isEnum();
20+
return Converter.hasConvertKey(clazz) || clazz.isPrimitive() ||
21+
Enum.class.isAssignableFrom(clazz) ||
22+
URI.class == clazz || URL.class == clazz ||
23+
Locale.class == clazz || Class.class == clazz;
24+
}
25+
public static boolean isBaseTypeWithArray(Class<?> clazz) {
26+
return isBaseType(clazz)||(clazz.isArray()&& isBaseType(clazz.getComponentType()))|| Collection.class.isAssignableFrom(clazz) ;
27+
}
28+
public static boolean isVersionType(Class<?> clazz) {
29+
return Integer.class==clazz||Long.class==clazz;
1630
}
1731

1832
@SuppressWarnings("unchecked")
@@ -21,6 +35,15 @@ public static <T> T cast(Class<?> clazz, Object obj) {
2135
throw new ClassCastException(cannotCastMsg(clazz, obj));
2236
return (T) obj;
2337
}
38+
public static boolean isClassExists(String className) {
39+
try {
40+
Class.forName(className);
41+
return true;
42+
} catch (ClassNotFoundException e) {
43+
return false;
44+
}
45+
}
46+
2447

2548
@SuppressWarnings("unchecked")
2649
public static <T> T cast(Object obj) {

‎common-util/src/main/java/com/vonchange/common/util/ConvertUtil.java‎

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
11
package com.vonchange.common.util;
22

3+
import com.vonchange.common.util.bean.BeanUtil;
4+
import com.vonchange.common.util.bean.MethodAccessData;
35
import com.vonchange.common.util.bean.convert.Converter;
6+
import com.vonchange.common.util.model.BaseField;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
49

10+
import java.lang.reflect.Field;
511
import java.math.BigDecimal;
612
import java.math.BigInteger;
713
import java.nio.charset.Charset;
814
import java.time.LocalDate;
915
import java.time.LocalDateTime;
1016
import java.time.LocalTime;
17+
import java.util.ArrayList;
18+
import java.util.Arrays;
1119
import java.util.Date;
20+
import java.util.HashMap;
21+
import java.util.List;
22+
import java.util.Map;
23+
import java.util.concurrent.ConcurrentHashMap;
1224

1325
/**
1426
* 简单方式(效率高)实现类型转换,细节部分会不如ConvertUtils :ConvertUtils一次类型转换需要69ms 有点代价过高
@@ -17,15 +29,78 @@
1729
* @author vonchange@163.com
1830
*/
1931
public class ConvertUtil {
20-
private static final String NULLSTR = "NULL";
32+
private static Logger log = LoggerFactory.getLogger(ConvertUtil.class);
33+
private static final String NULL_STR = "NULL";
34+
private static final Map<String, List<BaseField>> fieldMap = new ConcurrentHashMap<>();
35+
36+
@SuppressWarnings("unchecked")
37+
public static <T> Map<String, Object> toMap(T entity) {
38+
if (entity instanceof Map) {
39+
return (Map<String, Object>) entity;
40+
}
41+
List<BaseField> baseFields =getBeanInfo(entity.getClass());
42+
MethodAccessData methodAccessData = BeanUtil.methodAccessData(entity.getClass());
43+
Map<String, Object> map = new HashMap<>();
44+
for (BaseField baseField : baseFields) {
45+
Integer index =BeanUtil.getPropertyIndex(methodAccessData,baseField.getFieldName());
46+
if(null!=index){
47+
Object value=methodAccessData.getMethodAccess().invoke(entity,index);
48+
map.put(baseField.getFieldName(),value);
49+
}
50+
}
51+
return map;
52+
}
53+
public static List<BaseField> getBeanInfo(Class<?> clazz){
54+
String entityName = clazz.getName();
55+
if(!fieldMap.containsKey(entityName)){
56+
initField(clazz);
57+
}
58+
return fieldMap.get(entityName);
59+
}
60+
private static void getFieldList(Class<?> clazz, List<Field> fieldList) {
61+
fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
62+
if(null!=clazz.getSuperclass()){
63+
getFieldList(clazz.getSuperclass(), fieldList);
64+
}
65+
}
66+
67+
private static synchronized void initField(Class<?> clazz) {
68+
if(ClazzUtils.isBaseType(clazz)){
69+
return;
70+
}
71+
String entityName=clazz.getName();
72+
log.debug("initField {}",entityName);
73+
List<Field> fieldList = new ArrayList<>();
74+
getFieldList(clazz,fieldList);
75+
List<BaseField> entityFieldList = new ArrayList<>();
76+
Map<String,Integer> fieldHasMap = new HashMap<>();
77+
MethodAccessData methodAccessData = BeanUtil.methodAccessData(clazz);
78+
int i=0;
79+
for (Field field : fieldList) {
80+
Class<?> type = field.getType();
81+
boolean isNormalField =BeanUtil.containsProperty(methodAccessData,field.getName(),"set")
82+
&&ClazzUtils.isBaseType(type);
83+
String fieldName = field.getName();
84+
if(!isNormalField||fieldHasMap.containsKey(fieldName)){
85+
continue;
86+
}
87+
BaseField entityField = new BaseField();
88+
entityField.setFieldName(fieldName);
89+
entityField.setType(type);
90+
entityFieldList.add(entityField);
91+
fieldHasMap.put(fieldName, i);
92+
i++;
93+
}
94+
fieldMap.put(clazz.getName(), entityFieldList);
95+
}
2196

2297
private static Object toNull(Object value) {
2398
if (null == value) {
2499
return null;
25100
}
26101
if (value instanceof String) {
27102
value = value.toString().trim();
28-
if (NULLSTR.equals(value)) {
103+
if (NULL_STR.equals(value)) {
29104
return null;
30105
}
31106
if ("".equals(value)) {

‎common-util/src/main/java/com/vonchange/common/util/JsonUtil.java‎

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,44 @@
44
import com.fasterxml.jackson.core.JsonProcessingException;
55
import com.fasterxml.jackson.core.type.TypeReference;
66
import com.fasterxml.jackson.databind.DeserializationFeature;
7+
import com.fasterxml.jackson.databind.Module;
78
import com.fasterxml.jackson.databind.ObjectMapper;
89
import org.slf4j.Logger;
910
import org.slf4j.LoggerFactory;
1011

1112
import java.io.IOException;
13+
import java.util.ArrayList;
14+
import java.util.List;
1215

1316
public class JsonUtil {
14-
private static Logger logger = LoggerFactory.getLogger(JsonUtil.class);
17+
private static Logger log = LoggerFactory.getLogger(JsonUtil.class);
1518
private JsonUtil() {
1619
throw new IllegalStateException("Utility class");
1720
}
21+
static ObjectMapper objectMapper;
22+
static List<String> moduleList=new ArrayList<>();
23+
static {
24+
objectMapper=new ObjectMapper();
25+
moduleList.add("com.fasterxml.jackson.datatype.jsr310.JavaTimeModule");
26+
moduleList.add("com.fasterxml.jackson.module.paramnames.ParameterNamesModule");
27+
moduleList.add("com.fasterxml.jackson.datatype.jdk8.Jdk8Module");
28+
for (String module : moduleList) {
29+
if(ClazzUtils.isClassExists(module)){
30+
try {
31+
objectMapper.registerModule((Module) Class.forName(module).newInstance());
32+
} catch (Exception e) {
33+
log.info("registerModule {} {}",module,e.getMessage());
34+
}
35+
}
36+
}
37+
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES,true);
38+
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
39+
}
1840
public static String toJson(Object object) {
19-
ObjectMapper objectMapper = new ObjectMapper();
2041
try {
2142
return objectMapper.writeValueAsString(object);
2243
} catch (JsonProcessingException e) {
23-
logger.error("序列化对象失败{}",e);
44+
log.error("toJson",e);
2445
}
2546
return null;
2647
}
@@ -35,33 +56,22 @@ public static <T> T evalJson(String json, Class<T> clazz) throws IOException {
3556
return evalJson(json,clazz,null);
3657
}
3758
public static <T> T evalJson(String json, Class<T> clazz,TypeReference<T> type) throws IOException {
38-
ObjectMapper mapper = new ObjectMapper();
39-
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES,true);
40-
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
4159
T t =null;
4260
if(null!=clazz){
43-
t = mapper.readValue(json, clazz);
61+
t = objectMapper.readValue(json, clazz);
4462
}
4563
if(null!=type){
46-
t = mapper.readValue(json, type);
64+
t = objectMapper.readValue(json, type);
4765
}
4866
return t;
4967
}
5068

5169
private static <T> T fromJson(String json, Class<T> clazz,TypeReference<T> type) {
52-
ObjectMapper mapper = new ObjectMapper();
53-
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES,true);
54-
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
5570
T t =null;
5671
try {
57-
if(null!=clazz){
58-
t = mapper.readValue(json, clazz);
59-
}
60-
if(null!=type){
61-
t = mapper.readValue(json, type);
62-
}
72+
t=evalJson(json,clazz,type);
6373
} catch (IOException e) {
64-
logger.error("反序列化对象失败{}",e);
74+
log.error("fromJson",e);
6575
}
6676
return t;
6777
}

‎common-util/src/main/java/com/vonchange/common/util/MarkdownUtil.java‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33

44
import com.vonchange.common.util.exception.EnumUtilErrorCode;
5+
import com.vonchange.common.util.exception.ErrorMsg;
56
import com.vonchange.common.util.exception.UtilException;
67
import org.slf4j.Logger;
78
import org.slf4j.LoggerFactory;
@@ -32,7 +33,8 @@ public static synchronized Map<String,String> readMarkdownFile(String id,b
3233
if(!notFoundError){
3334
return null;
3435
}
35-
throw new UtilException(path+" not Find");
36+
throw new UtilException(EnumUtilErrorCode.MarkdownPathNotFound,
37+
ErrorMsg.builder().message(path+" not found"));
3638
}
3739
String content=null;
3840
try {
@@ -151,7 +153,8 @@ public static String getContent(String id,boolean notFoundThrowError) {
151153
if(!notFoundThrowError){
152154
return null;
153155
}
154-
throw new UtilException(EnumUtilErrorCode.MarkdownIdNotFound,id+" not found");
156+
throw new UtilException(EnumUtilErrorCode.MarkdownIdNotFound,
157+
ErrorMsg.builder().message(id+" not found"));
155158
}
156159
String filePath= UtilAll.UString.substringBeforeLast(id, StringPool.DOT);
157160
String codeId= id.substring(filePath.length()+1);
@@ -160,7 +163,8 @@ public static String getContent(String id,boolean notFoundThrowError) {
160163
if(!notFoundThrowError){
161164
return null;
162165
}
163-
throw new UtilException(EnumUtilErrorCode.MarkdownIdNotFound,id+" not found");
166+
throw new UtilException(EnumUtilErrorCode.MarkdownIdNotFound,
167+
ErrorMsg.builder().message(id+" not found"));
164168
}
165169
String content= extendContent(contentMap,codeId);
166170
if(UtilAll.UString.isNotBlank(content)){
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.vonchange.common.util;
2+
3+
public class Three<A,B,C>{
4+
private final A first;
5+
private final B second;
6+
7+
private final C third;
8+
9+
private Three(A first, B second, C third) {
10+
this.first = first;
11+
this.second = second;
12+
this.third=third;
13+
}
14+
15+
public static <A, B,C> Three<A, B,C> of(A first, B second, C third) {
16+
return new Three<>(first, second,third);
17+
}
18+
19+
20+
public A getFirst() {
21+
return first;
22+
}
23+
24+
public B getSecond() {
25+
return second;
26+
}
27+
public C getThird() {
28+
return third;
29+
}
30+
31+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /