1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.type;
17
18 import java.math.BigDecimal;
19 import java.math.BigInteger;
20 import java.net.URL;
21 import java.sql.Array;
22 import java.sql.CallableStatement;
23 import java.sql.PreparedStatement;
24 import java.sql.ResultSet;
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;
35
36
37
38
39 public class ArrayTypeHandler extends BaseTypeHandler<Object> {
40
41 private static final ConcurrentHashMap<Class<?>, String> STANDARD_MAPPING;
42
43 static {
44 STANDARD_MAPPING = new ConcurrentHashMap<>();
45 STANDARD_MAPPING.put(BigDecimal.class, JdbcType.NUMERIC.name());
46 STANDARD_MAPPING.put(BigInteger.class, JdbcType.BIGINT.name());
47 STANDARD_MAPPING.put(boolean.class, JdbcType.BOOLEAN.name());
48 STANDARD_MAPPING.put(Boolean.class, JdbcType.BOOLEAN.name());
49 STANDARD_MAPPING.put(byte[].class, JdbcType.VARBINARY.name());
50 STANDARD_MAPPING.put(byte.class, JdbcType.TINYINT.name());
51 STANDARD_MAPPING.put(Byte.class, JdbcType.TINYINT.name());
52 STANDARD_MAPPING.put(Calendar.class, JdbcType.TIMESTAMP.name());
53 STANDARD_MAPPING.put(java.sql.Date.class, JdbcType.DATE.name());
54 STANDARD_MAPPING.put(java.util.Date.class, JdbcType.TIMESTAMP.name());
55 STANDARD_MAPPING.put(double.class, JdbcType.DOUBLE.name());
56 STANDARD_MAPPING.put(Double.class, JdbcType.DOUBLE.name());
57 STANDARD_MAPPING.put(float.class, JdbcType.REAL.name());
58 STANDARD_MAPPING.put(Float.class, JdbcType.REAL.name());
59 STANDARD_MAPPING.put(int.class, JdbcType.INTEGER.name());
60 STANDARD_MAPPING.put(Integer.class, JdbcType.INTEGER.name());
61 STANDARD_MAPPING.put(LocalDate.class, JdbcType.DATE.name());
62 STANDARD_MAPPING.put(LocalDateTime.class, JdbcType.TIMESTAMP.name());
63 STANDARD_MAPPING.put(LocalTime.class, JdbcType.TIME.name());
64 STANDARD_MAPPING.put(long.class, JdbcType.BIGINT.name());
65 STANDARD_MAPPING.put(Long.class, JdbcType.BIGINT.name());
66 STANDARD_MAPPING.put(OffsetDateTime.class, JdbcType.TIMESTAMP_WITH_TIMEZONE.name());
67 STANDARD_MAPPING.put(OffsetTime.class, JdbcType.TIME_WITH_TIMEZONE.name());
68 STANDARD_MAPPING.put(Short.class, JdbcType.SMALLINT.name());
69 STANDARD_MAPPING.put(String.class, JdbcType.VARCHAR.name());
70 STANDARD_MAPPING.put(Time.class, JdbcType.TIME.name());
71 STANDARD_MAPPING.put(Timestamp.class, JdbcType.TIMESTAMP.name());
72 STANDARD_MAPPING.put(URL.class, JdbcType.DATALINK.name());
73 }
74
75 public ArrayTypeHandler() {
76 super();
77 }
78
79 @Override
80 public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
81 throws SQLException {
82 if (parameter instanceof Array) {
83
84 ps.setArray(i, (Array) parameter);
85 } else {
86 if (!parameter.getClass().isArray()) {
87 throw new TypeException(
88 "ArrayType Handler requires SQL array or java array parameter and does not support type "
89 + parameter.getClass());
90 }
91 Class<?> componentType = parameter.getClass().getComponentType();
92 String arrayTypeName = resolveTypeName(componentType);
93 Array array = ps.getConnection().createArrayOf(arrayTypeName, (Object[]) parameter);
94 ps.setArray(i, array);
95 array.free();
96 }
97 }
98
99 protected String resolveTypeName(Class<?> type) {
100 return STANDARD_MAPPING.getOrDefault(type, JdbcType.JAVA_OBJECT.name());
101 }
102
103 @Override
104 public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
105 return extractArray(rs.getArray(columnName));
106 }
107
108 @Override
109 public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
110 return extractArray(rs.getArray(columnIndex));
111 }
112
113 @Override
114 public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
115 return extractArray(cs.getArray(columnIndex));
116 }
117
118 protected Object extractArray(Array array) throws SQLException {
119 if (array == null) {
120 return null;
121 }
122 Object result = array.getArray();
123 array.free();
124 return result;
125 }
126
127 }