View Javadoc
1   /*
2    *    Copyright 2016-2025 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.mybatis.dynamic.sql.insert;
17  
18  import static org.assertj.core.api.Assertions.assertThat;
19  import static org.mybatis.dynamic.sql.SqlBuilder.insert;
20  
21  import java.sql.JDBCType;
22  
23  import org.jspecify.annotations.Nullable;
24  import org.junit.jupiter.api.Test;
25  import org.mybatis.dynamic.sql.SqlColumn;
26  import org.mybatis.dynamic.sql.SqlTable;
27  import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider;
28  import org.mybatis.dynamic.sql.render.RenderingStrategies;
29  
30  class InsertStatementTest {
31  
32      private static final SqlTable foo = SqlTable.of("foo");
33      private static final SqlColumn<Integer> id = foo.column("id", JDBCType.INTEGER);
34      private static final SqlColumn<String> firstName = foo.column("first_name", JDBCType.VARCHAR);
35      private static final SqlColumn<String> lastName = foo.column("last_name", JDBCType.VARCHAR);
36      private static final SqlColumn<String> occupation = foo.column("occupation", JDBCType.VARCHAR);
37  
38      @Test
39      void testFullInsertStatementBuilder() {
40  
41          TestRecord row = new TestRecord(null, null, "jones", "dino driver");
42  
43          InsertStatementProvider<TestRecord> insertStatement = insert(row)
44                  .into(foo)
45                  .map(id).toProperty("id")
46                  .map(firstName).toProperty("firstName")
47                  .map(lastName).toProperty("lastName")
48                  .map(occupation).toProperty("occupation")
49                  .build()
50                  .render(RenderingStrategies.MYBATIS3);
51  
52          String expectedStatement = "insert into foo "
53                  + "(id, first_name, last_name, occupation) "
54                  + "values (#{row.id,jdbcType=INTEGER}, #{row.firstName,jdbcType=VARCHAR}, #{row.lastName,jdbcType=VARCHAR}, #{row.occupation,jdbcType=VARCHAR})";
55  
56          assertThat(insertStatement.getInsertStatement()).isEqualTo(expectedStatement);
57      }
58  
59      @Test
60      void testInsertStatementBuilderWithNulls() {
61  
62          TestRecord row = new TestRecord();
63  
64          InsertStatementProvider<TestRecord> insertStatement = insert(row)
65                  .into(foo)
66                  .map(id).toProperty("id")
67                  .map(firstName).toProperty("firstName")
68                  .map(lastName).toProperty("lastName")
69                  .map(occupation).toNull()
70                  .build()
71                  .render(RenderingStrategies.MYBATIS3);
72  
73          String expected = "insert into foo (id, first_name, last_name, occupation) "
74                  + "values (#{row.id,jdbcType=INTEGER}, #{row.firstName,jdbcType=VARCHAR}, #{row.lastName,jdbcType=VARCHAR}, null)";
75          assertThat(insertStatement.getInsertStatement()).isEqualTo(expected);
76      }
77  
78      @Test
79      void testInsertStatementBuilderWithConstants() {
80  
81          TestRecord row = new TestRecord();
82  
83          InsertStatementProvider<TestRecord> insertStatement = insert(row)
84                  .into(foo)
85                  .map(id).toConstant("3")
86                  .map(firstName).toProperty("firstName")
87                  .map(lastName).toProperty("lastName")
88                  .map(occupation).toStringConstant("Y")
89                  .build()
90                  .render(RenderingStrategies.MYBATIS3);
91  
92          String expected = "insert into foo (id, first_name, last_name, occupation) "
93                  + "values (3, #{row.firstName,jdbcType=VARCHAR}, #{row.lastName,jdbcType=VARCHAR}, 'Y')";
94          assertThat(insertStatement.getInsertStatement()).isEqualTo(expected);
95      }
96  
97      @Test
98      void testSelectiveInsertStatementBuilder() {
99          TestRecord row = new TestRecord(null, null, "jones", "dino driver");
100 
101         InsertStatementProvider<TestRecord> insertStatement = insert(row)
102                 .into(foo)
103                 .map(id).toPropertyWhenPresent("id", row::id)
104                 .map(firstName).toPropertyWhenPresent("firstName", row::firstName)
105                 .map(lastName).toPropertyWhenPresent("lastName", row::lastName)
106                 .map(occupation).toPropertyWhenPresent("occupation", row::occupation)
107                 .build()
108                 .render(RenderingStrategies.MYBATIS3);
109 
110         String expected = "insert into foo (last_name, occupation) "
111                 + "values (#{row.lastName,jdbcType=VARCHAR}, #{row.occupation,jdbcType=VARCHAR})";
112         assertThat(insertStatement.getInsertStatement()).isEqualTo(expected);
113     }
114 
115     record TestRecord (@Nullable Integer id, @Nullable String firstName, @Nullable String lastName, @Nullable String occupation) {
116         TestRecord() {
117             this(null, null, null, null);
118         }
119     }
120 }