|
15 | 15 | */
|
16 | 16 | package org.apache.ibatis.type;
|
17 | 17 |
|
| 18 | +import java.math.BigDecimal; |
| 19 | +import java.math.BigInteger; |
| 20 | +import java.net.URL; |
18 | 21 | import java.sql.Array;
|
19 | 22 | import java.sql.CallableStatement;
|
20 | 23 | import java.sql.PreparedStatement;
|
21 | 24 | import java.sql.ResultSet;
|
22 | 25 | import java.sql.SQLException;
|
| 26 | +import java.sql.Time; |
| 27 | +import java.sql.Timestamp; |
| 28 | +import java.time.LocalDate; |
| 29 | +import java.time.LocalDateTime; |
| 30 | +import java.time.LocalTime; |
| 31 | +import java.time.OffsetDateTime; |
| 32 | +import java.time.OffsetTime; |
| 33 | +import java.util.Calendar; |
| 34 | +import java.util.concurrent.ConcurrentHashMap; |
23 | 35 |
|
24 | 36 | /**
|
25 | 37 | * @author Clinton Begin
|
26 | 38 | */
|
27 | 39 | public class ArrayTypeHandler extends BaseTypeHandler<Object> {
|
28 | 40 |
|
| 41 | + private static final ConcurrentHashMap<Class<?>, String> STANDARD_MAPPING; |
| 42 | + static { |
| 43 | + STANDARD_MAPPING = new ConcurrentHashMap<>(); |
| 44 | + STANDARD_MAPPING.put(BigDecimal.class, JdbcType.NUMERIC.name()); |
| 45 | + STANDARD_MAPPING.put(BigInteger.class, JdbcType.BIGINT.name()); |
| 46 | + STANDARD_MAPPING.put(boolean.class, JdbcType.BOOLEAN.name()); |
| 47 | + STANDARD_MAPPING.put(Boolean.class, JdbcType.BOOLEAN.name()); |
| 48 | + STANDARD_MAPPING.put(byte[].class, JdbcType.VARBINARY.name()); |
| 49 | + STANDARD_MAPPING.put(byte.class, JdbcType.TINYINT.name()); |
| 50 | + STANDARD_MAPPING.put(Byte.class, JdbcType.TINYINT.name()); |
| 51 | + STANDARD_MAPPING.put(Calendar.class, JdbcType.TIMESTAMP.name()); |
| 52 | + STANDARD_MAPPING.put(java.sql.Date.class, JdbcType.DATE.name()); |
| 53 | + STANDARD_MAPPING.put(java.util.Date.class, JdbcType.TIMESTAMP.name()); |
| 54 | + STANDARD_MAPPING.put(double.class, JdbcType.DOUBLE.name()); |
| 55 | + STANDARD_MAPPING.put(Double.class, JdbcType.DOUBLE.name()); |
| 56 | + STANDARD_MAPPING.put(float.class, JdbcType.REAL.name()); |
| 57 | + STANDARD_MAPPING.put(Float.class, JdbcType.REAL.name()); |
| 58 | + STANDARD_MAPPING.put(int.class, JdbcType.INTEGER.name()); |
| 59 | + STANDARD_MAPPING.put(Integer.class, JdbcType.INTEGER.name()); |
| 60 | + STANDARD_MAPPING.put(LocalDate.class, JdbcType.DATE.name()); |
| 61 | + STANDARD_MAPPING.put(LocalDateTime.class, JdbcType.TIMESTAMP.name()); |
| 62 | + STANDARD_MAPPING.put(LocalTime.class, JdbcType.TIME.name()); |
| 63 | + STANDARD_MAPPING.put(long.class, JdbcType.BIGINT.name()); |
| 64 | + STANDARD_MAPPING.put(Long.class, JdbcType.BIGINT.name()); |
| 65 | + STANDARD_MAPPING.put(OffsetDateTime.class, JdbcType.TIMESTAMP_WITH_TIMEZONE.name()); |
| 66 | + STANDARD_MAPPING.put(OffsetTime.class, JdbcType.TIME_WITH_TIMEZONE.name()); |
| 67 | + STANDARD_MAPPING.put(Short.class, JdbcType.SMALLINT.name()); |
| 68 | + STANDARD_MAPPING.put(String.class, JdbcType.VARCHAR.name()); |
| 69 | + STANDARD_MAPPING.put(Time.class, JdbcType.TIME.name()); |
| 70 | + STANDARD_MAPPING.put(Timestamp.class, JdbcType.TIMESTAMP.name()); |
| 71 | + STANDARD_MAPPING.put(URL.class, JdbcType.DATALINK.name()); |
| 72 | + } |
| 73 | + |
29 | 74 | public ArrayTypeHandler() {
|
30 | 75 | super();
|
31 | 76 | }
|
32 | 77 |
|
33 | 78 | @Override
|
34 |
| - public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException { |
35 |
| - ps.setArray(i, (Array) parameter); |
| 79 | + public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) |
| 80 | + throws SQLException { |
| 81 | + if (parameter instanceof Array) { |
| 82 | + // it's the user's responsibility to properly free() the Array instance |
| 83 | + ps.setArray(i, (Array) parameter); |
| 84 | + } else { |
| 85 | + if (!parameter.getClass().isArray()) { |
| 86 | + throw new TypeException( |
| 87 | + "ArrayType Handler requires SQL array or java array parameter and does not support type " |
| 88 | + + parameter.getClass()); |
| 89 | + } |
| 90 | + Class<?> componentType = parameter.getClass().getComponentType(); |
| 91 | + String arrayTypeName = resolveTypeName(componentType); |
| 92 | + Array array = ps.getConnection().createArrayOf(arrayTypeName, (Object[]) parameter); |
| 93 | + ps.setArray(i, array); |
| 94 | + array.free(); |
| 95 | + } |
| 96 | + } |
| 97 | + |
| 98 | + protected String resolveTypeName(Class<?> type) { |
| 99 | + return STANDARD_MAPPING.getOrDefault(type, JdbcType.JAVA_OBJECT.name()); |
36 | 100 | }
|
37 | 101 |
|
38 | 102 | @Override
|
|
0 commit comments