├── .mvn
├── jvm.config
├── maven.config
├── wrapper
│ ├── maven-wrapper.properties
│ └── MavenWrapperDownloader.java
├── extensions.xml
└── settings.xml
├── .gitattributes
├── renovate.json
├── NOTICE
├── .gitignore
├── LICENSE_HEADER
├── src
├── test
│ ├── resources
│ │ ├── mybatis-freemarker-empty.properties
│ │ ├── mybatis-freemarker.properties
│ │ ├── sql
│ │ │ ├── getAllNames.ftl
│ │ │ ├── TemplateFilePathProviderMapper-delete.ftl
│ │ │ ├── TemplateFilePathProviderMapper-findById.ftl
│ │ │ ├── findUsingCustomizedContext.ftl
│ │ │ ├── TemplateFilePathProviderMapper-insert.ftl
│ │ │ ├── findName.ftl
│ │ │ ├── preparedIn.ftl
│ │ │ ├── preparedDatabaseIdTest.ftl
│ │ │ ├── TemplateFilePathProviderMapper-update.ftl
│ │ │ └── prepared.ftl
│ │ ├── org
│ │ │ └── mybatis
│ │ │ │ └── scripting
│ │ │ │ └── freemarker
│ │ │ │ ├── support
│ │ │ │ ├── BaseMapper_selectOne.ftl
│ │ │ │ ├── TestMapper
│ │ │ │ │ ├── selectAllAsc.ftl
│ │ │ │ │ ├── TestMapper-delete.ftl
│ │ │ │ │ ├── TestMapper-update.ftl
│ │ │ │ │ └── TestMapper-update-h2.ftl
│ │ │ │ ├── BaseMapper
│ │ │ │ │ ├── BaseMapper-count.ftl
│ │ │ │ │ ├── BaseMapper-insert.ftl
│ │ │ │ │ └── BaseMapper-insert-h2.ftl
│ │ │ │ ├── sql
│ │ │ │ │ └── TestMapper-selectAllDesc.ftl
│ │ │ │ └── DefaultPackageNameMapper
│ │ │ │ │ └── DefaultPackageNameMapper-selectAllDesc.ftl
│ │ │ │ ├── create-db.sql
│ │ │ │ ├── mapper-config.xml
│ │ │ │ └── mapper.xml
│ │ └── mybatis-freemarker-custom.properties
│ └── java
│ │ ├── DefaultPackageNameMapper.java
│ │ └── org
│ │ └── mybatis
│ │ └── scripting
│ │ └── freemarker
│ │ ├── support
│ │ ├── BaseMapper.java
│ │ ├── TestMapper.java
│ │ └── TemplateFilePathProviderTest.java
│ │ ├── NameParam.java
│ │ ├── CustomizedDataContextMapper.java
│ │ ├── PreparedDatabaseIdParamsMapper.java
│ │ ├── InvalidFreeMarkerSettingTest.java
│ │ ├── Name.java
│ │ ├── TemplateFilePathProviderMapper.java
│ │ ├── PreparedParam.java
│ │ ├── PreparedParamsMapper.java
│ │ ├── NameMapper.java
│ │ ├── PreparedParamsTest.java
│ │ ├── PreparedDatabaseIdParamsTest.java
│ │ ├── CustomizedDataContextTest.java
│ │ ├── FreeMarkerInXmlTest.java
│ │ ├── FreeMarkerInAnnotationsTest.java
│ │ ├── TemplateFilePathProviderMapperTest.java
│ │ └── FreeMarkerLanguageDriverConfigTest.java
├── site
│ ├── site.xml
│ └── xdoc
│ │ └── index.xml.vm
└── main
│ └── java
│ └── org
│ └── mybatis
│ └── scripting
│ └── freemarker
│ ├── GeneratedParamsTemplateModel.java
│ ├── ParamObjectAdapter.java
│ ├── MyBatisParamDirective.java
│ ├── FreeMarkerSqlSource.java
│ ├── FreeMarkerLanguageDriver.java
│ ├── support
│ └── TemplateFilePathProvider.java
│ └── FreeMarkerLanguageDriverConfig.java
├── format.xml
├── .github
└── workflows
│ ├── sonatype.yaml
│ ├── ci.yaml
│ ├── site.yaml
│ ├── codeql.yaml
│ ├── sonar.yaml
│ └── coveralls.yaml
├── README.md
├── pom.xml
├── mvnw.cmd
├── LICENSE
└── mvnw
/.mvn/jvm.config:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set default behaviour, in case users don't have core.autocrlf set.
2 | * text=auto
--------------------------------------------------------------------------------
/.mvn/maven.config:
--------------------------------------------------------------------------------
1 | -Daether.checksums.algorithms=SHA-512,SHA-256,SHA-1,MD5
2 | -Daether.connector.smartChecksums=false
3 | --no-transfer-progress
4 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:recommended"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | MyBatis Freemarker
2 | Copyright 2015-2024
3 |
4 | This product includes software developed by
5 | The MyBatis Team (http://www.mybatis.org/).
6 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionType=source
2 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip
3 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.4/maven-wrapper-3.3.4.jar
4 | wrapperVersion=3.3.4
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /*.iml
2 | /*.ipr
3 | /*.iws
4 | /.classpath
5 | /.idea
6 | /.project
7 | /.settings
8 | /ibderby
9 | /nb*
10 | /release.properties
11 | /target
12 | /test.db.lck
13 | /test.db.log
14 | /test.db.properties
15 | /test.db.script
16 | /test.db.tmp
17 | /src/docbkx
18 | velocity.log
19 | /bin
20 | .mvn/wrapper/maven-wrapper.jar
21 | pom.xml.releaseBackup
22 |
--------------------------------------------------------------------------------
/LICENSE_HEADER:
--------------------------------------------------------------------------------
1 | Copyright ${license.git.copyrightYears} the original author or authors.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | https://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/src/test/resources/mybatis-freemarker-empty.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2015-2022 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 |
17 | #
18 |
--------------------------------------------------------------------------------
/src/test/resources/mybatis-freemarker.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2015-2022 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 |
17 | basePackage=sql
18 |
--------------------------------------------------------------------------------
/src/test/resources/sql/getAllNames.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 | SELECT *
19 | FROM names
--------------------------------------------------------------------------------
/src/test/resources/org/mybatis/scripting/freemarker/support/BaseMapper_selectOne.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 |
--------------------------------------------------------------------------------
/src/test/resources/org/mybatis/scripting/freemarker/support/TestMapper/selectAllAsc.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 |
--------------------------------------------------------------------------------
/src/test/resources/org/mybatis/scripting/freemarker/support/BaseMapper/BaseMapper-count.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 |
--------------------------------------------------------------------------------
/src/test/resources/org/mybatis/scripting/freemarker/support/BaseMapper/BaseMapper-insert.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 |
--------------------------------------------------------------------------------
/src/test/resources/org/mybatis/scripting/freemarker/support/TestMapper/TestMapper-delete.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 |
--------------------------------------------------------------------------------
/src/test/resources/org/mybatis/scripting/freemarker/support/TestMapper/TestMapper-update.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 |
--------------------------------------------------------------------------------
/src/test/resources/org/mybatis/scripting/freemarker/support/sql/TestMapper-selectAllDesc.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 |
--------------------------------------------------------------------------------
/src/test/resources/org/mybatis/scripting/freemarker/support/BaseMapper/BaseMapper-insert-h2.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 |
--------------------------------------------------------------------------------
/src/test/resources/org/mybatis/scripting/freemarker/support/TestMapper/TestMapper-update-h2.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 |
--------------------------------------------------------------------------------
/src/test/resources/org/mybatis/scripting/freemarker/support/DefaultPackageNameMapper/DefaultPackageNameMapper-selectAllDesc.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 |
--------------------------------------------------------------------------------
/src/test/resources/sql/TemplateFilePathProviderMapper-delete.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 | DELETE FROM names
19 | WHERE id = <@p name="id"/>
20 |
21 |
--------------------------------------------------------------------------------
/src/test/resources/sql/TemplateFilePathProviderMapper-findById.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 | SELECT * FROM names
19 | WHERE id = <@p name="id"/>
20 |
--------------------------------------------------------------------------------
/format.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/test/resources/sql/findUsingCustomizedContext.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 | <#-- MY_NAME constant is pre-defined -->
19 | SELECT *
20 | FROM names
21 | where firstName = '${MY_NAME}'
--------------------------------------------------------------------------------
/src/test/resources/sql/TemplateFilePathProviderMapper-insert.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 | INSERT INTO names (firstName, lastName)
19 | VALUES (<@p name="firstName"/>, <@p name="lastName"/>)
--------------------------------------------------------------------------------
/src/test/resources/sql/findName.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 | <#-- @ftlvariable name="p" type="org.mybatis.scripting.freemarker.MyBatisParamDirective" -->
19 | SELECT *
20 | FROM names
21 | where firstName = <@p name="name"/>
--------------------------------------------------------------------------------
/src/test/resources/sql/preparedIn.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 | select * from names where firstName in (
19 | <#list ids as id>
20 | <@p value=id/>
21 | <#if id_has_next>,#if>
22 | #list>
23 | )
--------------------------------------------------------------------------------
/src/test/resources/sql/preparedDatabaseIdTest.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2023 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 | select
19 | *
20 | from
21 | names
22 | where
23 | <#if '${_databaseId}' == 'hsqldb'>firstName = 'Fred' and lastName = 'Flintstone'#if>
24 |
--------------------------------------------------------------------------------
/src/test/java/DefaultPackageNameMapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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 | import java.util.List;
17 |
18 | import org.mybatis.scripting.freemarker.Name;
19 |
20 | public interface DefaultPackageNameMapper {
21 | List selectAllDesc();
22 | }
23 |
--------------------------------------------------------------------------------
/.mvn/extensions.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 | fr.jcgay.maven
22 | maven-profiler
23 | 3.3
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/support/BaseMapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker.support;
17 |
18 | public interface BaseMapper {
19 | void insert(T model);
20 |
21 | void update(T model);
22 |
23 | long count();
24 |
25 | T selectOne(int id);
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/resources/sql/TemplateFilePathProviderMapper-update.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 | UPDATE names
19 | SET id = id
20 | <#if firstName?has_content>
21 | ,firstName = <@p name="firstName"/>
22 | #if>
23 | <#if lastName?has_content>
24 | ,lastName = <@p name="lastName"/>
25 | #if>
26 | WHERE id = <@p name="id"/>
27 |
--------------------------------------------------------------------------------
/.github/workflows/sonatype.yaml:
--------------------------------------------------------------------------------
1 | name: Sonatype
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | permissions: read-all
9 |
10 | concurrency:
11 | group: ${{ github.workflow }}-${{ github.ref }}
12 | cancel-in-progress: true
13 |
14 | jobs:
15 | build:
16 | if: github.repository_owner == 'mybatis' && ! contains(toJSON(github.event.head_commit.message), '[maven-release-plugin]')
17 | runs-on: ubuntu-latest
18 | timeout-minutes: 30
19 | steps:
20 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
21 | - name: Setup Java
22 | uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
23 | with:
24 | cache: maven
25 | distribution: temurin
26 | java-version: 25
27 | - name: Deploy to Sonatype
28 | run: ./mvnw deploy --batch-mode --no-transfer-progress --settings ./.mvn/settings.xml --show-version -Dlicense.skip=true -DskipTests
29 | env:
30 | CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }}
31 | CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }}
32 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/support/TestMapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker.support;
17 |
18 | import java.util.List;
19 |
20 | import org.mybatis.scripting.freemarker.Name;
21 |
22 | interface TestMapper extends BaseMapper {
23 | void delete(int id);
24 |
25 | List selectAllDesc();
26 |
27 | List selectAllAsc();
28 |
29 | List selectAllByFirstName(String firstName);
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/NameParam.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker;
17 |
18 | /**
19 | * Class to test queries using parameter objects.
20 | *
21 | * @author elwood
22 | */
23 | public class NameParam {
24 | private int id;
25 |
26 | public NameParam(int id) {
27 | this.id = id;
28 | }
29 |
30 | public int getId() {
31 | return id;
32 | }
33 |
34 | public void setId(int id) {
35 | this.id = id;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | name: Java CI
2 |
3 | on: [workflow_dispatch, push, pull_request]
4 |
5 | permissions: read-all
6 |
7 | concurrency:
8 | group: ${{ github.workflow }}-${{ github.ref }}
9 | cancel-in-progress: true
10 |
11 | jobs:
12 | test:
13 | runs-on: ${{ matrix.os }}
14 | timeout-minutes: 30
15 | strategy:
16 | matrix:
17 | cache: [maven]
18 | distribution: [temurin]
19 | java: [21, 25, 26-ea]
20 | os: [macos-latest, ubuntu-latest, windows-latest]
21 | fail-fast: false
22 | max-parallel: 6
23 | name: Test JDK ${{ matrix.java }}, ${{ matrix.os }}
24 |
25 | steps:
26 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
27 | - name: Setup Java ${{ matrix.java }} ${{ matrix.distribution }}
28 | uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
29 | with:
30 | cache: ${{ matrix.cache }}
31 | distribution: ${{ matrix.distribution }}
32 | java-version: ${{ matrix.java }}
33 | - name: Test with Maven
34 | run: ./mvnw test --batch-mode --no-transfer-progress --show-version -D"license.skip=true"
35 |
--------------------------------------------------------------------------------
/src/test/resources/mybatis-freemarker-custom.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2015-2022 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 |
17 | template-file.base-dir=sqls
18 |
19 | template-file.path-provider.prefix = mappers
20 | template-file.path-provider.includes-package-path = false
21 | template-file.path-provider.separate-directory-per-mapper = false
22 | template-file.path-provider.includes-mapper-name-when-separate-directory = false
23 | template-file.path-provider.cache-enabled = false
24 |
25 | freemarker-settings.interpolation_syntax=dollar
26 | freemarker-settings.whitespace_stripping=yes
--------------------------------------------------------------------------------
/src/test/resources/sql/prepared.ftl:
--------------------------------------------------------------------------------
1 | <#--
2 |
3 | Copyright 2015-2022 the original author or authors.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | -->
18 | <#assign strValue='Wilma' />
19 | <#assign intValue=5/>
20 | <#assign doubleValue=10.5/>
21 | <#assign objectValue=innerObject/>
22 | <#assign innerStringProp=innerObject.strValue/>
23 |
24 | select * from names where firstName = <@p value='Wilma'/>
25 | and '${strValue}' = <@p value=strValue/>
26 | and ${intValue} = <@p value=intValue/>
27 | and ${doubleValue} = <@p value=doubleValue/>
28 | and '${innerStringProp}' = <@p value=innerObject.strValue/>
29 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/CustomizedDataContextMapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker;
17 |
18 | import java.util.List;
19 |
20 | import org.apache.ibatis.annotations.Lang;
21 | import org.apache.ibatis.annotations.Select;
22 |
23 | /**
24 | * @author elwood
25 | */
26 | public interface CustomizedDataContextMapper {
27 | @Lang(CustomizedDataContextTest.CustomFreeMarkerLanguageDriver.class)
28 | @Select("findUsingCustomizedContext.ftl")
29 | List find();
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/resources/org/mybatis/scripting/freemarker/create-db.sql:
--------------------------------------------------------------------------------
1 | --
2 | -- Copyright 2015-2022 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 |
17 | create table names (
18 | id int generated by default as identity,
19 | firstName varchar(20),
20 | lastName varchar(20)
21 | );
22 |
23 | insert into names (id, firstName, lastName) values(1, 'Fred', 'Flintstone');
24 | insert into names (id, firstName, lastName) values(2, 'Wilma', 'Flintstone');
25 | insert into names (id, firstName, lastName) values(3, 'Pebbles', 'Flintstone');
26 | insert into names (id, firstName, lastName) values(4, 'Barney', 'Rubble');
27 | insert into names (id, firstName, lastName) values(5, 'Betty', 'Rubble');
--------------------------------------------------------------------------------
/.github/workflows/site.yaml:
--------------------------------------------------------------------------------
1 | name: Site
2 |
3 | on:
4 | push:
5 | branches:
6 | - site
7 |
8 | permissions:
9 | contents: write
10 |
11 | concurrency:
12 | group: ${{ github.workflow }}-${{ github.ref }}
13 | cancel-in-progress: true
14 |
15 | jobs:
16 | build:
17 | if: github.repository_owner == 'mybatis' && ! contains(toJSON(github.event.head_commit.message), '[maven-release-plugin]')
18 | runs-on: ubuntu-latest
19 | timeout-minutes: 60
20 | steps:
21 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
22 | - name: Setup Java
23 | uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
24 | with:
25 | cache: maven
26 | distribution: temurin
27 | java-version: 25
28 | - name: Build site
29 | run: ./mvnw site site:stage --batch-mode --no-transfer-progress --settings ./.mvn/settings.xml --show-version -Dlicense.skip=true -DskipTests
30 | env:
31 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32 | NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
33 | - name: Deploy Site to gh-pages
34 | uses: JamesIves/github-pages-deploy-action@9d877eea73427180ae43cf98e8914934fe157a1a # v4
35 | with:
36 | branch: gh-pages
37 | folder: target/staging
38 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/PreparedDatabaseIdParamsMapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2023 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.scripting.freemarker;
17 |
18 | import java.util.Optional;
19 |
20 | import org.apache.ibatis.annotations.Lang;
21 | import org.apache.ibatis.annotations.Select;
22 |
23 | public interface PreparedDatabaseIdParamsMapper {
24 | @Lang(FreeMarkerLanguageDriver.class)
25 | @Select("preparedDatabaseIdTest.ftl")
26 | Optional getDatabaseIdTest();
27 |
28 | @Lang(FreeMarkerLanguageDriver.class)
29 | @Select("preparedDatabaseIdTest.ftl")
30 | Optional getDatabaseIdTestWithParam(PreparedParam param);
31 | }
32 |
--------------------------------------------------------------------------------
/.github/workflows/codeql.yaml:
--------------------------------------------------------------------------------
1 | name: "CodeQL"
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 | schedule:
9 | - cron: '43 10 * * 2'
10 |
11 | concurrency:
12 | group: ${{ github.workflow }}-${{ github.ref }}
13 | cancel-in-progress: true
14 |
15 | jobs:
16 | analyze:
17 | name: Analyze
18 | runs-on: 'ubuntu-latest'
19 | timeout-minutes: 30
20 | permissions:
21 | actions: read
22 | contents: read
23 | security-events: write
24 |
25 | steps:
26 | - name: Checkout
27 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
28 |
29 | - name: Setup Java
30 | uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
31 | with:
32 | cache: maven
33 | distribution: 'temurin'
34 | java-version: 25
35 |
36 | - name: Initialize CodeQL
37 | uses: github/codeql-action/init@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4
38 | with:
39 | queries: +security-and-quality
40 |
41 | - name: Autobuild
42 | uses: github/codeql-action/autobuild@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4
43 |
44 | - name: Perform CodeQL Analysis
45 | uses: github/codeql-action/analyze@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4
46 |
--------------------------------------------------------------------------------
/src/site/site.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | MyBatis FreeMarker Support
2 | ========================
3 |
4 | [](https://github.com/mybatis/freemarker-scripting/actions/workflows/ci.yaml)
5 | [](https://coveralls.io/github/mybatis/freemarker-scripting?branch=master)
6 | [](https://maven-badges.herokuapp.com/maven-central/org.mybatis.scripting/mybatis-freemarker)
7 | [](https://oss.sonatype.org/content/repositories/snapshots/org/mybatis/scripting/mybatis-freemarker/)
8 | [](https://www.apache.org/licenses/LICENSE-2.0.html)
9 |
10 | 
11 |
12 | MyBatis FreeMarker Scripting Support.
13 |
14 | Requirements
15 | ----------
16 |
17 | * master(1.2.x) : MyBatis 3.5+, FreeMarker 2.3.22+ and Java 8+
18 | * 1.1.x : MyBatis 3.4+, FreeMarker 2.3.22+ and Java 7+
19 |
20 |
21 | Essentials
22 | ----------
23 |
24 | * [See the docs](https://mybatis.org/freemarker-scripting/)
25 |
26 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/InvalidFreeMarkerSettingTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker;
17 |
18 | import org.junit.jupiter.api.Assertions;
19 | import org.junit.jupiter.api.Test;
20 |
21 | class InvalidFreeMarkerSettingTest {
22 |
23 | @Test
24 | void unknownSetting() {
25 |
26 | String message = Assertions.assertThrows(IllegalStateException.class, () -> {
27 | new FreeMarkerLanguageDriver(
28 | FreeMarkerLanguageDriverConfig.newInstance(c -> c.getFreemarkerSettings().put("foo", "bar")));
29 | }).getMessage();
30 | Assertions.assertEquals("Fail to configure FreeMarker template setting. name[foo] value[bar]", message);
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/scripting/freemarker/GeneratedParamsTemplateModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker;
17 |
18 | import java.util.List;
19 |
20 | import freemarker.template.TemplateModel;
21 |
22 | /**
23 | * Just a wrapper for list of generated params. Only to be able to return this object from
24 | * {@link freemarker.template.TemplateHashModel#get(java.lang.String)} method.
25 | *
26 | * @author elwood
27 | */
28 | public class GeneratedParamsTemplateModel implements TemplateModel {
29 | private final List generatedParams;
30 |
31 | public GeneratedParamsTemplateModel(List generatedParams) {
32 | this.generatedParams = generatedParams;
33 | }
34 |
35 | public List getGeneratedParams() {
36 | return generatedParams;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/Name.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker;
17 |
18 | /**
19 | * Entity to be selected.
20 | *
21 | * @author elwood
22 | */
23 | public class Name {
24 | private int id;
25 | private String firstName;
26 | private String lastName;
27 |
28 | public String getFirstName() {
29 | return firstName;
30 | }
31 |
32 | public void setFirstName(String firstName) {
33 | this.firstName = firstName;
34 | }
35 |
36 | public String getLastName() {
37 | return lastName;
38 | }
39 |
40 | public void setLastName(String lastName) {
41 | this.lastName = lastName;
42 | }
43 |
44 | public int getId() {
45 | return id;
46 | }
47 |
48 | public void setId(int id) {
49 | this.id = id;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/.github/workflows/sonar.yaml:
--------------------------------------------------------------------------------
1 | name: SonarCloud
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | permissions: read-all
9 |
10 | concurrency:
11 | group: ${{ github.workflow }}-${{ github.ref }}
12 | cancel-in-progress: true
13 |
14 | env:
15 | SONAR_ORGANIZATION: mybatis
16 | SONAR_PROJECT_KEY: freemarker-scripting
17 |
18 | jobs:
19 | build:
20 | if: github.repository_owner == 'mybatis'
21 | runs-on: ubuntu-latest
22 | timeout-minutes: 30
23 | steps:
24 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
25 | with:
26 | # Disabling shallow clone is recommended for improving relevancy of reporting
27 | fetch-depth: 0
28 | - name: Setup Java
29 | uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
30 | with:
31 | cache: maven
32 | distribution: temurin
33 | java-version: 25
34 | - name: Set SONAR_SCANNER_JAVA_OPTS
35 | run: echo "SONAR_SCANNER_JAVA_OPTS=-Xmx512m" >> ${GITHUB_ENV}
36 | - name: Analyze with SonarCloud
37 | run: ./mvnw verify jacoco:report sonar:sonar --batch-mode --no-transfer-progress --show-version -Dlicense.skip=true -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=${{ env.SONAR_ORGANIZATION }} -Dsonar.projectKey=${{ env.SONAR_ORGANIZATION }}_${{ env.SONAR_PROJECT_KEY }} -Dsonar.scanner.skipJreProvisioning=true -Dsonar.token=${{ env.SONAR_TOKEN }}
38 | env:
39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
41 |
--------------------------------------------------------------------------------
/.github/workflows/coveralls.yaml:
--------------------------------------------------------------------------------
1 | name: Coveralls
2 |
3 | on: [push, pull_request]
4 |
5 | permissions: read-all
6 |
7 | concurrency:
8 | group: ${{ github.workflow }}-${{ github.ref }}
9 | cancel-in-progress: true
10 |
11 | jobs:
12 | coveralls:
13 | if: github.repository_owner == 'mybatis'
14 | runs-on: ubuntu-latest
15 | timeout-minutes: 30
16 | steps:
17 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
18 | - name: Setup Java
19 | uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
20 | with:
21 | cache: maven
22 | distribution: temurin
23 | java-version: 25
24 | - name: Run the build
25 | run: ./mvnw test --batch-mode --no-transfer-progress --quiet --show-version -Dlicense.skip=true
26 | - name: Report Coverage to Coveralls for Pull Requests
27 | if: github.event_name == 'pull_request'
28 | run: ./mvnw generate-sources jacoco:report coveralls:report --batch-mode --no-transfer-progress -DpullRequest=${{ env.PR_NUMBER }} -DrepoToken=${{ env.GITHUB_TOKEN }} -DserviceName=github
29 | env:
30 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31 | PR_NUMBER: ${{ github.event.number }}
32 | - name: Report Coverage to Coveralls for General Push
33 | if: github.event_name == 'push'
34 | run: ./mvnw generate-sources jacoco:report coveralls:report --batch-mode --no-transfer-progress -DrepoToken=${{ env.GITHUB_TOKEN }} -DserviceName=github
35 | env:
36 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/TemplateFilePathProviderMapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker;
17 |
18 | import org.apache.ibatis.annotations.DeleteProvider;
19 | import org.apache.ibatis.annotations.InsertProvider;
20 | import org.apache.ibatis.annotations.Options;
21 | import org.apache.ibatis.annotations.SelectProvider;
22 | import org.apache.ibatis.annotations.UpdateProvider;
23 | import org.mybatis.scripting.freemarker.support.TemplateFilePathProvider;
24 |
25 | public interface TemplateFilePathProviderMapper {
26 |
27 | @Options(useGeneratedKeys = true, keyProperty = "id")
28 | @InsertProvider(type = TemplateFilePathProvider.class)
29 | void insert(Name name);
30 |
31 | @UpdateProvider(type = TemplateFilePathProvider.class)
32 | void update(Name name);
33 |
34 | @DeleteProvider(type = TemplateFilePathProvider.class)
35 | void delete(Name name);
36 |
37 | @SelectProvider(type = TemplateFilePathProvider.class)
38 | Name findById(Integer id);
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/PreparedParam.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker;
17 |
18 | /**
19 | * Class to test auto-generated prepared statement parameters.
20 | *
21 | * @author elwood
22 | */
23 | public class PreparedParam {
24 | public static class InnerClass {
25 | private String strValue = "InnerString";
26 |
27 | public String getStrValue() {
28 | return strValue;
29 | }
30 |
31 | public void setStrValue(String strValue) {
32 | this.strValue = strValue;
33 | }
34 | }
35 |
36 | private InnerClass innerObject = new InnerClass();
37 | private Object nullValue = null;
38 |
39 | public InnerClass getInnerObject() {
40 | return innerObject;
41 | }
42 |
43 | public void setInnerObject(InnerClass innerObject) {
44 | this.innerObject = innerObject;
45 | }
46 |
47 | public Object getNullValue() {
48 | return nullValue;
49 | }
50 |
51 | public void setNullValue(Object nullValue) {
52 | this.nullValue = nullValue;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/PreparedParamsMapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker;
17 |
18 | import java.util.List;
19 |
20 | import org.apache.ibatis.annotations.Lang;
21 | import org.apache.ibatis.annotations.Param;
22 | import org.apache.ibatis.annotations.Select;
23 |
24 | /**
25 | * This mapper demonstrates the usage of auto-generating prepared statement parameters instead of usual inline strategy.
26 | *
27 | * @author elwood
28 | */
29 | public interface PreparedParamsMapper {
30 | @Lang(FreeMarkerLanguageDriver.class)
31 | @Select("preparedIn.ftl")
32 | List findByNames(@Param("ids") List ids);
33 |
34 | /**
35 | * This is doesn't work - because params objects are unsupported when using auto-generated prepared parameters (it is
36 | * impossible to add parameters to MyBatis engine). This call will throw exception.
37 | */
38 | @Lang(FreeMarkerLanguageDriver.class)
39 | @Select("prepared.ftl")
40 | Name findUsingParamsObject(PreparedParam param);
41 |
42 | @Lang(FreeMarkerLanguageDriver.class)
43 | @Select("prepared.ftl")
44 | Name findUsingParams(@Param("innerObject") PreparedParam.InnerClass innerClass);
45 | }
46 |
--------------------------------------------------------------------------------
/.mvn/settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
21 |
22 |
23 |
24 |
25 | central
26 | ${env.CI_DEPLOY_USERNAME}
27 | ${env.CI_DEPLOY_PASSWORD}
28 |
29 |
30 |
31 |
32 | gh-pages-scm
33 |
34 | branch
35 | gh-pages
36 |
37 |
38 |
39 |
40 |
41 | github
42 | ${env.GITHUB_TOKEN}
43 |
44 |
45 |
46 |
47 | nvd
48 | ${env.NVD_API_KEY}
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/src/test/resources/org/mybatis/scripting/freemarker/mapper-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/src/test/resources/org/mybatis/scripting/freemarker/mapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
22 |
23 |
24 |
25 |
26 |
27 | id, ${r"firstName"}, lastName
28 |
29 |
32 |
35 |
36 |
39 |
40 |
43 |
44 |
47 |
50 |
51 |
56 |
57 |
62 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/scripting/freemarker/ParamObjectAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-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.scripting.freemarker;
17 |
18 | import java.util.HashMap;
19 | import java.util.List;
20 |
21 | import freemarker.ext.beans.BeanModel;
22 | import freemarker.ext.beans.BeansWrapperBuilder;
23 | import freemarker.template.TemplateHashModel;
24 | import freemarker.template.TemplateModel;
25 | import freemarker.template.TemplateModelException;
26 | import freemarker.template.Version;
27 |
28 | /**
29 | * Important: if you are using some object that already has property "p", then MyBatisParamDirective will be unavailable
30 | * from script.
31 | *
32 | * @author elwood
33 | */
34 | public class ParamObjectAdapter implements TemplateHashModel {
35 | private final BeanModel beanModel;
36 | private final List generatedParams;
37 | private HashMap additionalParams;
38 |
39 | public ParamObjectAdapter(Object paramObject, List generatedParams, Version incompatibleImprovementsVersion) {
40 | beanModel = new BeanModel(paramObject, new BeansWrapperBuilder(incompatibleImprovementsVersion).build());
41 | this.generatedParams = generatedParams;
42 | }
43 |
44 | /**
45 | * Puts the additional parameter into adapter, it will be available if no existing property with same key exists. For
46 | * example, it is suitable to add custom objects and directives into dataContext.
47 | */
48 | public void putAdditionalParam(String key, TemplateModel value) {
49 | if (additionalParams == null) {
50 | additionalParams = new HashMap<>();
51 | }
52 | additionalParams.put(key, value);
53 | }
54 |
55 | public List getGeneratedParams() {
56 | return generatedParams;
57 | }
58 |
59 | @Override
60 | public TemplateModel get(String key) throws TemplateModelException {
61 | // Trying to get bean property
62 | TemplateModel value = beanModel.get(key);
63 |
64 | // If no value retrieved, trying to find the key in additional params
65 | if (value == null && additionalParams != null && additionalParams.containsKey(key)) {
66 | return additionalParams.get(key);
67 | }
68 |
69 | // If it is GENERATED_PARAMS_KEY, returning wrapper of generated params list
70 | if (value == null && FreeMarkerSqlSource.GENERATED_PARAMS_KEY.equals(key)) {
71 | return new GeneratedParamsTemplateModel(generatedParams);
72 | }
73 |
74 | return value;
75 | }
76 |
77 | @Override
78 | public boolean isEmpty() throws TemplateModelException {
79 | return beanModel.isEmpty();
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/NameMapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker;
17 |
18 | import java.util.List;
19 |
20 | import org.apache.ibatis.annotations.Lang;
21 | import org.apache.ibatis.annotations.Param;
22 | import org.apache.ibatis.annotations.Select;
23 |
24 | /**
25 | * Annotations-driven mapper for {@link org.mybatis.scripting.freemarker.FreeMarkerInAnnotationsTest}.
26 | *
27 | * @author elwood
28 | */
29 | public interface NameMapper {
30 | /**
31 | * Simple query that is loaded from template.
32 | */
33 | @Lang(FreeMarkerLanguageDriver.class)
34 | @Select("getAllNames.ftl")
35 | List getAllNames();
36 |
37 | /**
38 | * Simple query with prepared statement parameter.
39 | */
40 | @Lang(FreeMarkerLanguageDriver.class)
41 | @Select("findName.ftl")
42 | Name findName(@Param("name") String name);
43 |
44 | /**
45 | * If any whitespace found inside @Select text, it is interpreted as inline script, not template name. It is
46 | * convenient to avoid creating templates when script is really small.
47 | */
48 | @Lang(FreeMarkerLanguageDriver.class)
49 | @Select("select * from names where id in (${ids?join(',')})")
50 | List findNamesByIds(@Param("ids") List ids);
51 |
52 | /**
53 | * There are no @Param annotation on argument. This means NameParam instance will be passed into driver as is, not as
54 | * Map entry. So, we need to support this case. Because in driver we need to add some another properties into template
55 | * model, and NameParam is not Map, we are need to wrap passed parameter object into
56 | * {@link org.mybatis.scripting.freemarker.ParamObjectAdapter} before processing template.
57 | */
58 | @Lang(FreeMarkerLanguageDriver.class)
59 | @Select("select * from names where id = <@p name='id'/> and id = ${id}")
60 | Name find(NameParam nameParam);
61 |
62 | /**
63 | * This query is to demonstrate MyBatis odd behaviour when using String as parameter and can use properties that not
64 | * exist. Both props will be use provided `name` parameter value. Goal is to write FreeMarker lang plugin to support
65 | * this behaviour too (although it is confusing one).
66 | */
67 | @Select("select * from names" + " where firstName = #{noSuchPropertyOnString}"
68 | + " or firstName = #{oneMoreUnexistingProperty}")
69 | List getNamesOddBehaviourStdLang(String name);
70 |
71 | /**
72 | * This query is to demonstrate that FreeMarker does not break the compatibility with this behaviour.
73 | */
74 | @Lang(FreeMarkerLanguageDriver.class)
75 | @Select("select * from names" + " where firstName = <@p name='noSuchPropertyOnString'/>"
76 | + " or firstName = <@p name='oneMoreUnexistingProperty'/>")
77 | List getNamesOddBehaviourFreeMarkerLang(String name);
78 | }
79 |
--------------------------------------------------------------------------------
/.mvn/wrapper/MavenWrapperDownloader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 |
20 | import java.io.IOException;
21 | import java.io.InputStream;
22 | import java.net.Authenticator;
23 | import java.net.PasswordAuthentication;
24 | import java.net.URI;
25 | import java.net.URL;
26 | import java.nio.file.Files;
27 | import java.nio.file.Path;
28 | import java.nio.file.StandardCopyOption;
29 | import java.util.concurrent.ThreadLocalRandom;
30 |
31 | public final class MavenWrapperDownloader {
32 | private static final String WRAPPER_VERSION = "3.3.4";
33 |
34 | private static final boolean VERBOSE = Boolean.parseBoolean(System.getenv("MVNW_VERBOSE"));
35 |
36 | public static void main(String[] args) {
37 | log("Apache Maven Wrapper Downloader " + WRAPPER_VERSION);
38 |
39 | if (args.length != 2) {
40 | System.err.println(" - ERROR wrapperUrl or wrapperJarPath parameter missing");
41 | System.exit(1);
42 | }
43 |
44 | try {
45 | log(" - Downloader started");
46 | final URL wrapperUrl = URI.create(args[0]).toURL();
47 | final Path baseDir = Path.of(".").toAbsolutePath().normalize();
48 | final Path wrapperJarPath = baseDir.resolve(args[1]).normalize();
49 | if (!wrapperJarPath.startsWith(baseDir)) {
50 | throw new IOException("Invalid path: outside of allowed directory");
51 | }
52 | downloadFileFromURL(wrapperUrl, wrapperJarPath);
53 | log("Done");
54 | } catch (IOException e) {
55 | System.err.println("- Error downloading: " + e.getMessage());
56 | if (VERBOSE) {
57 | e.printStackTrace();
58 | }
59 | System.exit(1);
60 | }
61 | }
62 |
63 | private static void downloadFileFromURL(URL wrapperUrl, Path wrapperJarPath)
64 | throws IOException {
65 | log(" - Downloading to: " + wrapperJarPath);
66 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
67 | final String username = System.getenv("MVNW_USERNAME");
68 | final char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
69 | Authenticator.setDefault(new Authenticator() {
70 | @Override
71 | protected PasswordAuthentication getPasswordAuthentication() {
72 | return new PasswordAuthentication(username, password);
73 | }
74 | });
75 | }
76 | Path temp = wrapperJarPath
77 | .getParent()
78 | .resolve(wrapperJarPath.getFileName() + "."
79 | + Long.toUnsignedString(ThreadLocalRandom.current().nextLong()) + ".tmp");
80 | try (InputStream inStream = wrapperUrl.openStream()) {
81 | Files.copy(inStream, temp, StandardCopyOption.REPLACE_EXISTING);
82 | Files.move(temp, wrapperJarPath, StandardCopyOption.REPLACE_EXISTING);
83 | } finally {
84 | Files.deleteIfExists(temp);
85 | }
86 | log(" - Downloader complete");
87 | }
88 |
89 | private static void log(String msg) {
90 | if (VERBOSE) {
91 | System.out.println(msg);
92 | }
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/PreparedParamsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker;
17 |
18 | import java.io.Reader;
19 | import java.sql.Connection;
20 | import java.util.ArrayList;
21 | import java.util.List;
22 |
23 | import org.apache.ibatis.exceptions.PersistenceException;
24 | import org.apache.ibatis.io.Resources;
25 | import org.apache.ibatis.jdbc.ScriptRunner;
26 | import org.apache.ibatis.mapping.Environment;
27 | import org.apache.ibatis.session.Configuration;
28 | import org.apache.ibatis.session.SqlSession;
29 | import org.apache.ibatis.session.SqlSessionFactory;
30 | import org.apache.ibatis.session.SqlSessionFactoryBuilder;
31 | import org.apache.ibatis.transaction.TransactionFactory;
32 | import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
33 | import org.hsqldb.jdbc.JDBCDataSource;
34 | import org.junit.jupiter.api.Assertions;
35 | import org.junit.jupiter.api.BeforeAll;
36 | import org.junit.jupiter.api.Test;
37 |
38 | /**
39 | * Test of using FreeMarker to generate prepared statements parameters.
40 | *
41 | * @author elwood
42 | */
43 | class PreparedParamsTest {
44 | private static SqlSessionFactory sqlSessionFactory;
45 |
46 | @BeforeAll
47 | static void setUp() throws Exception {
48 | Class.forName("org.hsqldb.jdbcDriver");
49 |
50 | JDBCDataSource dataSource = new JDBCDataSource();
51 | dataSource.setUrl("jdbc:hsqldb:mem:db3");
52 | dataSource.setUser("sa");
53 | dataSource.setPassword("");
54 |
55 | try (Connection conn = dataSource.getConnection()) {
56 | try (Reader reader = Resources.getResourceAsReader("org/mybatis/scripting/freemarker/create-db.sql")) {
57 | ScriptRunner runner = new ScriptRunner(conn);
58 | runner.setLogWriter(null);
59 | runner.setErrorLogWriter(null);
60 | runner.runScript(reader);
61 | conn.commit();
62 | }
63 | }
64 |
65 | TransactionFactory transactionFactory = new JdbcTransactionFactory();
66 | Environment environment = new Environment("development", transactionFactory, dataSource);
67 |
68 | // You can call configuration.setDefaultScriptingLanguage(FreeMarkerLanguageDriver.class)
69 | // after this to use FreeMarker driver by default.
70 | Configuration configuration = new Configuration(environment);
71 |
72 | configuration.addMapper(PreparedParamsMapper.class);
73 | sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
74 | }
75 |
76 | @Test
77 | void testInCall() {
78 | try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
79 | PreparedParamsMapper mapper = sqlSession.getMapper(PreparedParamsMapper.class);
80 | List names = mapper.findByNames(new ArrayList() {
81 | private static final long serialVersionUID = 1L;
82 | {
83 | add("Pebbles");
84 | add("Barney");
85 | add("Betty");
86 | }
87 | });
88 | Assertions.assertEquals(3, names.size());
89 | }
90 | }
91 |
92 | /**
93 | * PersistenceException will be thrown with cause of UnsupportedOperationException
94 | */
95 | @Test
96 | void testParamsObjectCall() {
97 | try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
98 | final PreparedParamsMapper mapper = sqlSession.getMapper(PreparedParamsMapper.class);
99 | Assertions.assertThrows(PersistenceException.class, () -> mapper.findUsingParamsObject(new PreparedParam()));
100 | }
101 | }
102 |
103 | @Test
104 | void testNoParamsCall() {
105 | try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
106 | PreparedParamsMapper mapper = sqlSession.getMapper(PreparedParamsMapper.class);
107 | Name name = mapper.findUsingParams(new PreparedParam.InnerClass());
108 | Assertions.assertTrue(name != null && name.getFirstName().equals("Wilma"));
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/PreparedDatabaseIdParamsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2024 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.scripting.freemarker;
17 |
18 | import java.io.Reader;
19 | import java.sql.Connection;
20 | import java.util.Optional;
21 |
22 | import org.apache.ibatis.io.Resources;
23 | import org.apache.ibatis.jdbc.ScriptRunner;
24 | import org.apache.ibatis.mapping.Environment;
25 | import org.apache.ibatis.session.Configuration;
26 | import org.apache.ibatis.session.SqlSession;
27 | import org.apache.ibatis.session.SqlSessionFactory;
28 | import org.apache.ibatis.session.SqlSessionFactoryBuilder;
29 | import org.apache.ibatis.transaction.TransactionFactory;
30 | import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
31 | import org.hsqldb.jdbc.JDBCDataSource;
32 | import org.junit.jupiter.api.Assertions;
33 | import org.junit.jupiter.api.BeforeAll;
34 | import org.junit.jupiter.api.Test;
35 |
36 | /**
37 | * Test of using FreeMarker to generate prepared statements parameters.
38 | *
39 | * @author s-nakao
40 | */
41 | class PreparedDatabaseIdParamsTest {
42 | private static SqlSessionFactory sqlSessionFactory;
43 |
44 | @BeforeAll
45 | static void setUp() throws Exception {
46 | Class.forName("org.hsqldb.jdbcDriver");
47 |
48 | JDBCDataSource dataSource = new JDBCDataSource();
49 | dataSource.setUrl("jdbc:hsqldb:mem:db5");
50 | dataSource.setUser("sa");
51 | dataSource.setPassword("");
52 |
53 | try (Connection conn = dataSource.getConnection()) {
54 | try (Reader reader = Resources.getResourceAsReader("org/mybatis/scripting/freemarker/create-db.sql")) {
55 | ScriptRunner runner = new ScriptRunner(conn);
56 | runner.setLogWriter(null);
57 | runner.setErrorLogWriter(null);
58 | runner.runScript(reader);
59 | conn.commit();
60 | }
61 | }
62 |
63 | TransactionFactory transactionFactory = new JdbcTransactionFactory();
64 | Environment environment = new Environment("development", transactionFactory, dataSource);
65 |
66 | // You can call configuration.setDefaultScriptingLanguage(FreeMarkerLanguageDriver.class)
67 | // after this to use FreeMarker driver by default.
68 | Configuration configuration = new Configuration(environment);
69 |
70 | // set databaseId. default null
71 | // If it is a property, please refer to the following
72 | // https://mybatis.org/mybatis-3/ja/configuration.html#databaseIdProvider.
73 | configuration.setDatabaseId("hsqldb");
74 |
75 | configuration.addMapper(PreparedDatabaseIdParamsMapper.class);
76 | sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
77 | }
78 |
79 | @Test
80 | void testReferDatabaseIdInTemplate() throws Exception {
81 | try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
82 | PreparedDatabaseIdParamsMapper mapper = sqlSession.getMapper(PreparedDatabaseIdParamsMapper.class);
83 | Optional nameList = mapper.getDatabaseIdTest();
84 | Assertions.assertTrue(nameList.isPresent());
85 | Assertions.assertEquals("Fred", nameList.orElseThrow(() -> new Exception()).getFirstName());
86 | Assertions.assertEquals("Flintstone", nameList.orElseThrow(() -> new Exception()).getLastName());
87 | }
88 | }
89 |
90 | @Test
91 | void testReferDatabaseIdInTemplateWithParam() throws Exception {
92 | try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
93 | PreparedDatabaseIdParamsMapper mapper = sqlSession.getMapper(PreparedDatabaseIdParamsMapper.class);
94 | Optional nameList = mapper.getDatabaseIdTestWithParam(new PreparedParam());
95 | Assertions.assertTrue(nameList.isPresent());
96 | Assertions.assertEquals("Fred", nameList.orElseThrow(() -> new Exception()).getFirstName());
97 | Assertions.assertEquals("Flintstone", nameList.orElseThrow(() -> new Exception()).getLastName());
98 | }
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/CustomizedDataContextTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker;
17 |
18 | import java.io.Reader;
19 | import java.sql.Connection;
20 | import java.util.List;
21 | import java.util.Map;
22 |
23 | import org.apache.ibatis.io.Resources;
24 | import org.apache.ibatis.jdbc.ScriptRunner;
25 | import org.apache.ibatis.mapping.Environment;
26 | import org.apache.ibatis.mapping.SqlSource;
27 | import org.apache.ibatis.session.Configuration;
28 | import org.apache.ibatis.session.SqlSession;
29 | import org.apache.ibatis.session.SqlSessionFactory;
30 | import org.apache.ibatis.session.SqlSessionFactoryBuilder;
31 | import org.apache.ibatis.transaction.TransactionFactory;
32 | import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
33 | import org.hsqldb.jdbc.JDBCDataSource;
34 | import org.junit.jupiter.api.Assertions;
35 | import org.junit.jupiter.api.BeforeAll;
36 | import org.junit.jupiter.api.Test;
37 |
38 | import freemarker.template.SimpleScalar;
39 | import freemarker.template.Template;
40 | import freemarker.template.Version;
41 |
42 | /**
43 | * @author elwood
44 | */
45 | class CustomizedDataContextTest {
46 | private static SqlSessionFactory sqlSessionFactory;
47 |
48 | @BeforeAll
49 | static void setUp() throws Exception {
50 | Class.forName("org.hsqldb.jdbcDriver");
51 |
52 | JDBCDataSource dataSource = new JDBCDataSource();
53 | dataSource.setUrl("jdbc:hsqldb:mem:db4");
54 | dataSource.setUser("sa");
55 | dataSource.setPassword("");
56 |
57 | try (Connection conn = dataSource.getConnection()) {
58 | try (Reader reader = Resources.getResourceAsReader("org/mybatis/scripting/freemarker/create-db.sql")) {
59 | ScriptRunner runner = new ScriptRunner(conn);
60 | runner.setLogWriter(null);
61 | runner.setErrorLogWriter(null);
62 | runner.runScript(reader);
63 | conn.commit();
64 | }
65 | }
66 |
67 | TransactionFactory transactionFactory = new JdbcTransactionFactory();
68 | Environment environment = new Environment("development", transactionFactory, dataSource);
69 |
70 | // You can call configuration.setDefaultScriptingLanguage(FreeMarkerLanguageDriver.class)
71 | // after this to use FreeMarker driver by default.
72 | Configuration configuration = new Configuration(environment);
73 |
74 | configuration.addMapper(CustomizedDataContextMapper.class);
75 | sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
76 | }
77 |
78 | public static class CustomSqlSource extends FreeMarkerSqlSource {
79 | CustomSqlSource(Template template, Configuration configuration, Version version) {
80 | super(template, configuration, version);
81 | }
82 |
83 | @Override
84 | @SuppressWarnings("unchecked")
85 | protected Object preProcessDataContext(Object dataContext, boolean isMap) {
86 | dataContext = super.preProcessDataContext(dataContext, isMap);
87 | if (isMap) {
88 | ((Map) dataContext).put("MY_NAME", new SimpleScalar("Barney"));
89 | } else {
90 | ((ParamObjectAdapter) dataContext).putAdditionalParam("MY_NAME", new SimpleScalar("Barney"));
91 | }
92 | return dataContext;
93 | }
94 | }
95 |
96 | public static class CustomFreeMarkerLanguageDriver extends FreeMarkerLanguageDriver {
97 | @Override
98 | protected SqlSource createSqlSource(Template template, Configuration configuration) {
99 | return new CustomSqlSource(template, configuration, freemarkerCfg.getIncompatibleImprovements());
100 | }
101 | }
102 |
103 | @Test
104 | void test() {
105 | try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
106 | CustomizedDataContextMapper mapper = sqlSession.getMapper(CustomizedDataContextMapper.class);
107 | List names = mapper.find();
108 | Assertions.assertEquals(1, names.size());
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/test/java/org/mybatis/scripting/freemarker/FreeMarkerInXmlTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2022 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.scripting.freemarker;
17 |
18 | import java.io.Reader;
19 | import java.sql.Connection;
20 | import java.sql.DriverManager;
21 | import java.util.ArrayList;
22 | import java.util.HashMap;
23 | import java.util.List;
24 |
25 | import org.apache.ibatis.io.Resources;
26 | import org.apache.ibatis.jdbc.ScriptRunner;
27 | import org.apache.ibatis.session.SqlSession;
28 | import org.apache.ibatis.session.SqlSessionFactory;
29 | import org.apache.ibatis.session.SqlSessionFactoryBuilder;
30 | import org.junit.jupiter.api.Assertions;
31 | import org.junit.jupiter.api.BeforeAll;
32 | import org.junit.jupiter.api.Test;
33 |
34 | /**
35 | * Test of using FreeMarker inside XML mapper config.
36 | *
37 | * @author elwood
38 | */
39 | class FreeMarkerInXmlTest {
40 | private static SqlSessionFactory sqlSessionFactory;
41 |
42 | @BeforeAll
43 | static void setUp() throws Exception {
44 | Connection conn = null;
45 |
46 | try {
47 | Class.forName("org.hsqldb.jdbcDriver");
48 | conn = DriverManager.getConnection("jdbc:hsqldb:mem:db2", "sa", "");
49 |
50 | Reader reader = Resources.getResourceAsReader("org/mybatis/scripting/freemarker/create-db.sql");
51 |
52 | ScriptRunner runner = new ScriptRunner(conn);
53 | runner.setLogWriter(null);
54 | runner.setErrorLogWriter(null);
55 | runner.runScript(reader);
56 | conn.commit();
57 | reader.close();
58 |
59 | reader = Resources.getResourceAsReader("org/mybatis/scripting/freemarker/mapper-config.xml");
60 | sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
61 | reader.close();
62 | } finally {
63 | if (conn != null) {
64 | conn.close();
65 | }
66 | }
67 | }
68 |
69 | @Test
70 | void testNoParamsCall() {
71 | try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
72 | List allNames = sqlSession.selectList("getAllNames");
73 | Assertions.assertEquals(5, allNames.size());
74 | }
75 | }
76 |
77 | @Test
78 | void testMyBatisParamCall() {
79 | try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
80 | HashMap paramsMap = new HashMap<>();
81 | paramsMap.put("name", "Pebbles");
82 | Name pebble = sqlSession.selectOne("findName", paramsMap);
83 | Assertions.assertTrue(pebble != null && pebble.getFirstName().equals("Pebbles"));
84 | }
85 | }
86 |
87 | @Test
88 | void testInQuery() {
89 | try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
90 | HashMap paramsMap = new HashMap<>();
91 | paramsMap.put("ids", new ArrayList() {
92 | private static final long serialVersionUID = 1L;
93 | {
94 | add(1);
95 | add(3);
96 | add(4);
97 | }
98 | });
99 | List namesByIds = sqlSession.selectList("findNamesByIds", paramsMap);
100 | Assertions.assertEquals(3, namesByIds.size());
101 | }
102 | }
103 |
104 | @Test
105 | void testParamObject() {
106 | try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
107 | Name name = sqlSession.selectOne("find", new NameParam(4));
108 | Assertions.assertTrue(name != null && name.getId() == 4);
109 | }
110 | }
111 |
112 | @Test
113 | void testStringParam() {
114 | try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
115 | List stdLangResult = sqlSession.selectList("getNamesOddBehaviourStdLang", "Pebbles");
116 | List freeMarkerLangResult = sqlSession.selectList("getNamesOddBehaviourFreeMarkerLang", "Pebbles");
117 | Assertions.assertEquals(1, stdLangResult.size());
118 | Assertions.assertEquals("Pebbles", stdLangResult.get(0).getFirstName());
119 | Assertions.assertEquals(1, freeMarkerLangResult.size());
120 | Assertions.assertEquals("Pebbles", freeMarkerLangResult.get(0).getFirstName());
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/java/org/mybatis/scripting/freemarker/MyBatisParamDirective.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2023 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.scripting.freemarker;
17 |
18 | import java.io.IOException;
19 | import java.util.List;
20 | import java.util.Map;
21 |
22 | import freemarker.core.Environment;
23 | import freemarker.ext.util.WrapperTemplateModel;
24 | import freemarker.template.DefaultListAdapter;
25 | import freemarker.template.SimpleScalar;
26 | import freemarker.template.TemplateBooleanModel;
27 | import freemarker.template.TemplateDateModel;
28 | import freemarker.template.TemplateDirectiveBody;
29 | import freemarker.template.TemplateDirectiveModel;
30 | import freemarker.template.TemplateException;
31 | import freemarker.template.TemplateModel;
32 | import freemarker.template.TemplateNumberModel;
33 | import freemarker.template.TemplateScalarModel;
34 |
35 | /**
36 | * Custom FreeMarker directive for generating "#{paramName}" declarations in convenient way. Problem is FreeMarker
37 | * supports this syntax natively and there are no chance to disable this (although it is deprecated). And to get
38 | * "#{paramName}" we should write ${r"#{paramName}"}. With this directive you can write more simple:
39 | *
40 | *
41 | *
42 | *
43 | * <@p name="paramName"/>
44 | *
45 | *
46 | *
47 | *
48 | * Also directive supports `value` attribute. If it is specified, param will take passed value and create the
49 | * corresponding #{}-parameter. This is useful in loops:
50 | *