Skip to content

Commit 5ad9926

Browse files
committed
Initial support for javaType on SqlColumn
1 parent 5b71a8b commit 5ad9926

File tree

9 files changed

+102
-18
lines changed

9 files changed

+102
-18
lines changed

src/main/java/org/mybatis/dynamic/sql/BindableColumn.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,8 @@ default Optional<RenderingStrategy> renderingStrategy() {
5151
default Object convertParameterType(T value) {
5252
return value;
5353
}
54+
55+
default Optional<Class<T>> javaType() {
56+
return Optional.empty();
57+
}
5458
}

src/main/java/org/mybatis/dynamic/sql/SqlColumn.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class SqlColumn<T> implements BindableColumn<T>, SortSpecification {
3636
protected final RenderingStrategy renderingStrategy;
3737
protected final ParameterTypeConverter<T, ?> parameterTypeConverter;
3838
protected final BiFunction<TableAliasCalculator, SqlTable, Optional<String>> tableQualifierFunction;
39+
protected final Class<T> javaType;
3940

4041
private SqlColumn(Builder<T> builder) {
4142
name = Objects.requireNonNull(builder.name);
@@ -47,6 +48,7 @@ private SqlColumn(Builder<T> builder) {
4748
renderingStrategy = builder.renderingStrategy;
4849
parameterTypeConverter = builder.parameterTypeConverter;
4950
tableQualifierFunction = Objects.requireNonNull(builder.tableQualifierFunction);
51+
javaType = builder.javaType;
5052
}
5153

5254
public String name() {
@@ -72,6 +74,11 @@ public Optional<String> typeHandler() {
7274
return Optional.ofNullable(typeHandler);
7375
}
7476

77+
@Override
78+
public Optional<Class<T>> javaType() {
79+
return Optional.ofNullable(javaType);
80+
}
81+
7582
@Override
7683
public Object convertParameterType(T value) {
7784
return parameterTypeConverter == null ? value : parameterTypeConverter.convert(value);
@@ -158,6 +165,12 @@ public <S> SqlColumn<S> withParameterTypeConverter(ParameterTypeConverter<S, ?>
158165
return b.withParameterTypeConverter(parameterTypeConverter).build();
159166
}
160167

168+
@NotNull
169+
public <S> SqlColumn<S> withJavaType(Class<S> javaType) {
170+
Builder<S> b = copy();
171+
return b.withJavaType(javaType).build();
172+
}
173+
161174
/**
162175
* This method helps us tell a bit of fiction to the Java compiler. Java, for better or worse,
163176
* does not carry generic type information through chained methods. We want to enable method
@@ -178,7 +191,8 @@ private <S> Builder<S> copy() {
178191
.withTypeHandler(this.typeHandler)
179192
.withRenderingStrategy(this.renderingStrategy)
180193
.withParameterTypeConverter((ParameterTypeConverter<S, ?>) this.parameterTypeConverter)
181-
.withTableQualifierFunction(this.tableQualifierFunction);
194+
.withTableQualifierFunction(this.tableQualifierFunction)
195+
.withJavaType((Class<S>) this.javaType);
182196
}
183197

184198
private String applyTableAlias(String tableAlias) {
@@ -209,6 +223,7 @@ public static class Builder<T> {
209223
protected ParameterTypeConverter<T, ?> parameterTypeConverter;
210224
protected BiFunction<TableAliasCalculator, SqlTable, Optional<String>> tableQualifierFunction =
211225
TableAliasCalculator::aliasForColumn;
226+
protected Class<T> javaType;
212227

213228
public Builder<T> withName(String name) {
214229
this.name = name;
@@ -256,6 +271,11 @@ private Builder<T> withTableQualifierFunction(
256271
return this;
257272
}
258273

274+
public Builder<T> withJavaType(Class<T> javaType) {
275+
this.javaType = javaType;
276+
return this;
277+
}
278+
259279
public SqlColumn<T> build() {
260280
return new SqlColumn<>(this);
261281
}

src/main/java/org/mybatis/dynamic/sql/render/MyBatis3RenderingStrategy.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public String getFormattedJdbcPlaceholder(BindableColumn<?> column, String prefi
3434
+ "." //$NON-NLS-1$
3535
+ parameterName
3636
+ renderJdbcType(column)
37+
+ renderJavaType(column)
3738
+ renderTypeHandler(column)
3839
+ "}"; //$NON-NLS-1$
3940
}
@@ -49,4 +50,10 @@ private String renderJdbcType(BindableColumn<?> column) {
4950
.map(jt -> ",jdbcType=" + jt.getName()) //$NON-NLS-1$
5051
.orElse(""); //$NON-NLS-1$
5152
}
53+
54+
private String renderJavaType(BindableColumn<?> column) {
55+
return column.javaType()
56+
.map(jt -> ",javaType=" + jt.getName()) //$NON-NLS-1$
57+
.orElse(""); //$NON-NLS-1$
58+
}
5259
}

src/test/java/examples/simple/AddressDynamicSqlSupport.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,16 @@ public final class AddressDynamicSqlSupport {
2626
public static final SqlColumn<String> streetAddress = address.streetAddress;
2727
public static final SqlColumn<String> city = address.city;
2828
public static final SqlColumn<String> state = address.state;
29+
public static final SqlColumn<AddressRecord.AddressType> addressType = address.addressType;
2930

3031
public static final class Address extends SqlTable {
3132
public final SqlColumn<Integer> id = column("address_id", JDBCType.INTEGER);
3233
public final SqlColumn<String> streetAddress = column("street_address", JDBCType.VARCHAR);
3334
public final SqlColumn<String> city = column("city", JDBCType.VARCHAR);
3435
public final SqlColumn<String> state = column("state", JDBCType.VARCHAR);
36+
public final SqlColumn<AddressRecord.AddressType> addressType = column("address_type", JDBCType.INTEGER)
37+
.withTypeHandler("org.apache.ibatis.type.EnumOrdinalTypeHandler")
38+
.withJavaType(AddressRecord.AddressType.class);
3539

3640
public Address() {
3741
super("Address");
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package examples.simple;
2+
3+
import org.mybatis.dynamic.sql.util.mybatis3.CommonInsertMapper;
4+
import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper;
5+
6+
public interface AddressMapper extends CommonInsertMapper<AddressRecord>, CommonSelectMapper {
7+
}

src/test/java/examples/simple/AddressRecord.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class AddressRecord {
2020
private String streetAddress;
2121
private String city;
2222
private String state;
23+
private AddressType addressType;
2324

2425
public Integer getId() {
2526
return id;
@@ -52,4 +53,17 @@ public String getState() {
5253
public void setState(String state) {
5354
this.state = state;
5455
}
56+
57+
public AddressType getAddressType() {
58+
return addressType;
59+
}
60+
61+
public void setAddressType(AddressType addressType) {
62+
this.addressType = addressType;
63+
}
64+
65+
public enum AddressType {
66+
HOME,
67+
BUSINESS
68+
}
5569
}

src/test/java/examples/simple/PersonMapperTest.java

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.junit.jupiter.api.Test;
2828
import org.mybatis.dynamic.sql.delete.DeleteDSLCompleter;
2929
import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider;
30+
import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider;
3031
import org.mybatis.dynamic.sql.render.RenderingStrategies;
3132
import org.mybatis.dynamic.sql.select.CountDSLCompleter;
3233
import org.mybatis.dynamic.sql.select.SelectDSLCompleter;
@@ -42,6 +43,7 @@
4243
import java.util.Objects;
4344
import java.util.Optional;
4445

46+
import static examples.simple.AddressDynamicSqlSupport.address;
4547
import static examples.simple.PersonDynamicSqlSupport.addressId;
4648
import static examples.simple.PersonDynamicSqlSupport.birthDate;
4749
import static examples.simple.PersonDynamicSqlSupport.employed;
@@ -52,17 +54,7 @@
5254
import static examples.simple.PersonDynamicSqlSupport.person;
5355
import static org.assertj.core.api.Assertions.assertThat;
5456
import static org.junit.jupiter.api.Assertions.assertAll;
55-
import static org.mybatis.dynamic.sql.SqlBuilder.deleteFrom;
56-
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
57-
import static org.mybatis.dynamic.sql.SqlBuilder.isFalse;
58-
import static org.mybatis.dynamic.sql.SqlBuilder.isGreaterThan;
59-
import static org.mybatis.dynamic.sql.SqlBuilder.isIn;
60-
import static org.mybatis.dynamic.sql.SqlBuilder.isLike;
61-
import static org.mybatis.dynamic.sql.SqlBuilder.isNotLike;
62-
import static org.mybatis.dynamic.sql.SqlBuilder.isNull;
63-
import static org.mybatis.dynamic.sql.SqlBuilder.isTrue;
64-
import static org.mybatis.dynamic.sql.SqlBuilder.or;
65-
import static org.mybatis.dynamic.sql.SqlBuilder.select;
57+
import static org.mybatis.dynamic.sql.SqlBuilder.*;
6658

6759
class PersonMapperTest {
6860

@@ -86,6 +78,7 @@ void setup() throws Exception {
8678
Configuration config = new Configuration(environment);
8779
config.addMapper(PersonMapper.class);
8880
config.addMapper(PersonWithAddressMapper.class);
81+
config.addMapper(AddressMapper.class);
8982
sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
9083
}
9184

@@ -650,6 +643,9 @@ void testJoinAllRows() {
650643
assertThat(records.get(0).getAddress().getStreetAddress()).isEqualTo("123 Main Street");
651644
assertThat(records.get(0).getAddress().getCity()).isEqualTo("Bedrock");
652645
assertThat(records.get(0).getAddress().getState()).isEqualTo("IN");
646+
assertThat(records.get(0).getAddress().getAddressType()).isEqualTo(AddressRecord.AddressType.HOME);
647+
648+
assertThat(records.get(4).getAddress().getAddressType()).isEqualTo(AddressRecord.AddressType.BUSINESS);
653649
}
654650
}
655651

@@ -723,4 +719,32 @@ void testJoinCountWithSubcriteria() {
723719
assertThat(count).isEqualTo(1);
724720
}
725721
}
722+
723+
@Test
724+
void testWithEnumOrdinalTypeHandler() {
725+
try (SqlSession session = sqlSessionFactory.openSession()) {
726+
AddressMapper mapper = session.getMapper(AddressMapper.class);
727+
728+
GeneralInsertStatementProvider insertStatement = insertInto(address)
729+
.set(address.id).toValue(4)
730+
.set(address.streetAddress).toValue("987 Elm Street")
731+
.set(address.city).toValue("Mayberry")
732+
.set(address.state).toValue("NC")
733+
.set(address.addressType).toValue(AddressRecord.AddressType.HOME)
734+
.build()
735+
.render(RenderingStrategies.MYBATIS3);
736+
737+
int rows = mapper.generalInsert(insertStatement);
738+
assertThat(rows).isEqualTo(1);
739+
740+
SelectStatementProvider selectStatement = select(address.addressType)
741+
.from(address)
742+
.where(address.id, isEqualTo(4))
743+
.build()
744+
.render(RenderingStrategies.MYBATIS3);
745+
746+
Optional<Integer> type = mapper.selectOptionalInteger(selectStatement);
747+
assertThat(type).hasValueSatisfying(i -> assertThat(i).isEqualTo(0));
748+
}
749+
}
726750
}

src/test/java/examples/simple/PersonWithAddressMapper.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.apache.ibatis.annotations.ResultMap;
3434
import org.apache.ibatis.annotations.Results;
3535
import org.apache.ibatis.annotations.SelectProvider;
36+
import org.apache.ibatis.type.EnumOrdinalTypeHandler;
3637
import org.apache.ibatis.type.JdbcType;
3738
import org.mybatis.dynamic.sql.BasicColumn;
3839
import org.mybatis.dynamic.sql.SqlBuilder;
@@ -64,7 +65,9 @@ public interface PersonWithAddressMapper {
6465
@Result(column="address_id", property="address.id", jdbcType=JdbcType.INTEGER),
6566
@Result(column="street_address", property="address.streetAddress", jdbcType=JdbcType.VARCHAR),
6667
@Result(column="city", property="address.city", jdbcType=JdbcType.VARCHAR),
67-
@Result(column="state", property="address.state", jdbcType=JdbcType.CHAR)
68+
@Result(column="state", property="address.state", jdbcType=JdbcType.CHAR),
69+
@Result(column="address_type", property="address.addressType", jdbcType=JdbcType.INTEGER,
70+
typeHandler = EnumOrdinalTypeHandler.class)
6871
})
6972
List<PersonWithAddress> selectMany(SelectStatementProvider selectStatement);
7073

@@ -77,7 +80,7 @@ public interface PersonWithAddressMapper {
7780

7881
BasicColumn[] selectList =
7982
BasicColumn.columnList(id.as("A_ID"), firstName, lastName, birthDate, employed, occupation, address.id,
80-
address.streetAddress, address.city, address.state);
83+
address.streetAddress, address.city, address.state, address.addressType);
8184

8285
default Optional<PersonWithAddress> selectOne(SelectDSLCompleter completer) {
8386
QueryExpressionDSL<SelectModel> start = SqlBuilder.select(selectList).from(person)

src/test/resources/examples/simple/CreateSimpleDB.sql

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ create table Address (
2222
street_address varchar(50) not null,
2323
city varchar(20) not null,
2424
state varchar(2) not null,
25+
address_type int not null,
2526
primary key(address_id)
2627
);
2728

@@ -36,11 +37,11 @@ create table Person (
3637
primary key(id)
3738
);
3839

39-
insert into Address (address_id, street_address, city, state)
40-
values(1, '123 Main Street', 'Bedrock', 'IN');
40+
insert into Address (address_id, street_address, city, state, address_type)
41+
values(1, '123 Main Street', 'Bedrock', 'IN', 0);
4142

42-
insert into Address (address_id, street_address, city, state)
43-
values(2, '456 Main Street', 'Bedrock', 'IN');
43+
insert into Address (address_id, street_address, city, state, address_type)
44+
values(2, '456 Main Street', 'Bedrock', 'IN', 1);
4445

4546
insert into Person values(1, 'Fred', 'Flintstone', '1935-02-01', 'Yes', 'Brontosaurus Operator', 1);
4647

0 commit comments

Comments
 (0)