Skip to content

Commit 35cecc4

Browse files
authored
Merge pull request #19 from VonChange/develop
Develop
2 parents db6e1e7 + 00f5fc8 commit 35cecc4

File tree

47 files changed

+1629
-53
lines changed

Some content is hidden

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

47 files changed

+1629
-53
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,24 @@ public class JdbcMybatisTestApplication {
8484
```
8585

8686

87+
88+
## official spring data jdbc extend mybatis dynamic sql
89+
90+
see spring-data-jdbc-demo
91+
92+
configuration
93+
```
94+
@Configuration
95+
public class MybatisQuerySupportConfig {
96+
@Bean
97+
public NamedParameterJdbcOperations namedParameterJdbcOperations(DataSource dataSource) {
98+
return new MybatisJdbcTemplate(dataSource) {@Override protected Dialect dialect() {return new MySQLDialect();}};
99+
}
100+
}
101+
```
102+
use
103+
```
104+
@Query("user.queryByUserCode")
105+
List<UserDTO> queryByUserCode(@Param("userCode") String userCode);
106+
```
107+
but SpEL support became available with Spring Data JDBC 3.0 RC1

README.zh-CN.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,32 @@
77
[![](https://gitee.com/vonchange/spring-data-jdbc-mybatis/badge/star.svg?theme=dark)
88
](https://gitee.com/vonchange/spring-data-jdbc-mybatis)
99

10-
**spring data jdbc 扩展 mybatis 动态sql能力**
11-
## What Is This?
10+
**简单点 开发的方法简单点 繁琐的功能请省略 你有不是个AI**
11+
## spring data jdbc 扩展 mybatis 动态sql能力
12+
### spring data jdbc官方直接 扩展 mybatis动态sql能力
13+
14+
使用方式和官方教程一直 引入spring-boot-starter-data-jdbc 即可
15+
只需要配置魔改的NamedParameterJdbcTemplate 即可
16+
```
17+
@Configuration
18+
public class MybatisQuerySupportConfig {
19+
@Bean
20+
public NamedParameterJdbcOperations namedParameterJdbcOperations(DataSource dataSource) {
21+
return new MybatisJdbcTemplate(dataSource) {@Override protected Dialect dialect() {return new MySQLDialect();}};
22+
}
23+
}
24+
```
25+
@Query 的ID 是user.md里面ID是queryByUserCode的sql片段
26+
```
27+
@Query("user.queryByUserCode")
28+
List<UserDTO> queryByUserCode(@Param("userCode") String userCode);
29+
```
30+
具体使用参考spring-data-jdbc-demo
31+
但是 @Query spring 6(jdk17以上) 以上才支持SPEL 不支持实体参数
32+
通过改代码可以解决(支持mybatis版本的) 但有代码侵入性
33+
无法直接 根据方法名 自动查找sql片段
34+
35+
### 更推荐自研版本spring data jdbc扩展 mybatis动态sql能力
1236
* 底层 jdbcTemplate 复杂SQL才需要mybatis动态模板能力 无QueryDSL 提供crudClient 和jdbcClient
1337

1438
* 和spring data jdbc一样的追求简单,使用jdbcTemplate,调用jdbc。不提供缓存、延迟加载、QueryDSL等JPA或mybatis的许多特性。一个简单、有限、固执己见的ORM

jdbc-mybatis/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
</parent>
1010
<modelVersion>4.0.0</modelVersion>
1111
<artifactId>jdbc-mybatis</artifactId>
12-
<version>2.5.0.1</version>
12+
<version>2.5.1</version>
1313
<dependencies>
1414
<dependency>
1515
<groupId>com.vonchange.common</groupId>
1616
<artifactId>mybatis-sql-extend</artifactId>
17-
<version>2.5.0.1</version>
17+
<version>2.5.1</version>
1818
</dependency>
1919
<dependency>
2020
<groupId>com.vonchange.common</groupId>

jdbc-mybatis/src/main/java/com/vonchange/jdbc/core/CrudClient.java renamed to jdbc-mybatis/src/main/java/com/vonchange/jdbc/client/CrudClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.vonchange.jdbc.core;/*
1+
package com.vonchange.jdbc.client;/*
22
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,8 +15,8 @@
1515
*/
1616

1717

18-
import com.vonchange.jdbc.client.JdbcClient;
1918
import com.vonchange.jdbc.config.ConstantJdbc;
19+
import com.vonchange.jdbc.core.DefaultCrudClient;
2020
import com.vonchange.jdbc.mapper.AbstractPageWork;
2121
import com.vonchange.jdbc.model.DataSourceWrapper;
2222
import com.vonchange.mybatis.dialect.MySQLDialect;

jdbc-mybatis/src/main/java/com/vonchange/jdbc/core/DefaultCrudClient.java

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

33
import com.vonchange.common.util.ConvertUtil;
44
import com.vonchange.common.util.StringPool;
5+
import com.vonchange.jdbc.client.CrudClient;
56
import com.vonchange.jdbc.client.JdbcClient;
67
import com.vonchange.jdbc.config.ConstantJdbc;
78
import com.vonchange.jdbc.config.EnumRWType;
@@ -29,7 +30,7 @@
2930
import java.util.Map;
3031
import java.util.concurrent.ConcurrentHashMap;
3132

32-
public class DefaultCrudClient implements CrudClient{
33+
public class DefaultCrudClient implements CrudClient {
3334
private static final Logger log = LoggerFactory.getLogger(DefaultCrudClient.class);
3435
private final MyJdbcTemplate classicOps;
3536
private final DataSourceWrapper dataSourceWrapper;
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package com.vonchange.jdbc.mybatis;
2+
3+
import com.vonchange.common.util.StringPool;
4+
import com.vonchange.jdbc.model.SqlParam;
5+
import com.vonchange.jdbc.util.JdbcUtil;
6+
import com.vonchange.jdbc.util.MybatisTpl;
7+
import com.vonchange.mybatis.dialect.Dialect;
8+
import org.springframework.jdbc.core.JdbcOperations;
9+
import org.springframework.jdbc.core.PreparedStatementCreator;
10+
import org.springframework.jdbc.core.PreparedStatementCreatorFactory;
11+
import org.springframework.jdbc.core.SqlParameter;
12+
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
13+
import org.springframework.jdbc.core.namedparam.NamedParameterUtils;
14+
import org.springframework.jdbc.core.namedparam.ParsedSql;
15+
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
16+
import org.springframework.jdbc.support.JdbcUtils;
17+
import org.springframework.lang.Nullable;
18+
19+
import javax.sql.DataSource;
20+
import java.util.ArrayList;
21+
import java.util.Collection;
22+
import java.util.HashMap;
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.function.Consumer;
26+
27+
public abstract class MybatisJdbcTemplate extends NamedParameterJdbcTemplate {
28+
public MybatisJdbcTemplate(DataSource dataSource) {
29+
super(dataSource);
30+
}
31+
32+
public MybatisJdbcTemplate(JdbcOperations classicJdbcTemplate) {
33+
super(classicJdbcTemplate);
34+
}
35+
36+
protected PreparedStatementCreator getPreparedStatementCreator(String sql, SqlParameterSource paramSource,
37+
@Nullable Consumer<PreparedStatementCreatorFactory> customizer) {
38+
Map<String,Object> param =toMap(paramSource);
39+
SqlParam sqlParam = genSqlParam(sql,param);
40+
if(null==sqlParam){
41+
return getPreparedStatementCreatorOriginal(sql,paramSource,customizer);
42+
}
43+
Object[] paramObj=sqlParam.getParams().toArray();
44+
List<SqlParameter> declaredParameters = buildSqlParameterList(sqlParam.getParams());
45+
PreparedStatementCreatorFactory pscf = new PreparedStatementCreatorFactory(sqlParam.getSql(),declaredParameters);
46+
if (customizer != null) {
47+
customizer.accept(pscf);
48+
}
49+
return pscf.newPreparedStatementCreator(sqlParam.getSql(),paramObj);
50+
}
51+
protected PreparedStatementCreator getPreparedStatementCreatorOriginal(String sql, SqlParameterSource paramSource,
52+
@Nullable Consumer<PreparedStatementCreatorFactory> customizer) {
53+
54+
ParsedSql parsedSql = getParsedSql(sql);
55+
PreparedStatementCreatorFactory pscf = getPreparedStatementCreatorFactory(parsedSql, paramSource);
56+
if (customizer != null) {
57+
customizer.accept(pscf);
58+
}
59+
Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, null);
60+
return pscf.newPreparedStatementCreator(params);
61+
}
62+
protected abstract Dialect dialect();
63+
private SqlParam genSqlParam(String sql,Map<String,Object> param){
64+
if(!sql.contains(StringPool.SPACE)){
65+
return MybatisTpl.generate("sql."+sql,param,dialect());
66+
}
67+
if(sql.contains("[@")){//#{ spel 也有的 ||sql.contains("#{"
68+
return MybatisTpl.generate(sql,sql,param,dialect());
69+
}
70+
if(sql.contains("#{")){
71+
if(!sql.contains(":#{")){
72+
return MybatisTpl.generate(sql,sql,param,dialect());
73+
}
74+
}
75+
return null;
76+
}
77+
public static List<SqlParameter> buildSqlParameterList(Collection<?> param) {
78+
List<SqlParameter> params = new ArrayList<>(param.size());
79+
for (Object value : param) {
80+
if(null==value){
81+
params.add(new SqlParameter(JdbcUtils.TYPE_UNKNOWN));
82+
continue;
83+
}
84+
params.add(new SqlParameter(JdbcUtil.sqlTypeFor(value.getClass())));
85+
}
86+
return params;
87+
}
88+
public static List<SqlParameter> buildSqlParameterListX(SqlParameterSource paramSource) {
89+
String[] paramNames = paramSource.getParameterNames();
90+
if (paramNames == null) {
91+
return new ArrayList<>();
92+
}
93+
List<SqlParameter> params = new ArrayList<>(paramNames.length);
94+
for (String paramName : paramNames) {
95+
params.add(new SqlParameter(
96+
paramName, paramSource.getSqlType(paramName), paramSource.getTypeName(paramName)));
97+
}
98+
return params;
99+
}
100+
101+
private Map<String,Object> toMap( SqlParameterSource paramSource){
102+
String[] parameterNames = paramSource.getParameterNames();
103+
Map<String,Object> map = new HashMap<>();
104+
if(null==parameterNames){
105+
return map;
106+
}
107+
for (String paramName : parameterNames) {
108+
map.put(paramName,paramSource.getValue(paramName));
109+
}
110+
return map;
111+
}
112+
113+
114+
115+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2017-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.vonchange.jdbc.util;
17+
18+
19+
import org.springframework.jdbc.support.JdbcUtils;
20+
21+
import java.math.BigDecimal;
22+
import java.math.BigInteger;
23+
import java.sql.Date;
24+
import java.sql.Time;
25+
import java.sql.Timestamp;
26+
import java.sql.Types;
27+
import java.util.HashMap;
28+
import java.util.Map;
29+
30+
/**
31+
* Contains methods dealing with the quirks of JDBC, independent of any Entity, Aggregate or Repository abstraction.
32+
*
33+
* @author Jens Schauder
34+
*/
35+
public class JdbcUtil {
36+
37+
private static final Map<Class<?>, Integer> sqlTypeMappings = new HashMap<>();
38+
39+
static {
40+
41+
sqlTypeMappings.put(String.class, Types.VARCHAR);
42+
sqlTypeMappings.put(BigInteger.class, Types.BIGINT);
43+
sqlTypeMappings.put(BigDecimal.class, Types.NUMERIC);
44+
sqlTypeMappings.put(Byte.class, Types.TINYINT);
45+
sqlTypeMappings.put(byte.class, Types.TINYINT);
46+
sqlTypeMappings.put(Short.class, Types.SMALLINT);
47+
sqlTypeMappings.put(short.class, Types.SMALLINT);
48+
sqlTypeMappings.put(Integer.class, Types.INTEGER);
49+
sqlTypeMappings.put(int.class, Types.INTEGER);
50+
sqlTypeMappings.put(Long.class, Types.BIGINT);
51+
sqlTypeMappings.put(long.class, Types.BIGINT);
52+
sqlTypeMappings.put(Double.class, Types.DOUBLE);
53+
sqlTypeMappings.put(double.class, Types.DOUBLE);
54+
sqlTypeMappings.put(Float.class, Types.REAL);
55+
sqlTypeMappings.put(float.class, Types.REAL);
56+
sqlTypeMappings.put(Boolean.class, Types.BIT);
57+
sqlTypeMappings.put(boolean.class, Types.BIT);
58+
sqlTypeMappings.put(byte[].class, Types.VARBINARY);
59+
sqlTypeMappings.put(Date.class, Types.DATE);
60+
sqlTypeMappings.put(Time.class, Types.TIME);
61+
sqlTypeMappings.put(Timestamp.class, Types.TIMESTAMP);
62+
}
63+
64+
public static int sqlTypeFor(Class<?> type) {
65+
return sqlTypeMappings.keySet().stream() //
66+
.filter(k -> k.isAssignableFrom(type)) //
67+
.findFirst() //
68+
.map(sqlTypeMappings::get) //
69+
.orElse(JdbcUtils.TYPE_UNKNOWN);
70+
}
71+
}

mybatis-sql-extend-test/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<artifactId>mybatis-sql-extend-test</artifactId>
1515
<version>2.5.0</version>
1616
<properties>
17-
<spring.jdbc.mybatis>2.5.0</spring.jdbc.mybatis>
17+
<spring.jdbc.mybatis>2.5.1</spring.jdbc.mybatis>
1818
<mysql-connector-java.version>8.0.15</mysql-connector-java.version>
1919
</properties>
2020
<dependencies>

mybatis-sql-extend/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</parent>
1010
<modelVersion>4.0.0</modelVersion>
1111
<artifactId>mybatis-sql-extend</artifactId>
12-
<version>2.5.0.1</version>
12+
<version>2.5.1</version>
1313
<dependencies>
1414
<dependency>
1515
<groupId>com.vonchange.common</groupId>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.vonchange.mybatis.dialect;
2+
3+
public class H2MySqlDialect extends MySQLDialect {
4+
@Override
5+
public int getBigDataFetchSize() {
6+
return 500;
7+
}
8+
9+
@Override
10+
public int getFetchSize() {
11+
return -1;
12+
}
13+
14+
@Override
15+
public String getDialogName() {
16+
return "h2-mysql";
17+
}
18+
}

0 commit comments

Comments
 (0)