Skip to content

Commit 0f6e9ab

Browse files
authored
Merge pull request #3 from mybatis/master
feat: merge from master
2 parents eec7172 + ea6fe1f commit 0f6e9ab

File tree

67 files changed

+1259
-257
lines changed

Some content is hidden

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

67 files changed

+1259
-257
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ language: java
22

33
jdk:
44
- openjdk-ea
5+
- openjdk13
56
- openjdk12
67
- openjdk11
78
- oraclejdk8

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ MyBatis SQL Mapper Framework for Java
44
[![Build Status](https://travis-ci.org/mybatis/mybatis-3.svg?branch=master)](https://travis-ci.org/mybatis/mybatis-3)
55
[![Coverage Status](https://coveralls.io/repos/mybatis/mybatis-3/badge.svg?branch=master&service=github)](https://coveralls.io/github/mybatis/mybatis-3?branch=master)
66
[![Maven central](https://maven-badges.herokuapp.com/maven-central/org.mybatis/mybatis/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.mybatis/mybatis)
7-
[![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/https/oss.sonatype.org/org.mybatis/mybatis.svg)](https://oss.sonatype.org/content/repositories/snapshots/org/mybatis/mybatis)
7+
[![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/https/oss.sonatype.org/org.mybatis/mybatis.svg)](https://oss.sonatype.org/content/repositories/snapshots/org/mybatis/mybatis/)
88
[![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html)
99
[![Stack Overflow](http://img.shields.io/:stack%20overflow-mybatis-brightgreen.svg)](http://stackoverflow.com/questions/tagged/mybatis)
1010
[![Project Stats](https://www.openhub.net/p/mybatis/widgets/project_thin_badge.gif)](https://www.openhub.net/p/mybatis)

pom.xml

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
</parent>
2828

2929
<artifactId>mybatis</artifactId>
30-
<version>3.5.2-SNAPSHOT</version>
30+
<version>3.5.3-SNAPSHOT</version>
3131
<packaging>jar</packaging>
3232

3333
<name>mybatis</name>
@@ -200,7 +200,7 @@
200200
<dependency>
201201
<groupId>org.junit.jupiter</groupId>
202202
<artifactId>junit-jupiter-engine</artifactId>
203-
<version>5.4.1</version>
203+
<version>5.5.0</version>
204204
<scope>test</scope>
205205
</dependency>
206206
<dependency>
@@ -252,6 +252,12 @@
252252
<version>42.2.5</version>
253253
<scope>test</scope>
254254
</dependency>
255+
<dependency>
256+
<groupId>mysql</groupId>
257+
<artifactId>mysql-connector-java</artifactId>
258+
<version>8.0.17</version>
259+
<scope>test</scope>
260+
</dependency>
255261
<dependency>
256262
<groupId>org.assertj</groupId>
257263
<artifactId>assertj-core</artifactId>
@@ -267,13 +273,19 @@
267273
<dependency>
268274
<groupId>org.testcontainers</groupId>
269275
<artifactId>junit-jupiter</artifactId>
270-
<version>1.11.2</version>
276+
<version>1.12.1</version>
271277
<scope>test</scope>
272278
</dependency>
273279
<dependency>
274280
<groupId>org.testcontainers</groupId>
275281
<artifactId>postgresql</artifactId>
276-
<version>1.11.2</version>
282+
<version>1.12.1</version>
283+
<scope>test</scope>
284+
</dependency>
285+
<dependency>
286+
<groupId>org.testcontainers</groupId>
287+
<artifactId>mysql</artifactId>
288+
<version>1.12.1</version>
277289
<scope>test</scope>
278290
</dependency>
279291
</dependencies>

src/main/java/org/apache/ibatis/binding/MapperProxy.java

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
import java.io.Serializable;
1919
import java.lang.invoke.MethodHandles;
20+
import java.lang.invoke.MethodHandles.Lookup;
21+
import java.lang.invoke.MethodType;
2022
import java.lang.reflect.Constructor;
2123
import java.lang.reflect.InvocationHandler;
2224
import java.lang.reflect.Method;
@@ -32,6 +34,10 @@
3234
public class MapperProxy<T> implements InvocationHandler, Serializable {
3335

3436
private static final long serialVersionUID = -6424540398559729838L;
37+
private static final int ALLOWED_MODES = MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED
38+
| MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC;
39+
private static final Constructor<Lookup> lookupConstructor;
40+
private static final Method privateLookupInMethod;
3541
private final SqlSession sqlSession;
3642
private final Class<T> mapperInterface;
3743
private final Map<Method, MapperMethod> methodCache;
@@ -42,13 +48,43 @@ public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method,
4248
this.methodCache = methodCache;
4349
}
4450

51+
static {
52+
Method privateLookupIn;
53+
try {
54+
privateLookupIn = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class);
55+
} catch (NoSuchMethodException e) {
56+
privateLookupIn = null;
57+
}
58+
privateLookupInMethod = privateLookupIn;
59+
60+
Constructor<Lookup> lookup = null;
61+
if (privateLookupInMethod == null) {
62+
// JDK 1.8
63+
try {
64+
lookup = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
65+
lookup.setAccessible(true);
66+
} catch (NoSuchMethodException e) {
67+
throw new IllegalStateException(
68+
"There is neither 'privateLookupIn(Class, Lookup)' nor 'Lookup(Class, int)' method in java.lang.invoke.MethodHandles.",
69+
e);
70+
} catch (Throwable t) {
71+
lookup = null;
72+
}
73+
}
74+
lookupConstructor = lookup;
75+
}
76+
4577
@Override
4678
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
4779
try {
4880
if (Object.class.equals(method.getDeclaringClass())) {
4981
return method.invoke(this, args);
5082
} else if (method.isDefault()) {
51-
return invokeDefaultMethod(proxy, method, args);
83+
if (privateLookupInMethod == null) {
84+
return invokeDefaultMethodJava8(proxy, method, args);
85+
} else {
86+
return invokeDefaultMethodJava9(proxy, method, args);
87+
}
5288
}
5389
} catch (Throwable t) {
5490
throw ExceptionUtil.unwrapThrowable(t);
@@ -58,21 +94,23 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
5894
}
5995

6096
private MapperMethod cachedMapperMethod(Method method) {
61-
return methodCache.computeIfAbsent(method, k -> new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));
97+
return methodCache.computeIfAbsent(method,
98+
k -> new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));
6299
}
63100

64-
private Object invokeDefaultMethod(Object proxy, Method method, Object[] args)
101+
private Object invokeDefaultMethodJava9(Object proxy, Method method, Object[] args)
102+
throws Throwable {
103+
final Class<?> declaringClass = method.getDeclaringClass();
104+
return ((Lookup) privateLookupInMethod.invoke(null, declaringClass, MethodHandles.lookup()))
105+
.findSpecial(declaringClass, method.getName(),
106+
MethodType.methodType(method.getReturnType(), method.getParameterTypes()), declaringClass)
107+
.bindTo(proxy).invokeWithArguments(args);
108+
}
109+
110+
private Object invokeDefaultMethodJava8(Object proxy, Method method, Object[] args)
65111
throws Throwable {
66-
final Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class
67-
.getDeclaredConstructor(Class.class, int.class);
68-
if (!constructor.isAccessible()) {
69-
constructor.setAccessible(true);
70-
}
71112
final Class<?> declaringClass = method.getDeclaringClass();
72-
return constructor
73-
.newInstance(declaringClass,
74-
MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED
75-
| MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC)
76-
.unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args);
113+
return lookupConstructor.newInstance(declaringClass, ALLOWED_MODES).unreflectSpecial(method, declaringClass)
114+
.bindTo(proxy).invokeWithArguments(args);
77115
}
78116
}

src/main/java/org/apache/ibatis/builder/BaseBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ protected Object createInstance(String alias) {
102102
return null;
103103
}
104104
try {
105-
return resolveClass(alias).newInstance();
105+
return resolveClass(alias).getDeclaredConstructor().newInstance();
106106
} catch (Exception e) {
107107
throw new BuilderException("Error creating instance. Cause: " + e, e);
108108
}

src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.apache.ibatis.builder;
1717

1818
import java.util.ArrayList;
19+
import java.util.Collections;
1920
import java.util.HashMap;
2021
import java.util.HashSet;
2122
import java.util.List;
@@ -369,7 +370,12 @@ public ResultMapping buildResultMapping(
369370
boolean lazy) {
370371
Class<?> javaTypeClass = resolveResultJavaType(resultType, property, javaType);
371372
TypeHandler<?> typeHandlerInstance = resolveTypeHandler(javaTypeClass, typeHandler);
372-
List<ResultMapping> composites = parseCompositeColumnName(column);
373+
List<ResultMapping> composites;
374+
if ((nestedSelect == null || nestedSelect.isEmpty()) && (foreignColumn == null || foreignColumn.isEmpty())) {
375+
composites = Collections.emptyList();
376+
} else {
377+
composites = parseCompositeColumnName(column);
378+
}
373379
return new ResultMapping.Builder(configuration, property, column, javaTypeClass)
374380
.jdbcType(jdbcType)
375381
.nestedQueryId(applyCurrentNamespace(nestedSelect, true))

src/main/java/org/apache/ibatis/builder/annotation/MapperAnnotationBuilder.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ void parseStatement(Method method) {
306306
Integer fetchSize = null;
307307
Integer timeout = null;
308308
StatementType statementType = StatementType.PREPARED;
309-
ResultSetType resultSetType = null;
309+
ResultSetType resultSetType = configuration.getDefaultResultSetType();
310310
SqlCommandType sqlCommandType = getSqlCommandType(method);
311311
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
312312
boolean flushCache = !isSelect;
@@ -342,7 +342,9 @@ void parseStatement(Method method) {
342342
fetchSize = options.fetchSize() > -1 || options.fetchSize() == Integer.MIN_VALUE ? options.fetchSize() : null; //issue #348
343343
timeout = options.timeout() > -1 ? options.timeout() : null;
344344
statementType = options.statementType();
345-
resultSetType = options.resultSetType();
345+
if (options.resultSetType() != ResultSetType.DEFAULT) {
346+
resultSetType = options.resultSetType();
347+
}
346348
}
347349

348350
String resultMapId = null;

0 commit comments

Comments
 (0)