diff --git a/src/test/java/examples/array/ArrayTest.java b/src/test/java/examples/array/ArrayTest.java new file mode 100644 index 000000000..ab571d1b3 --- /dev/null +++ b/src/test/java/examples/array/ArrayTest.java @@ -0,0 +1,122 @@ +/* + * Copyright 2016-2020 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package examples.array; + +import static examples.array.NamesTableDynamicSqlSupport.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mybatis.dynamic.sql.SqlBuilder.*; + +import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; +import org.apache.ibatis.jdbc.ScriptRunner; +import org.apache.ibatis.mapping.Environment; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider; +import org.mybatis.dynamic.sql.render.RenderingStrategies; +import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.sql.Connection; +import java.sql.DriverManager; +import java.util.Optional; + +class ArrayTest { + private static final String JDBC_URL = "jdbc:hsqldb:mem:aname"; + private static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver"; + + private SqlSessionFactory sqlSessionFactory; + + @BeforeEach + void setup() throws Exception { + Class.forName(JDBC_DRIVER); + InputStream is = getClass().getResourceAsStream("/examples/array/CreateDB.sql"); + try (Connection connection = DriverManager.getConnection(JDBC_URL, "sa", "")) { + ScriptRunner sr = new ScriptRunner(connection); + sr.setLogWriter(null); + sr.runScript(new InputStreamReader(is)); + } + + UnpooledDataSource ds = new UnpooledDataSource(JDBC_DRIVER, JDBC_URL, "sa", ""); + Environment environment = new Environment("test", new JdbcTransactionFactory(), ds); + Configuration config = new Configuration(environment); + config.addMapper(NamesTableMapper.class); + sqlSessionFactory = new SqlSessionFactoryBuilder().build(config); + } + + @Test + void testInsertSelectById() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + NamesTableMapper mapper = sqlSession.getMapper(NamesTableMapper.class); + + String[] someNames = {"Fred", "Wilma", "Pebbles"}; + + GeneralInsertStatementProvider insertStatement = insertInto(namesTable) + .set(id).toValue(1) + .set(names).toValue(someNames) + .build() + .render(RenderingStrategies.MYBATIS3); + int rows = mapper.generalInsert(insertStatement); + assertThat(rows).isEqualTo(1); + + SelectStatementProvider selectStatement = select(id, NamesTableDynamicSqlSupport.names) + .from(namesTable) + .where(id, isEqualTo(1)) + .build() + .render(RenderingStrategies.MYBATIS3); + + Optional record = mapper.selectOne(selectStatement); + assertThat(record).hasValueSatisfying( r -> { + assertThat(r.getId()).isEqualTo(1); + assertThat(r.getNames()).isEqualTo(someNames); + }); + } + } + + @Test + void testInsertSelectByArray() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + NamesTableMapper mapper = sqlSession.getMapper(NamesTableMapper.class); + + String[] someNames = {"Fred", "Wilma", "Pebbles"}; + + GeneralInsertStatementProvider insertStatement = insertInto(namesTable) + .set(id).toValue(1) + .set(names).toValue(someNames) + .build() + .render(RenderingStrategies.MYBATIS3); + int rows = mapper.generalInsert(insertStatement); + assertThat(rows).isEqualTo(1); + + SelectStatementProvider selectStatement = select(id, NamesTableDynamicSqlSupport.names) + .from(namesTable) + .where(names, isEqualTo(someNames)) + .build() + .render(RenderingStrategies.MYBATIS3); + + Optional record = mapper.selectOne(selectStatement); + assertThat(record).hasValueSatisfying( r -> { + assertThat(r.getId()).isEqualTo(1); + assertThat(r.getNames()).isEqualTo(someNames); + }); + } + } +} diff --git a/src/test/java/examples/array/NamesRecord.java b/src/test/java/examples/array/NamesRecord.java new file mode 100644 index 000000000..acb5dee7b --- /dev/null +++ b/src/test/java/examples/array/NamesRecord.java @@ -0,0 +1,37 @@ +/* + * Copyright 2016-2020 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package examples.array; + +public class NamesRecord { + private Integer id; + private String[] names; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String[] getNames() { + return names; + } + + public void setNames(String[] names) { + this.names = names; + } +} diff --git a/src/test/java/examples/array/NamesTableDynamicSqlSupport.java b/src/test/java/examples/array/NamesTableDynamicSqlSupport.java new file mode 100644 index 000000000..04deabd17 --- /dev/null +++ b/src/test/java/examples/array/NamesTableDynamicSqlSupport.java @@ -0,0 +1,35 @@ +/* + * Copyright 2016-2020 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package examples.array; + +import org.mybatis.dynamic.sql.SqlColumn; +import org.mybatis.dynamic.sql.SqlTable; + +import java.sql.JDBCType; + +public class NamesTableDynamicSqlSupport { + public static final NamesTable namesTable = new NamesTable(); + public static final SqlColumn id = namesTable.id; + public static final SqlColumn names = namesTable.names; + + public static final class NamesTable extends SqlTable { + public NamesTable() { + super("NamesTable"); + } + public final SqlColumn id = column("id", JDBCType.INTEGER); + public final SqlColumn names = column("names", JDBCType.ARRAY); + } +} diff --git a/src/test/java/examples/array/NamesTableMapper.java b/src/test/java/examples/array/NamesTableMapper.java new file mode 100644 index 000000000..abf043366 --- /dev/null +++ b/src/test/java/examples/array/NamesTableMapper.java @@ -0,0 +1,44 @@ +/* + * Copyright 2016-2020 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package examples.array; + +import org.apache.ibatis.annotations.InsertProvider; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.ResultMap; +import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.SelectProvider; +import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider; +import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.util.SqlProviderAdapter; + +import java.util.List; +import java.util.Optional; + +public interface NamesTableMapper { + @SelectProvider(type=SqlProviderAdapter.class, method="select") + @Results(id="NamesTableResult", value={ + @Result(column="id", property="id", id=true), + @Result(column="names", property="names", typeHandler = StringArrayTypeHandler.class) + }) + List selectMany(SelectStatementProvider selectStatement); + + @SelectProvider(type=SqlProviderAdapter.class, method="select") + @ResultMap("NamesTableResult") + Optional selectOne(SelectStatementProvider selectStatement); + + @InsertProvider(type= SqlProviderAdapter.class, method="generalInsert") + int generalInsert(GeneralInsertStatementProvider insertStatement); +} diff --git a/src/test/java/examples/array/StringArrayTypeHandler.java b/src/test/java/examples/array/StringArrayTypeHandler.java new file mode 100644 index 000000000..db9a8e6b1 --- /dev/null +++ b/src/test/java/examples/array/StringArrayTypeHandler.java @@ -0,0 +1,67 @@ +/* + * Copyright 2016-2020 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package examples.array; + +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; + +import java.sql.Array; +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class StringArrayTypeHandler extends BaseTypeHandler { + @Override + public void setNonNullParameter(PreparedStatement ps, int i, String[] parameter, JdbcType jdbcType) throws SQLException { + Array array = ps.getConnection().createArrayOf("CHAR", parameter); + ps.setArray(i, array); + array.free(); + } + + @Override + public String[] getNullableResult(ResultSet rs, String columnName) throws SQLException { + Array array = rs.getArray(columnName); + return extractArray(array); + } + + @Override + public String[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + Array array = rs.getArray(columnIndex); + return extractArray(array); + } + + @Override + public String[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + Array array = cs.getArray(columnIndex); + return extractArray(array); + } + + private String[] extractArray(Array array) throws SQLException { + Object[] objArray = (Object[]) array.getArray(); + array.free(); + + List stringList = Arrays.stream(objArray) + .map(Object::toString) + .collect(Collectors.toList()); + + String[] stringArray = new String[stringList.size()]; + return stringList.toArray(stringArray); + } +} diff --git a/src/test/resources/examples/array/CreateDB.sql b/src/test/resources/examples/array/CreateDB.sql new file mode 100644 index 000000000..333865112 --- /dev/null +++ b/src/test/resources/examples/array/CreateDB.sql @@ -0,0 +1,23 @@ +-- +-- Copyright 2016-2020 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. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +drop table NamesTable if exists; + +create table NamesTable ( + id int not null, + names varchar(32) array, + primary key(id) +);