Skip to content

Commit

Permalink
Minor adjustments
Browse files Browse the repository at this point in the history
  • Loading branch information
harawata committed May 27, 2019
1 parent 3812082 commit 9e85477
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 72 deletions.
84 changes: 40 additions & 44 deletions src/main/java/org/apache/ibatis/type/ArrayTypeHandler.java
Expand Up @@ -25,7 +25,6 @@
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
Expand All @@ -42,67 +41,64 @@ public class ArrayTypeHandler extends BaseTypeHandler<Object> {
private static final ConcurrentHashMap<Class<?>, String> STANDARD_MAPPING;
static {
STANDARD_MAPPING = new ConcurrentHashMap<>();
STANDARD_MAPPING.put(BigDecimal.class, "NUMERIC");
STANDARD_MAPPING.put(BigInteger.class, "BIGINT");
STANDARD_MAPPING.put(boolean.class, "BOOLEAN");
STANDARD_MAPPING.put(Boolean.class, "BOOLEAN");
STANDARD_MAPPING.put(byte[].class, "VARBINARY");
STANDARD_MAPPING.put(byte.class, "TINYINT");
STANDARD_MAPPING.put(Byte.class, "TINYINT");
STANDARD_MAPPING.put(Calendar.class, "TIMESTAMP");
STANDARD_MAPPING.put(java.sql.Date.class, "DATE");
STANDARD_MAPPING.put(java.util.Date.class, "TIMESTAMP");
STANDARD_MAPPING.put(double.class, "DOUBLE");
STANDARD_MAPPING.put(Double.class, "DOUBLE");
STANDARD_MAPPING.put(float.class, "REAL");
STANDARD_MAPPING.put(Float.class, "REAL");
STANDARD_MAPPING.put(int.class, "INTEGER");
STANDARD_MAPPING.put(Integer.class, "INTEGER");
STANDARD_MAPPING.put(LocalDate.class, "DATE");
STANDARD_MAPPING.put(LocalDateTime.class, "TIMESTAMP");
STANDARD_MAPPING.put(LocalTime.class, "TIME");
STANDARD_MAPPING.put(long.class, "BIGINT");
STANDARD_MAPPING.put(Long.class, "BIGINT");
STANDARD_MAPPING.put(OffsetDateTime.class, "TIMESTAMP_WITH_TIMEZONE");
STANDARD_MAPPING.put(OffsetTime.class, "TIME_WITH_TIMEZONE");
STANDARD_MAPPING.put(Short.class, "SMALLINT");
STANDARD_MAPPING.put(String.class, "VARCHAR");
STANDARD_MAPPING.put(Time.class, "TIME");
STANDARD_MAPPING.put(Timestamp.class, "TIMESTAMP");
STANDARD_MAPPING.put(URL.class, "DATALINK");
};
STANDARD_MAPPING.put(BigDecimal.class, JdbcType.NUMERIC.name());
STANDARD_MAPPING.put(BigInteger.class, JdbcType.BIGINT.name());
STANDARD_MAPPING.put(boolean.class, JdbcType.BOOLEAN.name());
STANDARD_MAPPING.put(Boolean.class, JdbcType.BOOLEAN.name());
STANDARD_MAPPING.put(byte[].class, JdbcType.VARBINARY.name());
STANDARD_MAPPING.put(byte.class, JdbcType.TINYINT.name());
STANDARD_MAPPING.put(Byte.class, JdbcType.TINYINT.name());
STANDARD_MAPPING.put(Calendar.class, JdbcType.TIMESTAMP.name());
STANDARD_MAPPING.put(java.sql.Date.class, JdbcType.DATE.name());
STANDARD_MAPPING.put(java.util.Date.class, JdbcType.TIMESTAMP.name());
STANDARD_MAPPING.put(double.class, JdbcType.DOUBLE.name());
STANDARD_MAPPING.put(Double.class, JdbcType.DOUBLE.name());
STANDARD_MAPPING.put(float.class, JdbcType.REAL.name());
STANDARD_MAPPING.put(Float.class, JdbcType.REAL.name());
STANDARD_MAPPING.put(int.class, JdbcType.INTEGER.name());
STANDARD_MAPPING.put(Integer.class, JdbcType.INTEGER.name());
STANDARD_MAPPING.put(LocalDate.class, JdbcType.DATE.name());
STANDARD_MAPPING.put(LocalDateTime.class, JdbcType.TIMESTAMP.name());
STANDARD_MAPPING.put(LocalTime.class, JdbcType.TIME.name());
STANDARD_MAPPING.put(long.class, JdbcType.BIGINT.name());
STANDARD_MAPPING.put(Long.class, JdbcType.BIGINT.name());
STANDARD_MAPPING.put(OffsetDateTime.class, JdbcType.TIMESTAMP_WITH_TIMEZONE.name());
STANDARD_MAPPING.put(OffsetTime.class, JdbcType.TIME_WITH_TIMEZONE.name());
STANDARD_MAPPING.put(Short.class, JdbcType.SMALLINT.name());
STANDARD_MAPPING.put(String.class, JdbcType.VARCHAR.name());
STANDARD_MAPPING.put(Time.class, JdbcType.TIME.name());
STANDARD_MAPPING.put(Timestamp.class, JdbcType.TIMESTAMP.name());
STANDARD_MAPPING.put(URL.class, JdbcType.DATALINK.name());
}

public ArrayTypeHandler() {
super();
}

@Override
protected void setNullParameter(PreparedStatement ps, int i, JdbcType jdbcType) throws SQLException {
ps.setNull(i, Types.ARRAY);
}

@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
throws SQLException {
if (parameter instanceof Array) {
// it's the user's responsibility to properly free() the Array instance
ps.setArray(i, (Array)parameter);
}
else {
ps.setArray(i, (Array) parameter);
} else {
if (!parameter.getClass().isArray()) {
throw new TypeException("ArrayType Handler requires SQL array or java array parameter and does not support type " + parameter.getClass());
throw new TypeException(
"ArrayType Handler requires SQL array or java array parameter and does not support type "
+ parameter.getClass());
}
Class<?> componentType = parameter.getClass().getComponentType();
String arrayTypeName = resolveTypeName(componentType);
Array array = ps.getConnection().createArrayOf(arrayTypeName, (Object[])parameter);
Array array = ps.getConnection().createArrayOf(arrayTypeName, (Object[]) parameter);
ps.setArray(i, array);
array.free();
}
}

protected String resolveTypeName(Class<?> type) {
return STANDARD_MAPPING.getOrDefault(type, "JAVA_OBJECT");
return STANDARD_MAPPING.getOrDefault(type, JdbcType.JAVA_OBJECT.name());
}

@Override
public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
return extractArray(rs.getArray(columnName));
Expand Down
6 changes: 1 addition & 5 deletions src/main/java/org/apache/ibatis/type/BaseTypeHandler.java
Expand Up @@ -58,7 +58,7 @@ public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbc
throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
}
try {
setNullParameter(ps, i, jdbcType);
ps.setNull(i, jdbcType.TYPE_CODE);
} catch (SQLException e) {
throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . "
+ "Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. "
Expand All @@ -75,10 +75,6 @@ public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbc
}
}

protected void setNullParameter(PreparedStatement ps, int i, JdbcType jdbcType) throws SQLException {
ps.setNull(i, jdbcType.TYPE_CODE);
}

@Override
public T getResult(ResultSet rs, String columnName) throws SQLException {
try {
Expand Down
@@ -1,5 +1,5 @@
/**
* Copyright 2019 the original author or authors.
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -28,48 +28,49 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class BaseTest {
public class ArrayTypeHandlerTest {

private SqlSessionFactory sqlSessionFactory;

@BeforeEach
public void setUp() throws Exception {
try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/array_type_handler/mybatis-config.xml")) {
try (Reader reader = Resources
.getResourceAsReader("org/apache/ibatis/submitted/array_type_handler/mybatis-config.xml")) {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}

BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
"org/apache/ibatis/submitted/array_type_handler/CreateDB.sql");
}

@Test
public void shouldInsertArrayValue() throws Exception {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
User user = new User();
user.setId(1);
user.setName("User 1");
user.setNicknames(new String[] { "User", "one" });

Mapper mapper = sqlSession.getMapper(Mapper.class);
mapper.insert(user);
sqlSession.commit();

int usersInDatabase = mapper.getUserCount();
assertEquals(1, usersInDatabase);

Integer nicknameCount = mapper.getNicknameCount();
assertEquals(2, nicknameCount);
}
}

@Test
public void shouldInsertNullValue() throws Exception {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
User user = new User();
user.setId(1);
user.setName("User 1");
// note how the user does not have nicknames

Mapper mapper = sqlSession.getMapper(Mapper.class);
mapper.insert(user);
sqlSession.commit();
Expand Down
@@ -1,5 +1,5 @@
--
-- Copyright 2019 the original author or authors.
-- Copyright 2009-2019 the original author or authors.
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
Expand Down
@@ -1,5 +1,5 @@
/**
* Copyright 2019 the original author or authors.
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,9 +21,8 @@ public interface Mapper {

int getUserCount();

/**
* HSQL returns NULL when asked for the cardinality of an array column
* with NULL value :-(
/**
* HSQL returns NULL when asked for the cardinality of an array column with NULL value :-(
*/
Integer getNicknameCount();
}
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2019 the original author or authors.
Copyright 2009-2019 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -27,7 +27,7 @@
insert into users
(id, name, nicknames)
values
(#{id}, #{name}, #{nicknames,jdbcType=VARCHAR,typeHandler=org.apache.ibatis.type.ArrayTypeHandler})
(#{id}, #{name}, #{nicknames,typeHandler=org.apache.ibatis.type.ArrayTypeHandler})
</insert>

<select id="getUserCount" resultType="int">
Expand Down
@@ -1,5 +1,5 @@
/**
* Copyright 2019 the original author or authors.
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,26 +20,27 @@ public class User {
private Integer id;
private String name;
private String[] nicknames;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String[] getNicknames() {
return nicknames;
}

public void setNicknames(String[] nicknames) {
this.nicknames = nicknames;
}
Expand Down
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright 2019 the original author or authors.
Copyright 2009-2019 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down

0 comments on commit 9e85477

Please sign in to comment.