├── .gitattributes
├── .github
└── workflows
│ ├── ci.yaml
│ ├── codeql.yml
│ ├── coveralls.yaml
│ ├── site.yaml
│ ├── sonar.yaml
│ └── sonatype.yaml
├── .gitignore
├── .mvn
├── extensions.xml
├── maven.config
├── settings.xml
└── wrapper
│ ├── MavenWrapperDownloader.java
│ └── maven-wrapper.properties
├── LICENSE
├── LICENSE_HEADER
├── NOTICE
├── README.md
├── format.xml
├── mvnw
├── mvnw.cmd
├── mybatis-scala-core
├── LICENSE_HEADER
├── format.xml
├── pom.xml
└── src
│ ├── main
│ └── scala
│ │ └── org
│ │ └── mybatis
│ │ └── scala
│ │ ├── cache
│ │ └── package.scala
│ │ ├── config
│ │ ├── Configuration.scala
│ │ ├── ConfigurationException.scala
│ │ ├── ConfigurationSpace.scala
│ │ ├── DefaultScriptingDriver.scala
│ │ ├── DynamicSQLBuilder.scala
│ │ ├── Environment.scala
│ │ ├── ObjectFactory.scala
│ │ ├── ObjectWrapperFactory.scala
│ │ └── package.scala
│ │ ├── mapping
│ │ ├── Binding.scala
│ │ ├── Case.scala
│ │ ├── Delete.scala
│ │ ├── FQI.scala
│ │ ├── Insert.scala
│ │ ├── JdbcType.scala
│ │ ├── KeyGenerator.scala
│ │ ├── OptionTypeHandler.scala
│ │ ├── Perform.scala
│ │ ├── ResultFlag.scala
│ │ ├── ResultMap.scala
│ │ ├── ResultMapping.scala
│ │ ├── ResultSetType.scala
│ │ ├── SQLFunction.scala
│ │ ├── Select.scala
│ │ ├── Statement.scala
│ │ ├── StatementType.scala
│ │ ├── T.scala
│ │ ├── Update.scala
│ │ └── package.scala
│ │ └── session
│ │ ├── ExecutorType.scala
│ │ ├── ResultHandlerDelegator.scala
│ │ ├── RowBounds.scala
│ │ ├── Session.scala
│ │ ├── SessionManager.scala
│ │ ├── TransactionIsolationLevel.scala
│ │ └── package.scala
│ ├── site
│ ├── site.xml
│ └── xdoc
│ │ ├── cache.xml
│ │ ├── configuration.xml
│ │ ├── index.xml
│ │ ├── mapping.xml
│ │ └── session.xml
│ └── test
│ ├── resources
│ └── mybatis.xml
│ └── scala
│ └── org
│ └── mybatis
│ └── scala
│ ├── Database.scala
│ ├── DatabaseSchema.scala
│ ├── DatabaseSupport.scala
│ ├── domain
│ ├── Blog.scala
│ └── User.scala
│ ├── infrastructure
│ ├── BlogRepository.scala
│ └── UserRepository.scala
│ └── mapping
│ ├── InsertSpec.scala
│ ├── SelectSpec.scala
│ └── StatementSpec.scala
├── mybatis-scala-samples
├── LICENSE_HEADER
├── format.xml
├── pom.xml
└── src
│ ├── main
│ ├── resources
│ │ ├── mybatis.xml
│ │ ├── sample-data.sql
│ │ └── schema.sql
│ └── scala
│ │ └── org
│ │ └── mybatis
│ │ └── scala
│ │ └── samples
│ │ ├── crud
│ │ ├── Config.scala
│ │ ├── Item.scala
│ │ ├── ItemDAO.scala
│ │ └── Main.scala
│ │ ├── delete
│ │ └── DeleteSample.scala
│ │ ├── insert
│ │ ├── InsertSample.scala
│ │ └── InsertSampleBatch.scala
│ │ ├── nestedselect
│ │ └── NestedSelectSample.scala
│ │ ├── performance
│ │ └── ProfileTest.scala
│ │ ├── resultmap
│ │ └── SelectWithResultMapSample.scala
│ │ ├── select
│ │ ├── SelectImmutableSample.scala
│ │ └── SelectSample.scala
│ │ ├── update
│ │ └── UpdateSample.scala
│ │ └── util
│ │ ├── DBSampleData.scala
│ │ └── DBSchema.scala
│ └── site
│ ├── resources
│ └── images
│ │ └── ERD.png
│ ├── site.xml
│ └── xdoc
│ └── index.xml
├── pom.xml
├── renovate.json
└── src
└── site
├── site.xml
└── xdoc
└── index.xml
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set default behaviour, in case users don't have core.autocrlf set.
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | name: Java CI
2 |
3 | on: [workflow_dispatch, push, pull_request]
4 |
5 | permissions: read-all
6 |
7 | jobs:
8 | test:
9 | runs-on: ${{ matrix.os }}
10 | strategy:
11 | matrix:
12 | cache: [maven]
13 | distribution: [temurin]
14 | java: [17, 21, 24, 25-ea]
15 | os: [ubuntu-latest, macos-latest, windows-latest]
16 | fail-fast: false
17 | max-parallel: 4
18 | name: Test JDK ${{ matrix.java }}, ${{ matrix.os }}
19 |
20 | steps:
21 | - uses: actions/checkout@v4
22 | - name: Set up JDK ${{ matrix.java }} ${{ matrix.distribution }}
23 | uses: actions/setup-java@v4
24 | with:
25 | java-version: ${{ matrix.java }}
26 | distribution: ${{ matrix.distribution }}
27 | cache: ${{ matrix.cache }}
28 | - name: Test with Maven
29 | run: ./mvnw test -B -V --no-transfer-progress -D"license.skip=true"
30 |
--------------------------------------------------------------------------------
/.github/workflows/codeql.yml:
--------------------------------------------------------------------------------
1 | name: "CodeQL"
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 | schedule:
9 | - cron: '26 6 * * 6'
10 |
11 | jobs:
12 | analyze:
13 | name: Analyze
14 | runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
15 | timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
16 | permissions:
17 | actions: read
18 | contents: read
19 | security-events: write
20 |
21 | strategy:
22 | fail-fast: false
23 | matrix:
24 | language: [ 'java-kotlin' ]
25 |
26 | steps:
27 | - name: Checkout repository
28 | uses: actions/checkout@v4
29 |
30 | - name: Setup Java
31 | uses: actions/setup-java@v4
32 | with:
33 | cache: maven
34 | distribution: 'temurin'
35 | java-version: 21
36 |
37 | - name: Initialize CodeQL
38 | uses: github/codeql-action/init@v3
39 | with:
40 | languages: ${{ matrix.language }}
41 | queries: +security-and-quality
42 |
43 | - name: Autobuild
44 | uses: github/codeql-action/autobuild@v3
45 |
46 | - name: Perform CodeQL Analysis
47 | uses: github/codeql-action/analyze@v3
48 | with:
49 | category: "/language:${{ matrix.language }}"
50 |
--------------------------------------------------------------------------------
/.github/workflows/coveralls.yaml:
--------------------------------------------------------------------------------
1 | name: Coveralls
2 |
3 | on: [push, pull_request]
4 |
5 | permissions: read-all
6 |
7 | jobs:
8 | build:
9 | if: github.repository_owner == 'mybatis'
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v4
13 | - name: Set up JDK
14 | uses: actions/setup-java@v4
15 | with:
16 | cache: maven
17 | distribution: temurin
18 | java-version: 21
19 | - name: Report Coverage to Coveralls for Pull Requests
20 | if: github.event_name == 'pull_request'
21 | run: ./mvnw -B -V test jacoco:report coveralls:report -q -Dlicense.skip=true -DrepoToken=$GITHUB_TOKEN -DserviceName=github -DpullRequest=$PR_NUMBER --no-transfer-progress
22 | env:
23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24 | PR_NUMBER: ${{ github.event.number }}
25 | - name: Report Coverage to Coveralls for General Push
26 | if: github.event_name == 'push'
27 | run: ./mvnw -B -V test jacoco:report coveralls:report -q -Dlicense.skip=true -DrepoToken=$GITHUB_TOKEN -DserviceName=github --no-transfer-progress
28 | env:
29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30 |
--------------------------------------------------------------------------------
/.github/workflows/site.yaml:
--------------------------------------------------------------------------------
1 | name: Site
2 |
3 | on:
4 | push:
5 | branches:
6 | - site
7 |
8 | permissions:
9 | contents: write
10 |
11 | jobs:
12 | build:
13 | if: github.repository_owner == 'mybatis' && ! contains(toJSON(github.event.head_commit.message), '[maven-release-plugin]')
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v4
17 | - name: Set up JDK
18 | uses: actions/setup-java@v4
19 | with:
20 | cache: maven
21 | distribution: temurin
22 | java-version: 21
23 | - name: Build site
24 | run: ./mvnw site site:stage -DskipTests -Dlicense.skip=true -B -V --no-transfer-progress --settings ./.mvn/settings.xml
25 | env:
26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
27 | NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
28 | - name: Deploy Site to gh-pages
29 | uses: JamesIves/github-pages-deploy-action@v4
30 | with:
31 | branch: gh-pages
32 | folder: target/staging
33 |
--------------------------------------------------------------------------------
/.github/workflows/sonar.yaml:
--------------------------------------------------------------------------------
1 | name: SonarCloud
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | permissions: read-all
9 |
10 | jobs:
11 | build:
12 | if: github.repository_owner == 'mybatis'
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | with:
17 | # Disabling shallow clone is recommended for improving relevancy of reporting
18 | fetch-depth: 0
19 | - name: Set up JDK
20 | uses: actions/setup-java@v4
21 | with:
22 | cache: maven
23 | distribution: temurin
24 | java-version: 21
25 | - name: Analyze with SonarCloud
26 | run: ./mvnw verify jacoco:report sonar:sonar -B -V -Dsonar.projectKey=mybatis_scala -Dsonar.organization=mybatis -Dsonar.host.url=https://sonarcloud.io -Dsonar.token=$SONAR_TOKEN -Dlicense.skip=true --no-transfer-progress
27 | env:
28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
30 |
--------------------------------------------------------------------------------
/.github/workflows/sonatype.yaml:
--------------------------------------------------------------------------------
1 | name: Sonatype
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | permissions: read-all
9 |
10 | jobs:
11 | build:
12 | if: github.repository_owner == 'mybatis' && ! contains(toJSON(github.event.head_commit.message), '[maven-release-plugin]')
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | - name: Set up JDK
17 | uses: actions/setup-java@v4
18 | with:
19 | cache: maven
20 | distribution: temurin
21 | java-version: 21
22 | - name: Deploy to Sonatype
23 | run: ./mvnw deploy -DskipTests -B -V --no-transfer-progress --settings ./.mvn/settings.xml -Dlicense.skip=true
24 | env:
25 | CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }}
26 | CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }}
27 |
--------------------------------------------------------------------------------
/.mvn/extensions.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 | fr.jcgay.maven
22 | maven-profiler
23 | 3.3
24 |
25 |
26 |
--------------------------------------------------------------------------------
/.mvn/maven.config:
--------------------------------------------------------------------------------
1 | -Daether.checksums.algorithms=SHA-512,SHA-256,SHA-1,MD5
2 | -Daether.connector.smartChecksums=false
3 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.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.Paths;
29 | import java.nio.file.StandardCopyOption;
30 | import java.util.concurrent.ThreadLocalRandom;
31 |
32 | public final class MavenWrapperDownloader {
33 | private static final String WRAPPER_VERSION = "3.3.2";
34 |
35 | private static final boolean VERBOSE = Boolean.parseBoolean(System.getenv("MVNW_VERBOSE"));
36 |
37 | public static void main(String[] args) {
38 | log("Apache Maven Wrapper Downloader " + WRAPPER_VERSION);
39 |
40 | if (args.length != 2) {
41 | System.err.println(" - ERROR wrapperUrl or wrapperJarPath parameter missing");
42 | System.exit(1);
43 | }
44 |
45 | try {
46 | log(" - Downloader started");
47 | final URL wrapperUrl = URI.create(args[0]).toURL();
48 | final String jarPath = args[1].replace("..", ""); // Sanitize path
49 | final Path wrapperJarPath = Paths.get(jarPath).toAbsolutePath().normalize();
50 | downloadFileFromURL(wrapperUrl, wrapperJarPath);
51 | log("Done");
52 | } catch (IOException e) {
53 | System.err.println("- Error downloading: " + e.getMessage());
54 | if (VERBOSE) {
55 | e.printStackTrace();
56 | }
57 | System.exit(1);
58 | }
59 | }
60 |
61 | private static void downloadFileFromURL(URL wrapperUrl, Path wrapperJarPath)
62 | throws IOException {
63 | log(" - Downloading to: " + wrapperJarPath);
64 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
65 | final String username = System.getenv("MVNW_USERNAME");
66 | final char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
67 | Authenticator.setDefault(new Authenticator() {
68 | @Override
69 | protected PasswordAuthentication getPasswordAuthentication() {
70 | return new PasswordAuthentication(username, password);
71 | }
72 | });
73 | }
74 | Path temp = wrapperJarPath
75 | .getParent()
76 | .resolve(wrapperJarPath.getFileName() + "."
77 | + Long.toUnsignedString(ThreadLocalRandom.current().nextLong()) + ".tmp");
78 | try (InputStream inStream = wrapperUrl.openStream()) {
79 | Files.copy(inStream, temp, StandardCopyOption.REPLACE_EXISTING);
80 | Files.move(temp, wrapperJarPath, StandardCopyOption.REPLACE_EXISTING);
81 | } finally {
82 | Files.deleteIfExists(temp);
83 | }
84 | log(" - Downloader complete");
85 | }
86 |
87 | private static void log(String msg) {
88 | if (VERBOSE) {
89 | System.out.println(msg);
90 | }
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. 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,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 | wrapperVersion=3.3.2
18 | distributionType=source
19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
20 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar
21 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | MyBatis Scala
2 | Copyright 2011-2023
3 |
4 | This product includes software developed by
5 | The MyBatis Team (http://www.mybatis.org/).
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | MyBatis Scala Adapter
2 | =====================
3 |
4 | [](https://github.com/mybatis/scala/actions/workflows/ci.yaml)
5 | [](https://coveralls.io/github/mybatis/scala?branch=master)
6 | [](https://www.apache.org/licenses/LICENSE-2.0.html)
7 |
8 | Versions
9 | * **Scala 2.9.2** [](https://maven-badges.herokuapp.com/maven-central/org.mybatis.scala/mybatis-scala-core_2.9.2)
10 | * **Scala 2.10** [](https://maven-badges.herokuapp.com/maven-central/org.mybatis.scala/mybatis-scala-core_2.10)
11 | * **Scala 2.11** [](https://maven-badges.herokuapp.com/maven-central/org.mybatis.scala/mybatis-scala-core_2.11)
12 | * **Scala 2.12** [](https://maven-badges.herokuapp.com/maven-central/org.mybatis.scala/mybatis-scala-core_2.12)
13 | * **Scala 2.13** [](https://maven-badges.herokuapp.com/maven-central/org.mybatis.scala/mybatis-scala-core_2.13)
14 |
15 | 
16 |
17 | MyBatis-Scala adapter for Scala.
18 |
19 | Essentials
20 | ----------
21 |
22 | * [See the docs](https://mybatis.org/scala/)
23 |
--------------------------------------------------------------------------------
/format.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/mybatis-scala-core/LICENSE_HEADER:
--------------------------------------------------------------------------------
1 | Copyright 2011-2015 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 |
--------------------------------------------------------------------------------
/mybatis-scala-core/format.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/mybatis-scala-core/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 | 4.0.0
21 |
22 |
23 | org.mybatis.scala
24 | mybatis-scala-parent_2.13
25 | 1.3.2-SNAPSHOT
26 |
27 |
28 | mybatis-scala-core_2.13
29 | 1.3.2-SNAPSHOT
30 | jar
31 | mybatis-scala-core
32 |
33 |
34 | scm:git:ssh://github.com/mybatis/scala.git
35 | scm:git:ssh://git@github.com/mybatis/scala.git
36 | HEAD
37 | http://github.com/mybatis/scala
38 |
39 |
40 |
41 |
42 | org.mybatis
43 | mybatis
44 | 3.5.19
45 |
46 |
47 | org.scala-lang
48 | scala-library
49 |
50 |
51 | org.scala-lang.modules
52 | scala-xml_${scala.binary}
53 |
54 |
55 | org.scalatest
56 | scalatest_${scala.binary}
57 | 3.2.19
58 | test
59 |
60 |
61 | org.hsqldb
62 | hsqldb
63 | 2.7.4
64 | test
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | META-INF
73 | ${project.basedir}/../
74 |
75 | LICENSE
76 | NOTICE
77 |
78 |
79 |
80 |
81 |
82 | net.alchim31.maven
83 | scala-maven-plugin
84 |
85 |
86 | attach-javadocs
87 |
88 | doc-jar
89 |
90 |
91 |
92 |
93 |
94 | org.apache.maven.plugins
95 | maven-site-plugin
96 |
97 |
98 | org.apache.maven.plugins
99 | maven-surefire-plugin
100 |
101 | true
102 |
103 |
104 |
105 | org.scalatest
106 | scalatest-maven-plugin
107 | 2.2.0
108 |
109 | ${project.build.directory}/surefire-reports
110 | .
111 | WDF TestSuite.txt
112 |
113 |
114 |
115 | test
116 |
117 | test
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | net.alchim31.maven
129 | scala-maven-plugin
130 | 4.9.5
131 |
132 |
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/cache/package.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala
17 |
18 | import org.apache.ibatis.cache.{Cache => MBCache}
19 | import org.apache.ibatis.cache.impl.PerpetualCache
20 | import org.mybatis.scala.mapping.T
21 | import org.apache.ibatis.cache.decorators._
22 |
23 | /** Provides Cache supporting types and objects */
24 | package object cache {
25 |
26 | /** Alias of [[org.apache.ibatis.cache.Cache]] */
27 | type Cache = MBCache
28 |
29 | /** Default MyBatis cache implementation: PerpetualCache */
30 | val DefaultCache = T[PerpetualCache]
31 |
32 | /** Default eviction policies */
33 | object Eviction {
34 |
35 | /** Least Recently Used: Removes objects that haven’t been used for the longest period of time. */
36 | val LRU = T[LruCache]
37 |
38 | /** First In First Out: Removes objects in the order that they entered the cache. */
39 | val FIFO = T[FifoCache]
40 |
41 | /** Soft Reference: Removes objects based on the garbage collector state and the rules of Soft References. */
42 | val SOFT = T[SoftCache]
43 |
44 | /** Weak Reference: More aggressively than Soft, removes objects based on the garbage collector state and rules of Weak References. */
45 | val WEAK = T[WeakCache]
46 |
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/config/ConfigurationException.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.config
17 |
18 | class ConfigurationException(msg : String, cause : Throwable = null) extends Throwable(msg, cause) {
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/config/DefaultScriptingDriver.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.config
17 |
18 | object DefaultScriptingDriver extends org.apache.ibatis.scripting.xmltags.XMLLanguageDriver
19 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/config/DynamicSQLBuilder.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.config
17 |
18 | import org.apache.ibatis.session.{Configuration => MBConfig}
19 | import java.util.{List, ArrayList}
20 | import org.apache.ibatis.scripting.xmltags._
21 | import org.apache.ibatis.mapping.SqlSource
22 | import scala.xml._
23 |
24 | /** Builder of Dynamic SQL Trees. */
25 | private[scala] class DynamicSQLBuilder(val configuration : MBConfig, val node : Node) {
26 |
27 | /** SqlSource built from an XML Node */
28 | def build : SqlSource =
29 | new DynamicSqlSource(configuration, parse(node))
30 |
31 | private def parse(n : Node) : SqlNode = {
32 | n match {
33 | case Text(text) =>
34 | new TextSqlNode(text)
35 | case PCData(text) =>
36 | new TextSqlNode(text)
37 | case {children @ _*} =>
38 | parseChildren(children)
39 | case trim @ {children @ _*} =>
40 | val content = parseChildren(children)
41 | new TrimSqlNode(
42 | configuration,
43 | content,
44 | attr(trim, "@prefix"),
45 | attr(trim, "@prefixOverrides"),
46 | attr(trim, "@suffix"),
47 | attr(trim, "@suffixOverrides")
48 | )
49 | case {children @ _*} =>
50 | val content = parseChildren(children)
51 | new WhereSqlNode(configuration, content)
52 | case {children @ _*} =>
53 | val content = parseChildren(children)
54 | new SetSqlNode(configuration, content)
55 | case foreach @ {children @ _*} =>
56 | val content = parseChildren(children)
57 | new ForEachSqlNode(
58 | configuration,
59 | content,
60 | attr(foreach, "@collection"),
61 | attr(foreach, "@index"),
62 | attr(foreach, "@item"),
63 | attr(foreach, "@open"),
64 | attr(foreach, "@close"),
65 | attr(foreach, "@separator"))
66 | case ifNode @ {children @ _*} =>
67 | val content = parseChildren(children)
68 | new IfSqlNode(content, attr(ifNode, "@test"))
69 | case {children @ _*} =>
70 | val ifNodes = new ArrayList[SqlNode]
71 | var defaultNode : MixedSqlNode = null
72 | for (child <- children) {
73 | child match {
74 | case when @ {ch @ _*} => {
75 | val content = parseChildren(ch)
76 | ifNodes add new IfSqlNode(content, attr(when, "@test"))
77 | }
78 | case other @ {ch @ _*} =>
79 | if (defaultNode == null)
80 | defaultNode = parseChildren(ch)
81 | else
82 | throw new ConfigurationException("Too many default (otherwise) elements in choose statement.")
83 | //error("Too many default (otherwise) elements in choose statement.")
84 | case _ =>
85 | }
86 | }
87 | new ChooseSqlNode(ifNodes, defaultNode)
88 | case ifNode @ {children @ _*} =>
89 | val content = parseChildren(children)
90 | new IfSqlNode(content, attr(ifNode, "@test"))
91 | case other @ {children @ _*} =>
92 | parseChildren(other)
93 | case a : Atom[_] =>
94 | new TextSqlNode(a.data.asInstanceOf[String])
95 | case bind @ =>
96 | new VarDeclSqlNode(attr(bind, "@name"), attr(bind, "@value"))
97 | case unsupported =>
98 | throw new ConfigurationException("Unknown element " + unsupported.getClass.getName + " in SQL statement.")
99 | //error("Unknown element " + unsupported.toString + " in SQL statement.")
100 | }
101 | }
102 |
103 | private def parseChildren(children : Seq[Node]) : MixedSqlNode = {
104 | val nodes = new ArrayList[SqlNode]
105 | for (child <- children) {
106 | nodes add parse(child)
107 | }
108 | new MixedSqlNode(nodes)
109 | }
110 |
111 | private def attr(n : Node, name : String) : String = {
112 | (n \ name).text match {
113 | case "" => null
114 | case text => text
115 | }
116 | }
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/config/Environment.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.config
17 |
18 | import javax.sql.DataSource
19 |
20 | /**
21 | *
22 | */
23 | case class Environment(id : String, tf : TransactionFactory, ds : DataSource) {
24 |
25 | val unwrap = new org.apache.ibatis.mapping.Environment(id, tf, ds)
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/config/ObjectFactory.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.config
17 |
18 | class DefaultObjectFactory extends ObjectFactory {
19 |
20 | def create[T](t : Class[T]) : T = create(t, null, null)
21 |
22 | def create[T](t : Class[T], constructorArgTypes : java.util.List[Class[_]], constructorArgs : java.util.List[AnyRef]) : T = {
23 | val classToCreate = resolveInterface(t)
24 | instantiateClass[T](classToCreate, constructorArgTypes, constructorArgs)
25 | }
26 |
27 | override def setProperties(properties : java.util.Properties) : Unit = {}
28 |
29 | private def instantiateClass[T](t : Class[_], constructorArgTypes : java.util.List[Class[_]], constructorArgs : java.util.List[AnyRef]) : T = {
30 |
31 | val argTypes = {
32 | if (constructorArgTypes != null)
33 | constructorArgTypes.toArray[Class[_]](new Array[Class[_]](constructorArgTypes.size))
34 | else
35 | null
36 | }
37 |
38 | val constructor = getConstructor(t, argTypes)
39 |
40 | val argValues = {
41 | if (constructorArgs != null)
42 | constructorArgs.toArray[AnyRef](new Array[AnyRef](constructorArgs.size))
43 | else
44 | null
45 | }
46 |
47 | try {
48 | if (argTypes == null || argValues == null) {
49 | constructor.newInstance().asInstanceOf[T]
50 | }
51 | else {
52 | constructor.newInstance(argValues : _*).asInstanceOf[T]
53 | }
54 | }
55 | catch {
56 | case e : Exception =>
57 | val types = {
58 | if (argTypes == null) ""
59 | else argTypes.map(_.getSimpleName).reduceLeft(_ + ", " + _)
60 | }
61 | val values = {
62 | if (argValues == null) ""
63 | else argValues.map(String.valueOf(_)).reduceLeft(_ + ", " + _)
64 | }
65 | throw new org.apache.ibatis.reflection.ReflectionException(
66 | "Error instantiating %s with invalid types (%s) or values (%s). Cause: %s".format(t.getSimpleName, types, values, e.getMessage), e);
67 | }
68 | }
69 |
70 | private def resolveInterface[T](t : Class[T]) : Class[_] = {
71 | // Java Collections
72 | if (t == classOf[java.util.List[_]])
73 | classOf[java.util.LinkedList[_]]
74 | else if (t == classOf[java.util.Collection[_]])
75 | classOf[java.util.LinkedList[_]]
76 | else if (t == classOf[java.util.Map[_,_]])
77 | classOf[java.util.HashMap[_,_]]
78 | else if (t == classOf[java.util.SortedSet[_]])
79 | classOf[java.util.TreeSet[_]]
80 | else if (t == classOf[java.util.Set[_]])
81 | classOf[java.util.HashSet[_]]
82 | // Scala Collections
83 | else if (t == classOf[scala.collection.Seq[_]])
84 | classOf[scala.collection.mutable.ArrayBuffer[_]]
85 | else if (t == classOf[scala.collection.Map[_,_]])
86 | classOf[scala.collection.mutable.HashMap[_,_]]
87 | else if (t == classOf[scala.collection.Set[_]])
88 | classOf[scala.collection.mutable.HashSet[_]]
89 | else {
90 | t
91 | }
92 | }
93 |
94 | def isCollection[T](t : Class[T]) : Boolean =
95 | classOf[scala.collection.Seq[_]].isAssignableFrom(t) ||
96 | classOf[scala.collection.Set[_]].isAssignableFrom(t)
97 |
98 | sealed class CacheKey(t : Class[_], args : Array[Class[_]]) {
99 |
100 | val _hc : Int = {
101 | if (args == null) {
102 | t.hashCode
103 | }
104 | else {
105 | var code = t.hashCode
106 | for (at <- args) {
107 | code = code * 41 + at.hashCode
108 | }
109 | code
110 | }
111 | }
112 |
113 | override def hashCode = _hc
114 |
115 | override def equals(that : Any) =
116 | that != null &&
117 | that.getClass == classOf[CacheKey] &&
118 | that.asInstanceOf[CacheKey]._hc == this._hc
119 |
120 | }
121 |
122 | def getConstructor(t : Class[_], args : Array[Class[_]]) : java.lang.reflect.Constructor[_] = {
123 | try {
124 | if (args == null) {
125 | val constructor = t.getDeclaredConstructor()
126 | if (!constructor.isAccessible()) {
127 | constructor.setAccessible(true)
128 | }
129 | constructor
130 | }
131 | else {
132 | val constructor = t.getDeclaredConstructor(args : _*)
133 | if (!constructor.isAccessible()) {
134 | constructor.setAccessible(true)
135 | }
136 | constructor
137 | }
138 | }
139 | catch {
140 | case e : Exception =>
141 | val types = {
142 | if (args == null) ""
143 | else args.map(_.getSimpleName).reduceLeft(_ + ", " + _)
144 | }
145 | throw new org.apache.ibatis.reflection.ReflectionException(
146 | "Error instantiating %s with invalid types (%s). Cause: %s".format(t.getSimpleName, args, e.getMessage), e);
147 | }
148 | }
149 |
150 | }
151 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/config/ObjectWrapperFactory.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.config
17 |
18 | import org.apache.ibatis.reflection.MetaObject
19 | import org.apache.ibatis.reflection.property.PropertyTokenizer
20 | import org.apache.ibatis.reflection.factory.{ObjectFactory => XObjectFactory}
21 |
22 | abstract class CollectionObjectWrapper extends org.apache.ibatis.reflection.wrapper.ObjectWrapper {
23 | def get(prop : PropertyTokenizer) : AnyRef = null
24 | def set(prop : PropertyTokenizer, value : AnyRef) : Unit = {}
25 | def findProperty(name : String, useCamelCaseMapping : Boolean) : String = null
26 | def getGetterNames() : Array[String] = null
27 | def getSetterNames() : Array[String] = null
28 | def getSetterType(name : String) : Class[_] = null
29 | def getGetterType(name : String) : Class[_] = null
30 | def hasSetter(name : String) : Boolean = false
31 | def hasGetter(name : String) : Boolean = false
32 | def instantiatePropertyValue(name : String, prop : PropertyTokenizer, objectFactory : XObjectFactory) : MetaObject = null
33 | def isCollection() : Boolean = true
34 | }
35 |
36 | class ArrayBufferWrapper(buffer : scala.collection.mutable.ArrayBuffer[AnyRef]) extends CollectionObjectWrapper {
37 | import scala.jdk.CollectionConverters._
38 | def add(element : AnyRef) : Unit = buffer append element
39 | def addAll[E](elements : java.util.List[E]) : Unit = buffer.addAll(elements.asInstanceOf[java.util.Collection[AnyRef]].asScala)
40 | }
41 |
42 | class HashSetWrapper(set : scala.collection.mutable.HashSet[AnyRef]) extends CollectionObjectWrapper {
43 | import scala.jdk.CollectionConverters._
44 | def add(element : AnyRef) : Unit = set add element
45 | def addAll[E](elements : java.util.List[E]) : Unit = set.addAll(elements.asInstanceOf[java.util.Collection[AnyRef]].asScala)
46 | }
47 |
48 | class DefaultObjectWrapperFactory extends ObjectWrapperFactory {
49 | def hasWrapperFor(obj : AnyRef) : Boolean = obj match {
50 | case o : scala.collection.mutable.ArrayBuffer[_] => true
51 | case o : scala.collection.mutable.HashSet[_] => true
52 | case _ => false
53 | }
54 | def getWrapperFor(metaObject : MetaObject, obj : AnyRef) : org.apache.ibatis.reflection.wrapper.ObjectWrapper = obj match {
55 | case o : scala.collection.mutable.ArrayBuffer[_] => new ArrayBufferWrapper(o.asInstanceOf[scala.collection.mutable.ArrayBuffer[AnyRef]])
56 | case o : scala.collection.mutable.HashSet[_] => new HashSetWrapper(o.asInstanceOf[scala.collection.mutable.HashSet[AnyRef]])
57 | case _ =>
58 | throw new IllegalArgumentException("Type not supported: " + obj.getClass.getSimpleName)
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/config/package.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala
17 |
18 | /** Provides main configuration classes.
19 | * == Basic usage ==
20 | * Usual steps are:
21 | * - Load the configuration from an external XML file
22 | * - Add one or more configuration spaces with mapped statements
23 | * - Create the persistenceContext
24 | *
25 | * == Code sample ==
26 | * {{{
27 | * val config = Configuration("META-INF/mybatis.xml")
28 | * config.addSpace("ns") { space =>
29 | * space ++= MyDAO
30 | * }
31 | * val persistenceContext = config.createPersistenceContext
32 | * }}}
33 | *
34 | * == Another example without external XML file and with default namespace ==
35 | * {{{
36 | * val config = Configuration(
37 | * Environment(
38 | * "default",
39 | * new JdbcTransactionFactory(),
40 | * new PooledDataSource(
41 | * "org.hsqldb.jdbcDriver",
42 | * "jdbc:hsqldb:mem:scala",
43 | * "sa",
44 | * ""
45 | * )
46 | * )
47 | * )
48 | * config ++= MyDAO
49 | *
50 | * val persistenceContext = config.createPersistenceContext
51 | * }}}
52 | */
53 | package object config {
54 |
55 | type TransactionFactory = org.apache.ibatis.transaction.TransactionFactory
56 | type JdbcTransactionFactory = org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory
57 | type ManagedTransactionFactory = org.apache.ibatis.transaction.managed.ManagedTransactionFactory
58 |
59 | type PooledDataSource = org.apache.ibatis.datasource.pooled.PooledDataSource
60 | type UnpooledDataSource = org.apache.ibatis.datasource.unpooled.UnpooledDataSource
61 | type JndiDataSourceFactory = org.apache.ibatis.datasource.jndi.JndiDataSourceFactory
62 |
63 | type ObjectFactory = org.apache.ibatis.reflection.factory.ObjectFactory
64 | type ObjectWrapperFactory = org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory
65 | type DatabaseIdProvider = org.apache.ibatis.mapping.DatabaseIdProvider
66 | type LanguageDriver = org.apache.ibatis.scripting.LanguageDriver
67 |
68 | sealed abstract class LocalCacheScope {
69 | val unwrap : org.apache.ibatis.session.LocalCacheScope
70 | case object SESSION extends LocalCacheScope { val unwrap = org.apache.ibatis.session.LocalCacheScope.SESSION }
71 | case object STATEMENT extends LocalCacheScope { val unwrap = org.apache.ibatis.session.LocalCacheScope.STATEMENT }
72 | }
73 |
74 | sealed abstract class AutoMappingBehavior {
75 | val unwrap : org.apache.ibatis.session.AutoMappingBehavior
76 | case object FULL extends AutoMappingBehavior { val unwrap = org.apache.ibatis.session.AutoMappingBehavior.FULL }
77 | case object NONE extends AutoMappingBehavior { val unwrap = org.apache.ibatis.session.AutoMappingBehavior.NONE }
78 | case object PARTIAL extends AutoMappingBehavior { val unwrap = org.apache.ibatis.session.AutoMappingBehavior.PARTIAL }
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/Binding.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | sealed class ParamModeEnum(v : String) {
19 | override def toString : String = v
20 | }
21 |
22 | case object ModeIN extends ParamModeEnum("IN")
23 | case object ModeOUT extends ParamModeEnum("OUT")
24 | case object ModeINOUT extends ParamModeEnum("INOUT")
25 |
26 | /** Provides compile time checked inline parameter bindings.
27 | * == Syntax ==
28 | * General notation
29 | * {{{
30 | * {?[T](propertyName, jdbcType=DBT, typeHandler=T[TH], mode=MD, numericScale=NS, resultMap=RM)}
31 | * }}}
32 | * Where
33 | * {{{
34 | * - T : JavaType : Type of the parameter property, Optional
35 | * - propertyName : String : Name of the parameter property, Required
36 | * - DBT : JdbcType : Any value of org.mybatis.scala.mapping.JdbcType, Optional
37 | * - TH : TypeHandler : A TypeHandler implementation class, Optional
38 | * - MD : ParamModeEnum : Any of (ModeIN, ModeOUT, ModeINOUT), Optional
39 | * - NS : Int : Numeric Scale, Optional
40 | * - RM : ResultMap : A ResultMap Object, Optional
41 | * }}}
42 | *
43 | * Simplified Notation
44 | * If you need to specify only the property name, you ca use this simplified notation:
45 | * {{{
46 | * {propertyName?}
47 | * }}}
48 | *
49 | * == Code Examples ==
50 | * {{{
51 | *
52 | * SELECT * FROM person
53 | * WHERE name = {"name"?}
54 | *
55 | * }}}
56 | *
57 | * {{{
58 | *
59 | * SELECT * FROM task
60 | * WHERE due_date = {?("date", typeHandler=T[JodaTimeTypeHandler])}
61 | *
62 | * }}}
63 | *
64 | */
65 | object Binding {
66 |
67 | /** Custom Aliased Types */
68 | private val valueTypes = Set("byte", "long", "short", "int", "double", "float", "boolean",
69 | "byte[]", "long[]", "short[]", "int[]", "double[]", "float[]", "boolean[]")
70 |
71 | /** Custom alias translator */
72 | private def translate(cls : Class[_]) : String = {
73 | if (valueTypes contains cls.getSimpleName) "_" + cls.getSimpleName
74 | else cls.getName
75 | }
76 |
77 | /** Generates an inline parameter binding */
78 | def ?[JavaType : Manifest] (
79 | property : String,
80 | jdbcType : JdbcType = null,
81 | jdbcTypeName : String = null,
82 | numericScale : Int = 0,
83 | mode : ParamModeEnum = ModeIN,
84 | typeHandler : T[_ <: TypeHandler[_]] = null,
85 | resultMap : ResultMap[_] = null
86 | ) : String = {
87 | Seq[Option[String]](
88 | Some(property)
89 | ,if (jdbcType != null) Some("jdbcType=" + jdbcType.toString) else None
90 | ,if (jdbcTypeName != null) Some("jdbcTypeName=" + jdbcTypeName) else None
91 | ,if (numericScale != 0) Some("numericScale=" + numericScale) else None
92 | ,if (mode != ModeIN) Some("mode=" + mode.toString) else None
93 | ,if (typeHandler != null) Some("typeHandler=" + typeHandler.unwrap.getName) else None
94 | ,if (resultMap != null) Some("resultMap=" + resultMap.fqi.id) else None
95 | ,{
96 | val t = manifest[JavaType].runtimeClass
97 | if (t != classOf[Nothing]) Some("javaType=" + translate(t)) else None
98 | }
99 | ) filter {_ match {case Some(x) => true; case None => false }} map {_.get} mkString("#{", ",", "}")
100 | }
101 |
102 | /** Utility class for simplified syntax support */
103 | implicit class Param(property : String) {
104 | def ? = Binding ? (property)
105 | }
106 |
107 | /** Implicit conversion for simplified syntax support */
108 | //implicit def StringToParam(s : String) = new Param(s)
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/Case.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | /** A result map reference based on some discriminator value.
19 | * @see [[org.mybatis.scala.mapping.ResultMap]]
20 | * @param value A discriminator value
21 | * @param resultMap A ResultMap to be used if value matches
22 | * @version \$Revision$
23 | */
24 | case class Case(val value : String, val resultMap : ResultMap[Any])
25 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/Delete.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | import org.mybatis.scala.session.Session
19 |
20 | /** A mapped SQL DELETE statement.
21 | * Basically this defines a function: (Param => Int)
22 | * @tparam Param Input parameter type of the apply method.
23 | * @version \$Revision$
24 | */
25 | abstract class Delete [Param : Manifest]
26 | extends Statement
27 | with SQLFunction1[Param,Int] {
28 |
29 | def parameterTypeClass = manifest[Param].runtimeClass
30 |
31 | /** Exceutes the SQL DELETE Statement
32 | * @param param Input paramenter of the statement
33 | * @param s Implicit Session
34 | * @return number of affected rows
35 | */
36 | def apply(param : Param)(implicit s : Session) : Int =
37 | execute { s.delete(fqi.id, param) }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/FQI.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | /** Fully Qualified Identifier */
19 | private[scala] case class FQI(spaceId : String, localId : String) {
20 | def resolveIn(externalSpaceId : String) : String = {
21 | if (externalSpaceId == spaceId)
22 | localId
23 | else
24 | spaceId + "." + localId
25 | }
26 | def id = spaceId + "." + localId
27 | }
28 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/Insert.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | import org.mybatis.scala.session.Session
19 |
20 | /** A mapped SQL INSERT statement.
21 | * Basically this defines a function: (Param => Int)
22 | * @tparam Param Input parameter type of the apply method.
23 | * @version \$Revision$
24 | */
25 | abstract class Insert[Param : Manifest]
26 | extends Statement
27 | with SQLFunction1[Param,Int] {
28 |
29 | /** Key Generator used to retrieve database generated keys.
30 | * Defaults to null
31 | */
32 | var keyGenerator : KeyGenerator = null //JdbcGeneratedKey(null, "id")
33 |
34 | def parameterTypeClass = manifest[Param].runtimeClass
35 |
36 | /** Exceutes the SQL INSERT Statement
37 | * @param param Input paramenter of the statement
38 | * @param s Implicit Session
39 | * @return number of affected rows
40 | */
41 | def apply(param : Param)(implicit s : Session) : Int =
42 | execute { s.insert(fqi.id, param) }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/JdbcType.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | import org.apache.ibatis.`type`.{JdbcType => JdbcTypeEnum}
19 |
20 | /** A wrapper of [[org.apache.ibatis.type.JdbcType]] */
21 | sealed trait JdbcType {
22 | val unwrap : JdbcTypeEnum
23 | override def toString = unwrap.toString
24 | }
25 |
26 | /** A wrapper of [[org.apache.ibatis.type.JdbcType]] values. */
27 | object JdbcType {
28 | val ARRAY = new JdbcType { val unwrap = JdbcTypeEnum.ARRAY }
29 | val BIT = new JdbcType { val unwrap = JdbcTypeEnum.BIT }
30 | val TINYINT = new JdbcType { val unwrap = JdbcTypeEnum.TINYINT }
31 | val SMALLINT = new JdbcType { val unwrap = JdbcTypeEnum.SMALLINT }
32 | val INTEGER = new JdbcType { val unwrap = JdbcTypeEnum.INTEGER }
33 | val BIGINT = new JdbcType { val unwrap = JdbcTypeEnum.BIGINT }
34 | val FLOAT = new JdbcType { val unwrap = JdbcTypeEnum.FLOAT }
35 | val REAL = new JdbcType { val unwrap = JdbcTypeEnum.REAL }
36 | val DOUBLE = new JdbcType { val unwrap = JdbcTypeEnum.DOUBLE }
37 | val NUMERIC = new JdbcType { val unwrap = JdbcTypeEnum.NUMERIC }
38 | val DECIMAL = new JdbcType { val unwrap = JdbcTypeEnum.DECIMAL }
39 | val CHAR = new JdbcType { val unwrap = JdbcTypeEnum.CHAR }
40 | val VARCHAR = new JdbcType { val unwrap = JdbcTypeEnum.VARCHAR }
41 | val LONGVARCHAR = new JdbcType { val unwrap = JdbcTypeEnum.LONGVARCHAR }
42 | val DATE = new JdbcType { val unwrap = JdbcTypeEnum.DATE }
43 | val TIME = new JdbcType { val unwrap = JdbcTypeEnum.TIME }
44 | val TIMESTAMP = new JdbcType { val unwrap = JdbcTypeEnum.TIMESTAMP }
45 | val BINARY = new JdbcType { val unwrap = JdbcTypeEnum.BINARY }
46 | val VARBINARY = new JdbcType { val unwrap = JdbcTypeEnum.VARBINARY }
47 | val LONGVARBINARY = new JdbcType { val unwrap = JdbcTypeEnum.LONGVARBINARY }
48 | val NULL = new JdbcType { val unwrap = JdbcTypeEnum.NULL }
49 | val OTHER = new JdbcType { val unwrap = JdbcTypeEnum.OTHER }
50 | val BLOB = new JdbcType { val unwrap = JdbcTypeEnum.BLOB }
51 | val CLOB = new JdbcType { val unwrap = JdbcTypeEnum.CLOB }
52 | val BOOLEAN = new JdbcType { val unwrap = JdbcTypeEnum.BOOLEAN }
53 | val CURSOR = new JdbcType { val unwrap = JdbcTypeEnum.CURSOR }
54 | val UNDEFINED = new JdbcType { val unwrap = JdbcTypeEnum.UNDEFINED }
55 | val NVARCHAR = new JdbcType { val unwrap = JdbcTypeEnum.NVARCHAR }
56 | val NCHAR = new JdbcType { val unwrap = JdbcTypeEnum.NCHAR }
57 | val NCLOB = new JdbcType { val unwrap = JdbcTypeEnum.NCLOB }
58 | val STRUCT = new JdbcType { val unwrap = JdbcTypeEnum.STRUCT }
59 | }
60 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/KeyGenerator.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | /** Abstract KeyGenerator
19 | * This trait must be implemented by any KeyGenerator.
20 | */
21 | trait KeyGenerator {
22 | var keyProperty : String
23 | var keyColumn : String
24 | }
25 |
26 | /** JDBC 3 Key Generator implementation.
27 | * This uses JDBC generatedKeys
28 | * @param keyColumn Column to be read from the generated keys resultset.
29 | * @param keyProperty Property to be set with the generated key value.
30 | */
31 | class JdbcGeneratedKey(keyColumn_ : String, keyProperty_ : String) extends KeyGenerator {
32 | var keyColumn = keyColumn_
33 | var keyProperty = keyProperty_
34 | }
35 |
36 | /** Factory of JdbcGeneratedKey */
37 | object JdbcGeneratedKey {
38 |
39 | /** Crteates a new JdbcGeneratedKey
40 | * @param keyColumn Column to be read from the generated keys resultset.
41 | * @param keyProperty Property to be set with the generated key value.
42 | */
43 | def apply(keyColumn : String, keyProperty : String) : JdbcGeneratedKey = new JdbcGeneratedKey(keyColumn, keyProperty)
44 |
45 | }
46 |
47 | /** Base class to define a native SQL Key generator.
48 | * @tparam Type result type of the generated key.
49 | * == Sample code ==
50 | * {{{
51 | * keyGenerator = new SqlGeneratedKey[Long] {
52 | * keyProperty = "myId"
53 | * def xsql = "SELECT currval('my_sequence')"
54 | * }
55 | * }}}
56 | */
57 | abstract class SqlGeneratedKey[Type : Manifest] extends KeyGenerator {
58 |
59 | /** Any one of STATEMENT, PREPARED or CALLABLE.
60 | * This causes MyBatis to use Statement, PreparedStatement or CallableStatement respectively.
61 | * Default: PREPARED.
62 | */
63 | var statementType : StatementType = StatementType.PREPARED
64 |
65 | /** Property to be set. */
66 | var keyProperty : String = "id"
67 |
68 | /** Property to be set. */
69 | var keyColumn : String = null
70 |
71 | /** If true then this statement will be executed before the main statement. */
72 | var executeBefore : Boolean = false
73 |
74 | /** Returns the Class of the generated key. */
75 | val resultTypeClass = manifest[Type].runtimeClass
76 |
77 | /** Dynamic SQL CODE to be executed in order to obtain/generate the key
78 | * == Code sample ==
79 | * {{{
80 | * def xsql = "SELECT currval('my_sequence')"
81 | * }}}
82 | */
83 | def xsql : XSQL
84 |
85 | }
86 |
87 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/OptionTypeHandler.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | import org.apache.ibatis.`type`.{JdbcType => JdbcTypeEnum}
19 | import java.sql.CallableStatement
20 | import java.sql.PreparedStatement
21 | import java.sql.ResultSet
22 |
23 | /** Generic scala.Option[T] TypeHandler.
24 | * Wraps any TypeHandler[T] to support TypeHandler[Option[T]]
25 | * == Example ==
26 | * {{{
27 | * class OptionIntegerTypeHandler extends OptionTypeHandler(new IntegerTypeHandler())
28 | * }}}
29 | */
30 | class OptionTypeHandler[T](delegate : TypeHandler[T]) extends TypeHandler[Option[T]] {
31 |
32 | def setParameter(ps : PreparedStatement, i : Int, parameter : Option[T], jdbcType : JdbcTypeEnum) : Unit =
33 | parameter match {
34 | case None => delegate.setParameter(ps, i, null.asInstanceOf[T], jdbcType)
35 | case Some(v) => delegate.setParameter(ps, i, v, jdbcType)
36 | }
37 |
38 | def getResult(rs : ResultSet, columnName : String) : Option[T] =
39 | Option{ delegate.getResult(rs, columnName) }
40 |
41 | def getResult(rs : ResultSet, columnIndex : Int) : Option[T] =
42 | Option{ delegate.getResult(rs, columnIndex) }
43 |
44 | def getResult(cs : CallableStatement, columnIndex : Int) : Option[T] =
45 | Option{ delegate.getResult(cs, columnIndex) }
46 |
47 | }
48 |
49 | /** Builtin Option TypeHandlers */
50 | object TypeHandlers {
51 |
52 | import org.apache.ibatis.`type`._
53 |
54 | class OptBooleanTypeHandler extends OptionTypeHandler(new BooleanTypeHandler())
55 | class OptByteTypeHandler extends OptionTypeHandler(new ByteTypeHandler())
56 | class OptShortTypeHandler extends OptionTypeHandler(new ShortTypeHandler())
57 | class OptIntegerTypeHandler extends OptionTypeHandler(new IntegerTypeHandler())
58 | class OptLongTypeHandler extends OptionTypeHandler(new LongTypeHandler())
59 | class OptFloatTypeHandler extends OptionTypeHandler(new FloatTypeHandler())
60 | class OptDoubleTypeHandler extends OptionTypeHandler(new DoubleTypeHandler())
61 | class OptStringTypeHandler extends OptionTypeHandler(new StringTypeHandler())
62 | class OptClobTypeHandler extends OptionTypeHandler(new ClobTypeHandler())
63 | class OptBlobTypeHandler extends OptionTypeHandler(new BlobTypeHandler())
64 | class OptNStringTypeHandler extends OptionTypeHandler(new NStringTypeHandler())
65 | class OptNClobTypeHandler extends OptionTypeHandler(new NClobTypeHandler())
66 | class OptBigDecimalTypeHandler extends OptionTypeHandler(new BigDecimalTypeHandler())
67 | class OptDateTypeHandler extends OptionTypeHandler(new DateOnlyTypeHandler())
68 | class OptTimeTypeHandler extends OptionTypeHandler(new TimeOnlyTypeHandler())
69 | class OptTimestampTypeHandler extends OptionTypeHandler(new DateTypeHandler())
70 |
71 | }
72 |
73 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/Perform.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | import org.mybatis.scala.session.Session
19 |
20 | /** A mapped SQL UPDATE statement.
21 | * Basically this defines a function: (=> Int)
22 | */
23 | abstract class Perform
24 | extends Statement
25 | with SQLFunction0[Int] {
26 |
27 | def parameterTypeClass = classOf[Nothing]
28 |
29 | /** Exceutes the SQL Statement
30 | * @param s Implicit Session
31 | * @return number of affected rows
32 | */
33 | def apply()(implicit s : Session) : Int =
34 | execute { s.update(fqi.id) }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/ResultFlag.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | import org.apache.ibatis.mapping.{ResultFlag => ResultFlagEnum}
19 |
20 | private[scala] sealed trait ResultFlag {
21 | val unwrap : ResultFlagEnum
22 | }
23 |
24 | private[scala] object ResultFlag {
25 | val ID = new ResultFlag { val unwrap = ResultFlagEnum.ID }
26 | val CONSTRUCTOR = new ResultFlag { val unwrap = ResultFlagEnum.CONSTRUCTOR }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/ResultMapping.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | import org.apache.ibatis.`type`.{JdbcType => JdbcTypeEnum}
19 | import org.apache.ibatis.mapping.{ResultFlag => ResultFlagEnum}
20 | import java.util.{List => JList}
21 | import scala.jdk.CollectionConverters._
22 |
23 | private[scala] class ResultMapping (
24 | resultType : T[_],
25 | property_ : String,
26 | column_ : String,
27 | javaType : T[_],
28 | jdbcType : JdbcType,
29 | nestedSelect_ : Select,
30 | nestedResultMap_ : ResultMap[_],
31 | notNullColumn_ : String,
32 | columnPrefix_ : String,
33 | typeHandler : T[_ <: TypeHandler[_]],
34 | flags_ : Seq[ResultFlag] = Seq()
35 | ) {
36 |
37 | def resultTypeClass : Class[_] = resultType.unwrap
38 | def property : String = property_
39 | def column : String = column_
40 | def javaTypeClass : Class[_] = if (javaType == null || javaType.isVoid) null else javaType.unwrap
41 | def jdbcTypeEnum : JdbcTypeEnum = if (jdbcType == null || jdbcType == JdbcType.UNDEFINED) null else jdbcType.unwrap
42 | def nestedSelect : Select = nestedSelect_
43 | def nestedResultMap : ResultMap[_] = nestedResultMap_
44 | def notNullColumn : String = notNullColumn_
45 | def typeHandlerClass : Class[_ <: TypeHandler[_]] = if (typeHandler == null) null else typeHandler.unwrap
46 | def flags : JList[ResultFlagEnum] = (for (f <- flags_) yield f.unwrap).asJava
47 | def columnPrefix = columnPrefix_
48 | }
49 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/ResultSetType.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | import org.apache.ibatis.mapping.{ResultSetType => MBResultSetType}
19 |
20 | /** Wrapper of org.apache.ibatis.mapping.ResultSetType */
21 | sealed trait ResultSetType {
22 | val unwrap : MBResultSetType
23 | }
24 |
25 | /** Wrapper of org.apache.ibatis.mapping.ResultSetType values */
26 | object ResultSetType {
27 | val FORWARD_ONLY = new ResultSetType { val unwrap = MBResultSetType.FORWARD_ONLY }
28 | val SCROLL_INSENSITIVE = new ResultSetType { val unwrap = MBResultSetType.SCROLL_INSENSITIVE }
29 | val SCROLL_SENSITIVE = new ResultSetType { val unwrap = MBResultSetType.SCROLL_SENSITIVE }
30 | }
31 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/SQLFunction.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | import org.mybatis.scala.session.Session
19 | import org.mybatis.scala.session.ResultContext
20 |
21 | trait SQLFunction0[+B] {
22 | def apply()(implicit s : Session) : B
23 | }
24 |
25 | trait SQLFunction1[-A, +B] {
26 | def apply(a : A)(implicit s : Session) : B
27 | }
28 |
29 | trait SQLFunction2[-A, -B, +C] {
30 | def apply(a : A, b : B)(implicit s : Session) : C
31 | }
32 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/Statement.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | /** Abstract SQL statement mapping.
19 | * @version \$Revision$
20 | */
21 | trait Statement {
22 |
23 | /** Fully qualified identifier of the statement.
24 | * Autogenerated by the configuration space.
25 | */
26 | var fqi : FQI = null
27 |
28 | /** Any one of STATEMENT, PREPARED or CALLABLE.
29 | * This causes MyBatis to use Statement, PreparedStatement or CallableStatement respectively.
30 | * Default: PREPARED.
31 | */
32 | var statementType : StatementType = StatementType.PREPARED
33 |
34 | /** This sets the maximum time the driver will wait for the database to return from a request, before throwing an exception.
35 | * Default is unset (driver dependent).
36 | */
37 | var timeout : Int = -1
38 |
39 | /** Setting this to true will cause the cache to be flushed whenever this statement is called.
40 | * Default: false for select statements.
41 | */
42 | var flushCache : Boolean = true
43 |
44 | /** Vendor ID */
45 | var databaseId : String = null
46 |
47 | /** Scripting driver */
48 | var languageDriver = org.mybatis.scala.config.DefaultScriptingDriver
49 |
50 | /** Dynamic SQL definition, an xml node with root <xsql>
51 | * == Code sample ==
52 | * As simple as an static SQL:
53 | * {{{
54 | * def xsql = "SELECT * FROM mytable WHERE id = #{{id}}"
55 | * }}}
56 | *
57 | * Or using dynamic tags:
58 | * {{{
59 | * def xsql =
60 | *
61 | * SELECT *
62 | * FROM mytable
63 | *
64 | *
65 | * name like #{{name}}
66 | *
67 | *
68 | *
69 | * }}}
70 | */
71 | def xsql : XSQL
72 |
73 | /** Returns the Class of the input parameter. */
74 | def parameterTypeClass : Class[_]
75 |
76 | def execute[A](command : => A) : A = fqi match {
77 | case null =>
78 | throw new org.mybatis.scala.config.ConfigurationException("Unknown Statement " + this.getClass.getName)
79 | case _ =>
80 | command
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/StatementType.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | import org.apache.ibatis.mapping.{StatementType => MBStatementType}
19 |
20 | /** Wrapper of org.apache.ibatis.mapping.StatementType */
21 | sealed trait StatementType {
22 | val unwrap : MBStatementType
23 | }
24 |
25 | /** Wrapper of org.apache.ibatis.mapping.StatementType values */
26 | object StatementType {
27 | val STATEMENT = new StatementType { val unwrap = MBStatementType.STATEMENT }
28 | val PREPARED = new StatementType { val unwrap = MBStatementType.PREPARED }
29 | val CALLABLE = new StatementType { val unwrap = MBStatementType.CALLABLE }
30 | }
31 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/T.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | /** Utility to wrap types with reflection capabilities via Manifest.
19 | * Use T[MyType] instead of classOf[MyType]
20 | * @tparam t wrapped type
21 | */
22 | class T[t : Manifest] {
23 | val raw = manifest[t].runtimeClass.asInstanceOf[Class[Any]]
24 | val unwrap = manifest[t].runtimeClass.asInstanceOf[Class[t]]
25 | val isVoid = unwrap == java.lang.Void.TYPE
26 | }
27 |
28 | /** Syntactic sugar to support "T[MyType]" instead of new T[MyType] */
29 | object T {
30 | def apply[t : Manifest] = new T[t]
31 | }
32 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/Update.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | import org.mybatis.scala.session.Session
19 |
20 | /** A mapped SQL UPDATE statement.
21 | * Basically this defines a function: (Param => Int)
22 | * @tparam Param Input parameter type of the apply method.
23 | * @version \$Revision$
24 | */
25 | abstract class Update[Param : Manifest]
26 | extends Statement
27 | with SQLFunction1[Param,Int] {
28 |
29 | def parameterTypeClass = manifest[Param].runtimeClass
30 |
31 | /** Exceutes the SQL UPDATE Statement
32 | * @param param Input paramenter of the statement
33 | * @param s Implicit Session
34 | * @return number of affected rows
35 | */
36 | def apply(param : Param)(implicit s : Session) : Int =
37 | execute { s.update(fqi.id, param) }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/mapping/package.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala
17 |
18 | import org.apache.ibatis.`type`.{TypeHandler => MBTypeHandler}
19 | import scala.xml.Node
20 | import scala.language.implicitConversions
21 |
22 | /** Statement and result mapping classes.
23 | * == Code sample ==
24 | * Sample database
25 | * {{{
26 | *
27 | * CREATE TABLE people_group (
28 | * id_ serial,
29 | * name_ varchar(255),
30 | * primary key (id_)
31 | * );
32 | *
33 | * CREATE TABLE person (
34 | * id_ serial,
35 | * first_name_ varchar(255),
36 | * last_name_ varchar(255),
37 | * group_id_ integer not null,
38 | * primary key (id_),
39 | * foreign key (group_id_) references people_group(id_)
40 | * );
41 | *
42 | * CREATE TABLE contact_info (
43 | * id_ serial,
44 | * owner_id_ integer not null,
45 | * street_address_ varchar(255),
46 | * phone_number_ varchar(20),
47 | * primary key (id_),
48 | * foreign key (owner_id_) references person(id_)
49 | * );
50 | *
51 | * }}}
52 | *
53 | * Sample Model
54 | * {{{
55 | *
56 | * // Simple Group POJO
57 | * class Group {
58 | * var id : Int = _
59 | * var name : String = _
60 | * }
61 | *
62 | * // Simple ContactInfo POJO
63 | * class ContactInfo {
64 | * var id : Int = _
65 | * var address : String = _
66 | * var phone : String = _
67 | * }
68 | *
69 | * // Simple Person POJO
70 | * class Person {
71 | * var id : Int = _
72 | * var firstName : String = _
73 | * var lastName : String = _
74 | * var group : Group = _
75 | * var contact : java.util.List[ContactInfo] = _
76 | * }
77 | *
78 | * }}}
79 | *
80 | * Sample Mapping
81 | * {{{
82 | *
83 | * // Define the result mapping
84 | * resultMap = new ResultMap[Person] {
85 | *
86 | * id(property="id", column="id_")
87 | * result(property="firstName", column="first_name_")
88 | * result(property="lastName", column="last_name_")
89 | *
90 | * association[Group] (property="group", column="group_id_",
91 | * resultMap= new ResultMap[Group] {
92 | * id(property="id", column="group_id_")
93 | * result(property="name", column="group_name_")
94 | * }
95 | * )
96 | *
97 | * collection[ContactInfo] (property="contact", column="cinfo_id_",
98 | * resultMap= new ResultMap[ContactInfo] {
99 | * id(property="id", column="cinfo_id_")
100 | * result(property="address", column="street_address_")
101 | * result(property="phone", column="phone_number_")
102 | * }
103 | * )
104 | * }
105 | * }}}
106 | */
107 | package object mapping {
108 |
109 | /** Alias of [[org.apache.ibatis.type.TypeHandler]] */
110 | type TypeHandler[T] = MBTypeHandler[T]
111 |
112 | /** Alias of [[scala.xml.Node]] */
113 | type XSQL = Node
114 |
115 | /** Implicit conversion from String to XSQL */
116 | implicit def string_to_xsql( s : String ) : XSQL = {s}
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/session/ExecutorType.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.session
17 |
18 | import org.apache.ibatis.session.{ExecutorType => ET}
19 |
20 | sealed trait ExecutorType {
21 | val unwrap : ET
22 | }
23 |
24 | object ExecutorType {
25 | val SIMPLE = new ExecutorType { val unwrap = ET.SIMPLE }
26 | val REUSE = new ExecutorType { val unwrap = ET.REUSE }
27 | val BATCH = new ExecutorType { val unwrap = ET.BATCH }
28 | }
29 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/session/ResultHandlerDelegator.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.session
17 |
18 | class ResultHandlerDelegator[T](callback : ResultContext[_ <: T] => Unit) extends ResultHandler[T] {
19 | def handleResult(context : ResultContext[_ <: T]) : Unit = callback(context)
20 | }
21 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/session/RowBounds.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.session
17 |
18 | /** Wrapper of [[org.apache.ibatis.session.RowBounds]]
19 | */
20 | case class RowBounds(val offset: Int, val limit: Int) {
21 | val unwrap = new org.apache.ibatis.session.RowBounds(offset, limit)
22 | }
23 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/session/Session.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.session
17 |
18 | import org.apache.ibatis.session.SqlSession
19 | import scala.jdk.CollectionConverters._
20 | import scala.collection.mutable._
21 |
22 | /** SqlSession Wrapper.
23 | * You rarely use this class in an explicit manner.
24 | * == Usage ==
25 | * Used implicitly by mapped statements:
26 | * {{{
27 | * dbcontext.transaction( implicit session =>
28 | * MyDAO.findAll()
29 | * )
30 | * }}}
31 | * @version \$Revision$
32 | */
33 | class Session(sqls : SqlSession) {
34 |
35 | def selectOne[Result](statement : String) : Result = {
36 | sqls.selectOne(statement).asInstanceOf[Result]
37 | }
38 |
39 | def selectOne[Param,Result](statement : String, parameter : Param) : Result = {
40 | sqls.selectOne(statement, parameter).asInstanceOf[Result]
41 | }
42 |
43 | def selectList[Result](statement : String) : Seq[Result] = {
44 | sqls.selectList(statement).asScala.toBuffer
45 | }
46 |
47 | def selectList[Param,Result](statement : String, parameter : Param) : Seq[Result] = {
48 | sqls.selectList(statement, parameter).asScala.toBuffer
49 | }
50 |
51 | def selectList[Param,Result](statement : String, parameter : Param, rowBounds : RowBounds) : Seq[Result] = {
52 | sqls.selectList(statement, parameter, rowBounds.unwrap).asScala.toBuffer
53 | }
54 |
55 | def selectMap[Key,Value](statement : String, mapKey : String) : Map[Key,Value] = {
56 | sqls.selectMap[Key,Value](statement, mapKey).asScala
57 | }
58 |
59 | def selectMap[Param,Key,Value](statement : String, parameter : Param, mapKey : String) : Map[Key,Value] = {
60 | sqls.selectMap[Key,Value](statement, parameter, mapKey).asScala
61 | }
62 |
63 | def selectMap[Param,Key,Value](statement : String, parameter : Param, mapKey : String, rowBounds : RowBounds) : Map[Key,Value] = {
64 | sqls.selectMap[Key,Value](statement, parameter, mapKey, rowBounds.unwrap).asScala
65 | }
66 |
67 | def select[Param, Res](statement : String, parameter : Param, handler : ResultHandler[Res]) : Unit = {
68 | sqls.select(statement, parameter, handler)
69 | }
70 |
71 | def select[T](statement : String, handler : ResultHandler[T]) : Unit = {
72 | sqls.select(statement, handler)
73 | }
74 |
75 | def select[Param, Res](statement : String, parameter : Param, rowBounds : RowBounds, handler : ResultHandler[Res]) : Unit = {
76 | sqls.select(statement, parameter, rowBounds.unwrap, handler)
77 | }
78 |
79 | def insert(statement : String) : Int = {
80 | sqls.insert(statement)
81 | }
82 |
83 | def insert[Param](statement : String, parameter : Param) : Int = {
84 | sqls.insert(statement, parameter)
85 | }
86 |
87 | def update(statement : String) : Int = {
88 | sqls.update(statement)
89 | }
90 |
91 | def update[Param](statement : String, parameter : Param) : Int = {
92 | sqls.update(statement, parameter)
93 | }
94 |
95 | def delete(statement : String) : Int = {
96 | sqls.delete(statement)
97 | }
98 |
99 | def delete[Param](statement : String, parameter : Param) : Int = {
100 | sqls.delete(statement, parameter)
101 | }
102 |
103 | def commit() : Unit = sqls.commit
104 |
105 | def commit(force : Boolean) : Unit = sqls.commit(force)
106 |
107 | def rollback() : Unit = sqls.rollback
108 |
109 | def rollback(force : Boolean) : Unit = sqls.rollback(force)
110 |
111 | def clearCache() : Unit = sqls.clearCache
112 |
113 | def flushStatements() : Seq[BatchResult] = sqls.flushStatements.asScala
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/session/SessionManager.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.session
17 |
18 | import org.apache.ibatis.logging.LogFactory
19 | import SessionManager.log
20 | import org.apache.ibatis.session.{SqlSession, SqlSessionFactory}
21 |
22 | /** Session lifecycle manager.
23 | * Manages the lifecycle of the Session
24 | * == Usage ==
25 | * - Rollback only
26 | * {{{
27 | * sessionManager.readOnly { implicit session =>
28 | * // Your code ...
29 | * // Always rollback at the end automatically.
30 | * }
31 | * }}}
32 | * - Direct transaction
33 | * {{{
34 | * sessionManager.transaction { implicit session =>
35 | * // Your code ...
36 | * // Always commit at the end if no exceptions are thrown, else rollback.
37 | * }
38 | * }}}
39 | * - External transaction
40 | * {{{
41 | * sessionManager.managed { implicit session =>
42 | * // Your code ...
43 | * // Never commit or rollback automatically.
44 | * // The transaction can be managed externally or manually.
45 | * }
46 | * }}}
47 | *
48 | * @version \$Revision$
49 | */
50 | sealed class SessionManager(factory : SqlSessionFactory) {
51 |
52 | type Callback[T] = (Session) => T
53 | type CloseSessionHook = (SqlSession) => Unit
54 |
55 | private var closeSession : CloseSessionHook = {(s : SqlSession) => s.close}
56 |
57 | def closeSessionHook(hook : CloseSessionHook) = {
58 | closeSession = hook
59 | }
60 |
61 | /** Executes the callback within a new session and rollback at the end. */
62 | def readOnly[T](
63 | executorType : ExecutorType = ExecutorType.SIMPLE,
64 | level: TransactionIsolationLevel = TransactionIsolationLevel.UNDEFINED)(callback : Callback[T]) : T = {
65 | val sqlSession = factory.openSession(executorType.unwrap, level.unwrap)
66 | try {
67 | val ret = callback(new Session(sqlSession))
68 | sqlSession.rollback
69 | ret
70 | }
71 | finally {
72 | closeSession(sqlSession)
73 | }
74 | }
75 |
76 | /** Executes the callback within a new session and rollback at the end. */
77 | def readOnly[T](callback : Callback[T]) : T = readOnly[T]()(callback)
78 |
79 | private def transaction[T](sqlSession : SqlSession)(callback : Callback[T]) : T = {
80 | try {
81 | val t = callback(new Session(sqlSession))
82 | sqlSession.commit
83 | t
84 | }
85 | catch {
86 | case e : Throwable =>
87 | try {
88 | sqlSession.rollback
89 | }
90 | catch {
91 | case e2 : Exception =>
92 | // Ignore. There's nothing that can be done at this point.
93 | // Throw the original exception as that's the one that matters.
94 | log.warn("Unexpected exception on rolling back transaction. Cause: " + e2)
95 | throw e
96 | }
97 | throw e
98 | }
99 | finally {
100 | closeSession(sqlSession)
101 | }
102 | }
103 |
104 | /** Executes the callback within a new transaction and commit at the end, automatically calls rollback if any exception. */
105 | def transaction[T](executorType : ExecutorType, level : TransactionIsolationLevel)(callback : Callback[T]) : T =
106 | transaction[T](factory.openSession(executorType.unwrap, level.unwrap))(callback)
107 |
108 | /** Executes the callback within a new transaction and commit at the end, automatically calls rollback if any exception. */
109 | def transaction[T](executorType : ExecutorType)(callback : Callback[T]) : T =
110 | transaction[T](factory.openSession(executorType.unwrap))(callback)
111 |
112 | /** Executes the callback within a new transaction and commit at the end, automatically calls rollback if any exception. */
113 | def transaction[T](level : TransactionIsolationLevel)(callback : Callback[T]) : T =
114 | transaction[T](factory.openSession(level.unwrap))(callback)
115 |
116 | /** Executes the callback within a new transaction and commit at the end, automatically calls rollback if any exception. */
117 | def transaction[T](executorType : ExecutorType, autoCommit : Boolean)(callback : Callback[T]) : T =
118 | transaction[T](factory.openSession(executorType.unwrap, autoCommit))(callback)
119 |
120 | /** Executes the callback within a new transaction and commit at the end, automatically calls rollback if any exception. */
121 | def transaction[T](autoCommit : Boolean)(callback : Callback[T]) : T =
122 | transaction[T](factory.openSession(autoCommit))(callback)
123 |
124 | /** Executes the callback within a new transaction and commit at the end, automatically calls rollback if any exception. */
125 | def transaction[T](callback : Callback[T]) : T =
126 | transaction[T](ExecutorType.SIMPLE, TransactionIsolationLevel.UNDEFINED)(callback)
127 |
128 | /** Executes the callback within a new session. Does not call any transaction method. */
129 | def managed[T](executorType : ExecutorType)(callback : Callback[T]) : T = {
130 | val sqlSession = factory.openSession(executorType.unwrap)
131 | try {
132 | callback(new Session(sqlSession))
133 | }
134 | finally {
135 | closeSession(sqlSession)
136 | }
137 | }
138 |
139 | /** Executes the callback within a new session. Does not call any transaction method. */
140 | def managed[T](callback : Callback[T]) : T = managed[T](ExecutorType.SIMPLE)(callback)
141 |
142 | }
143 |
144 | object SessionManager {
145 | val log = LogFactory.getLog(classOf[SessionManager])
146 | }
147 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/session/TransactionIsolationLevel.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.session
17 |
18 | import org.apache.ibatis.session.{TransactionIsolationLevel => TIL}
19 |
20 | sealed trait TransactionIsolationLevel {
21 | val unwrap : TIL
22 | }
23 |
24 | object TransactionIsolationLevel {
25 | val NONE = new TransactionIsolationLevel { val unwrap = TIL.NONE }
26 | val READ_COMMITTED = new TransactionIsolationLevel { val unwrap = TIL.READ_COMMITTED }
27 | val READ_UNCOMMITTED = new TransactionIsolationLevel { val unwrap = TIL.READ_UNCOMMITTED }
28 | val REPEATABLE_READ = new TransactionIsolationLevel { val unwrap = TIL.REPEATABLE_READ }
29 | val SERIALIZABLE = new TransactionIsolationLevel { val unwrap = TIL.SERIALIZABLE }
30 | val UNDEFINED = new TransactionIsolationLevel { val unwrap = null }
31 | }
32 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/main/scala/org/mybatis/scala/session/package.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala
17 |
18 | import org.apache.ibatis.session.{ResultHandler => MBResultHandler, ResultContext => MBResultContext}
19 | import org.apache.ibatis.session.{RowBounds => MBRowBounds}
20 |
21 | /** Session Management classes.
22 | * Provides classes needed to execute the mapped statements.
23 | * == Basic usage ==
24 | * Usual steps are:
25 | * - Obtain a SessionManager instance from a Configuration
26 | * - Call any of the lifecycle methods of the SessionManager passing the code to be executed.
27 | * == Code sample ==
28 | * {{{
29 | * val db = Config.persistenceContext
30 | * db.transaction { implicit session =>
31 | * MyDAO.insert(...)
32 | * MyDAO.update(...)
33 | * // etc...
34 | * }
35 | * }}}
36 | * @version \$Revision$
37 | */
38 | package object session {
39 |
40 | /** Alias of [[org.apache.ibatis.session.ResultHandler]] */
41 | type ResultHandler[T] = MBResultHandler[T]
42 |
43 | /** Alias of [[org.apache.ibatis.session.ResultContext]] */
44 | type ResultContext[T] = MBResultContext[T]
45 |
46 | /** Alias of [[org.apache.ibatis.executor.BatchResult]] */
47 | type BatchResult = org.apache.ibatis.executor.BatchResult
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/site/site.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
22 |
23 |
24 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/site/xdoc/cache.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
23 |
24 |
25 | MyBatis Scala API > Cache
26 | The MyBatis Team
27 | $Date$
28 |
29 |
30 |
31 |
32 |
This org.mybatis.scala.cache package provides some aliases to core MyBatis Cache types.
33 |
See the API docs for more info about caching.
34 |
35 | The only thing you have to do is call the cache method of the space,
36 | all parameters are optional, and by default they are set to sensible values.
37 |
38 |
40 |
41 | space cache(eviction=FIFO)
42 |
43 | space += findPeople
44 | space ++= PersonDAO
45 | space ++= Seq(deletePerson, updatePerson, ...)
46 |
47 | ...
48 |
49 | }]]>
50 |
51 | Notice Call the cache method earliest in the space block.
52 |
33 | The main responsibility of the org.mybatis.scala.config package is to provide classes to load the
34 | main configurations like plugins, datasource and transaction services, etc...
35 |
36 |
37 | Because this API is code centric and type safe, you don't need typeAliases. When you need to reference a type 'Type'
38 | just use T[Type].
39 |
40 |
41 | Your main configuration is specified in a small XML file as usual:
42 | http://mybatis.org/dtd/mybatis-3-config.dtd
43 | But you don't need to specify typeAliases nor mappers. Look at the mybatis core users guide for more details.
44 |
35 | MyBatis is one of the best advanced persistence frameworks available for java, it can be
36 | used with Scala too, but the main API is Java centric. This sub-project is to provide a
37 | more scala friendly API, it does not uses any annotation, and all SQL (static and dynamic)
38 | can be declared directly and elegantly in your scala code.
39 |
40 |
41 |
42 |
43 | The API is structured in four main packages, each package contains types and objects related to a specific
44 | concern. They are Configuration, Mapping, Session and Cache.
45 |
33 | org.mybatis.scala.mapping is the main package of the API, this provides all idioms needed to
34 | declare ResultMaps and Statements.
35 |
36 |
37 |
38 | To declare a ResultMap, just extend ResultMap[T] and call its mapping methods in its main constructor.
39 |
43 |
44 | You can define contructor args, properties, associations, collections, discriminators, ...
45 | Look at the scaladoc for furter details of ResultMap construction.
46 |
47 |
48 | You can declare your ResultMaps wherever you want, you will reference them later when you declare
49 | your mapped statements.
50 |
51 |
52 |
53 |
54 |
55 | There are four types of Mapped Statements as you know: Select, Insert, Update and Delete. But Select is
56 | a special case with three subtypes: SelectOne, SelectList and SelectMap.
57 |
58 |
59 | To define/declare a mapped statement you just have to extend one of the Statement types and set the
60 | desired properties.
61 |
62 |
63 |
64 |
65 |
66 | For example, if you want to select a User by its id:
67 |
68 | SELECT * from user WHERE id = {"id"?}
70 | }
71 |
72 | // this is also valid
73 | val findUserById = new SelectOneBy[Int,User] {
74 | def xsql =
75 |
76 | SELECT *
77 | FROM user
78 | WHERE id = {"id"?}
79 |
80 | }]]>
81 |
82 | You can also select a list of users filtered by its name
83 |
84 |
87 | SELECT *
88 | FROM user
89 | WHERE name LIKE {"name"?}
90 |
91 | }]]>
92 |
93 |
94 |
95 |
96 | The same applies to these statement types, just extends and define.
97 |
111 | All the mapping code is disconnected, so you can put it in a static initializer (scala object)
112 | or wherever you want.
113 |
114 |
115 |
116 |
117 | There are two syntaxes: Textual notation and Scala notation, lets see
118 |
119 |
120 |
Textual notation
121 |
122 | The former mybatis notation can be used here escaping '{' and '}' chars.
123 |
124 | SELECT *
125 | FROM ....
126 | WHERE field = #{{param}}
127 |
128 |
129 | SELECT *
130 | FROM ....
131 | WHERE field = #{{param, jdbcType=VARCHAR, mode=IN}}
132 |
133 | In this case VARCHAR and IN are just strings that will be parsed at runtime.
134 |
135 |
136 |
137 |
Scala notation
138 |
139 | You can import org.mybatis.scala.mapping.Binding._ and use the ? function. It provides
140 | type safety on binding attributes.
141 |
142 | SELECT *
143 | FROM ....
144 | WHERE field = {"param"?}
145 |
146 |
147 | SELECT *
148 | FROM ....
149 | WHERE field = {? ("param", jdbcType=JdbcType.VARCHAR, mode=ModeIN, typeHandler=T[CustomTHandler]) }
150 |
151 | In this case JdbcType.VARCHAR and ModeIN are true object references and CustomTHandler is a type reference, so they will be checked at compile time.
152 |
153 |
33 | The org.mybatis.scala.session package provides service classes to execute your mapped statements
34 | against a database connection.
35 |
36 |
37 | The main class in this package is SessionManager which its instances are provided by the configuration
38 | object. You should have only one instance of the SessionManager in your application. Just like
39 | SqlSessionFactory. This class is disconnected, it only create connections when you call a connected method.
40 |
41 |
42 |
43 |
44 | This method opens a connection, executes a code block, calls rollback and close.
45 |
46 |
47 |
48 | val list = findUsers("a%")
49 | for (user <- list) {
50 | // Do something with user
51 | }
52 |
53 | }]]>
54 |
55 |
56 |
57 |
58 | This method opens a connection, executes a code block, and calls commit if no exceptions are thrown,
59 | else calls rollback, then close.
60 |
75 | This method opens a connection, executes a code block and closes the connection. The Transaction lifecycle
76 | must be managed externally by the container or manually by the developer.
77 |
78 |
79 | val user = new User
80 | user.name = "John"
81 | user.username = "john1"
82 | user.password = "12345"
83 |
84 | insertNewUser(user)
85 |
86 | }]]>
87 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/test/resources/mybatis.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/test/scala/org/mybatis/scala/Database.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala
17 |
18 | import org.mybatis.scala.config.Configuration
19 | import org.mybatis.scala.infrastructure.{BlogRepository, UserRepository}
20 |
21 | /**
22 | * Provides [[org.mybatis.scala.session.SessionManager]] instances.
23 | */
24 | object Database {
25 | val config = Configuration("mybatis.xml")
26 |
27 | config.addSpace("test") { space =>
28 | space ++= DatabaseSchema
29 | space ++= UserRepository
30 | space ++= BlogRepository
31 | }
32 |
33 | /**
34 | * A configuration intended to be used for simple tests.
35 | */
36 | lazy val default = config.createPersistenceContext
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/test/scala/org/mybatis/scala/DatabaseSchema.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala
17 |
18 | import org.mybatis.scala.mapping._
19 | import org.mybatis.scala.session.Session
20 |
21 | /**
22 | * This object provides the feature of creating database tables.
23 | */
24 | object DatabaseSchema {
25 |
26 | /**
27 | * Prepares tables for testing.
28 | * @param session the session object to connect to databases.
29 | */
30 | def prepare(implicit session: Session): Unit = {
31 | bind foreach {
32 | case perform: Perform => perform()
33 | }
34 | }
35 |
36 | /**
37 | * Creates a table containing user data.
38 | */
39 | val createUserTable = new Perform {
40 | def xsql =
41 |
42 | CREATE TABLE IF NOT EXISTS user(
43 | id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL,
44 | name VARCHAR(64) NOT NULL,
45 | email VARCHAR(256) NOT NULL,
46 | PRIMARY KEY (id)
47 | )
48 |
49 | }
50 |
51 | /**
52 | * Creates a table containing blog data.
53 | */
54 | val createBlogTable = new Perform {
55 | def xsql =
56 |
57 | CREATE TABLE IF NOT EXISTS blog(
58 | id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL,
59 | title VARCHAR(128) NOT NULL,
60 | PRIMARY KEY (id)
61 | )
62 |
63 | }
64 |
65 | /**
66 | * Creates a table containing entries posted to blogs.
67 | */
68 | val createEntryTable = new Perform {
69 | def xsql =
70 |
71 | CREATE TABLE IF NOT EXISTS entry(
72 | id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL,
73 | body BLOB NOT NULL,
74 | blog_id INTEGER NOT NULL,
75 | PRIMARY KEY (id)
76 | )
77 |
78 | }
79 |
80 | def bind = Seq(createUserTable, createBlogTable, createEntryTable)
81 | }
82 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/test/scala/org/mybatis/scala/DatabaseSupport.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala
17 |
18 | import org.mybatis.scala.config.Configuration
19 | import org.mybatis.scala.session.{Session, SessionManager}
20 | import org.mybatis.scala.infrastructure.{BlogRepository, UserRepository}
21 |
22 | /**
23 | * This trait provides the feature of using databases in test cases.
24 | */
25 | trait DatabaseSupport {
26 | /**
27 | * Executes a callback function provided by a argument of this function within a read-only database transaction.
28 | * @param block the callback function to be executed within a database transaction.
29 | */
30 | def withReadOnly(db: SessionManager)(block: Session => Unit): Unit = {
31 | db.readOnly { implicit session =>
32 | DatabaseSchema.prepare
33 | block(session)
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/test/scala/org/mybatis/scala/domain/Blog.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.domain
17 |
18 | case class Blog(var title: String) {
19 | var id: Int = _
20 | var entries: Seq[Entry] = Seq.empty
21 | }
22 |
23 | object Blog {
24 | def apply(id: Int, title: String): Blog = {
25 | val blog = Blog(title)
26 | blog.id = id
27 | blog
28 | }
29 | }
30 |
31 | case class Entry(var body: String) {
32 | var id: Int = _
33 | }
34 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/test/scala/org/mybatis/scala/domain/User.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.domain
17 |
18 | /**
19 | * This class provides information about an user.
20 | * @param id the identity to specify a user
21 | * @param name the user name
22 | * @param email the email address
23 | */
24 | case class User(var id: Int, var name: String, var email: String)
25 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/test/scala/org/mybatis/scala/infrastructure/BlogRepository.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.infrastructure
17 |
18 | import org.mybatis.scala.mapping._
19 | import org.mybatis.scala.mapping.Binding._
20 | import org.mybatis.scala.domain.{Entry, Blog}
21 | import org.mybatis.scala.session.Session
22 | import scala.language.postfixOps
23 |
24 | object BlogRepository {
25 | lazy val blogResultMap = new ResultMap[Blog] {
26 | id(column = "blog_id", property = "id")
27 | arg(column = "blog_title", javaType = T[String])
28 | collection(property = "entries", resultMap = entryResultMap)
29 | }
30 |
31 | lazy val entryResultMap = new ResultMap[Entry] {
32 | id(column = "entry_id", property = "id")
33 | arg(column = "entry_body", javaType = T[String])
34 | }
35 |
36 | val findFirst = new SelectOne[Blog] {
37 | resultMap = blogResultMap
38 | def xsql =
39 |
40 | SELECT
41 | b.id as blog_id,
42 | b.title as blog_title,
43 | e.id as entry_id,
44 | e.body as entry_body
45 | FROM
46 | blog b
47 | LEFT OUTER JOIN
48 | entry e
49 | ON
50 | e.blog_id = b.id
51 | ORDER BY b.id
52 | LIMIT 1
53 |
54 | }
55 |
56 | val findById = new SelectOneBy[Int, Blog] {
57 | resultMap = blogResultMap
58 | def xsql =
59 |
60 | SELECT
61 | b.id as blog_id,
62 | b.title as blog_title,
63 | e.id as entry_id,
64 | e.body as entry_body
65 | FROM
66 | blog b
67 | LEFT OUTER JOIN
68 | entry e
69 | ON
70 | e.blog_id = b.id
71 | WHERE
72 | b.id = {"id" ?}
73 |
74 | }
75 |
76 | val findAll = new SelectList[Blog] {
77 | resultMap = blogResultMap
78 | def xsql =
79 |
80 | SELECT
81 | b.id as blog_id,
82 | b.title as blog_title,
83 | e.id as entry_id,
84 | e.body as entry_body
85 | FROM
86 | blog b
87 | LEFT OUTER JOIN
88 | entry e
89 | ON
90 | e.blog_id = b.id
91 |
92 | }
93 |
94 | val findAllByTitle = new SelectListBy[String, Blog] {
95 | resultMap = blogResultMap
96 | def xsql =
97 |
98 | SELECT
99 | b.id as blog_id,
100 | b.title as blog_title,
101 | e.id as entry_id,
102 | e.body as entry_body
103 | FROM
104 | blog b
105 | LEFT OUTER JOIN
106 | entry e
107 | ON
108 | e.blog_id = b.id
109 | WHERE
110 | b.title = {"title" ?}
111 |
112 | }
113 |
114 | val findAllWithPage = new SelectListPage[Blog] {
115 | resultMap = blogResultMap
116 | def xsql =
117 |
118 | SELECT
119 | b.id as blog_id,
120 | b.title as blog_title,
121 | e.id as entry_id,
122 | e.body as entry_body
123 | FROM
124 | blog b
125 | LEFT OUTER JOIN
126 | entry e
127 | ON
128 | e.blog_id = b.id
129 |
130 | }
131 |
132 | val findAllByTitleWithPage = new SelectListPageBy[String, Blog] {
133 | resultMap = blogResultMap
134 | def xsql =
135 |
136 | SELECT
137 | b.id as blog_id,
138 | b.title as blog_title,
139 | e.id as entry_id,
140 | e.body as entry_body
141 | FROM
142 | blog b
143 | LEFT OUTER JOIN
144 | entry e
145 | ON
146 | e.blog_id = b.id
147 | WHERE
148 | b.title = {"title" ?}
149 |
150 | }
151 |
152 | val findMapByTitle = new SelectMap[String, Blog](mapKey = "title") {
153 | resultMap = blogResultMap
154 | def xsql =
155 |
156 | SELECT
157 | b.id as blog_id,
158 | b.title as blog_title,
159 | e.id as entry_id,
160 | e.body as entry_body
161 | FROM
162 | blog b
163 | LEFT OUTER JOIN
164 | entry e
165 | ON
166 | e.blog_id = b.id
167 |
168 | }
169 |
170 | val findMapByTitleWithPage = new SelectMapPage[String, Blog](mapKey = "title") {
171 | resultMap = blogResultMap
172 | def xsql =
173 |
174 | SELECT
175 | b.id as blog_id,
176 | b.title as blog_title,
177 | e.id as entry_id,
178 | e.body as entry_body
179 | FROM
180 | blog b
181 | LEFT OUTER JOIN
182 | entry e
183 | ON
184 | e.blog_id = b.id
185 |
186 | }
187 |
188 | val findMapByTitleWithCondition = new SelectMapBy[String, String, Blog](mapKey = "title") {
189 | resultMap = blogResultMap
190 | def xsql =
191 |
192 | SELECT
193 | b.id as blog_id,
194 | b.title as blog_title,
195 | e.id as entry_id,
196 | e.body as entry_body
197 | FROM
198 | blog b
199 | LEFT OUTER JOIN
200 | entry e
201 | ON
202 | e.blog_id = b.id
203 | WHERE
204 | b.title LIKE {"title" ?}
205 |
206 | }
207 |
208 | val findMapByTitleWithConditionAndPage = new SelectMapPageBy[String, String, Blog](mapKey = "title") {
209 | resultMap = blogResultMap
210 | def xsql =
211 |
212 | SELECT
213 | b.id as blog_id,
214 | b.title as blog_title,
215 | e.id as entry_id,
216 | e.body as entry_body
217 | FROM
218 | blog b
219 | LEFT OUTER JOIN
220 | entry e
221 | ON
222 | e.blog_id = b.id
223 | WHERE
224 | b.title LIKE {"title" ?}
225 | ORDER BY b.id ASC
226 |
227 | }
228 |
229 | val insertBlog = new Insert[Blog] {
230 | keyGenerator = JdbcGeneratedKey(null, "id")
231 | def xsql = INSERT INTO blog(title) VALUES({"title" ?})
232 | }
233 |
234 | val insertEntry = new Insert[Entry] {
235 | keyGenerator = JdbcGeneratedKey(null, "id")
236 | def xsql = INSERT INTO entry(body) VALUES({"body" ?})
237 | }
238 |
239 | def create(blog: Blog)(implicit session: Session) = {
240 | insertBlog(blog)
241 | blog.entries.foreach(e => insertEntry(e))
242 | }
243 |
244 | def bind = Seq(
245 | insertBlog, insertEntry, findById, findAll, findAllByTitle,
246 | findAllWithPage, findAllByTitleWithPage, findFirst, findMapByTitle,
247 | findMapByTitleWithCondition, findMapByTitleWithPage, findMapByTitleWithConditionAndPage
248 | )
249 | }
250 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/test/scala/org/mybatis/scala/infrastructure/UserRepository.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.infrastructure
17 |
18 | import org.mybatis.scala.domain.User
19 | import org.mybatis.scala.mapping._
20 | import org.mybatis.scala.mapping.Binding._
21 | import scala.language.postfixOps
22 |
23 | object UserRepository {
24 | val defaultResultMap = new ResultMap[User] {
25 | idArg(column = "id", javaType = T[Int])
26 | arg(column = "name", javaType = T[String])
27 | arg(column = "email", javaType = T[String])
28 | }
29 |
30 | val create = new Insert[User] {
31 | keyGenerator = JdbcGeneratedKey(null, "id")
32 | def xsql = INSERT INTO user(name, email) VALUES({"name" ?}, {"email" ?})
33 | }
34 |
35 | val createFromTuple2 = new Insert[(String, String)] {
36 | def xsql = INSERT INTO user(name, email) VALUES({"_1" ?}, {"_2" ?})
37 | }
38 |
39 | val findById = new SelectOneBy[Int, User] {
40 | resultMap = defaultResultMap
41 | def xsql = SELECT * FROM user WHERE id = {"id" ?}
42 | }
43 |
44 | val findAll = new SelectList[User] {
45 | resultMap = defaultResultMap
46 | def xsql = SELECT * FROM user
47 | }
48 |
49 | val lastInsertId = new SelectOne[Int] {
50 | def xsql = CALL IDENTITY()
51 | }
52 |
53 | def bind = Seq(create, createFromTuple2, findById, findAll, lastInsertId)
54 | }
55 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/test/scala/org/mybatis/scala/mapping/InsertSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | import org.mybatis.scala.{Database, DatabaseSupport}
19 | import org.mybatis.scala.domain.User
20 | import org.mybatis.scala.infrastructure.UserRepository
21 | import org.scalatest._
22 | import org.scalatest.funspec.AnyFunSpec
23 | import org.scalatest.matchers.should.Matchers
24 |
25 | /**
26 | * The specification for [[Insert]].
27 | */
28 | class InsertSpec extends AnyFunSpec with Matchers with DatabaseSupport {
29 | describe("A Insert") {
30 | it("should insert User into user table") {
31 | withReadOnly(Database.default) { implicit session =>
32 | val expected = User(0, "test", "example@example.com")
33 |
34 | UserRepository.create(expected)
35 |
36 | UserRepository.findById(expected.id) should equal (Some(expected))
37 | }
38 | }
39 |
40 | it("should insert User into user table from Tuple2") {
41 | withReadOnly(Database.default) { implicit session =>
42 | val name = "test_user"
43 | val email = "example@example.com"
44 |
45 | UserRepository.createFromTuple2((name, email))
46 |
47 | for {
48 | id <- UserRepository.lastInsertId()
49 | actual <- UserRepository.findById(id)
50 | } yield {
51 | val expected = User(id, name, email)
52 | actual should equal (expected)
53 | Some(expected)
54 | } getOrElse fail("unable to get last insert id.")
55 | }
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/mybatis-scala-core/src/test/scala/org/mybatis/scala/mapping/StatementSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.mapping
17 |
18 | import org.mybatis.scala.config.ConfigurationException
19 | import org.scalatest._
20 | import scala.util.control.NonFatal
21 | import org.scalatest.funspec.AnyFunSpec
22 | import org.scalatest.matchers.should.Matchers
23 |
24 | /**
25 | * The specification for [[Statement]].
26 | */
27 | class StatementSpec extends AnyFunSpec with Matchers {
28 | val simpleStatement = new Statement {
29 | override def parameterTypeClass: Class[_] = classOf[Unit]
30 | override def xsql: XSQL = SELECT 1
31 | }
32 |
33 | describe("A Statement") {
34 | it("should throw an exception if FQI isn't set") {
35 | intercept[ConfigurationException] {
36 | simpleStatement.execute {
37 | fail("should not come here")
38 | }
39 | }
40 | }
41 |
42 | it("should not throw any exception if FQI is set") {
43 | try {
44 | simpleStatement.fqi = new FQI("databases", "local")
45 | simpleStatement.execute {}
46 | } catch {
47 | case NonFatal(e) => fail(e.getMessage)
48 | }
49 | }
50 | it("should return XSQL") {
51 | simpleStatement.xsql should equal (SELECT 1)
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/LICENSE_HEADER:
--------------------------------------------------------------------------------
1 | Copyright 2011-2015 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 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/format.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 | 4.0.0
21 |
22 |
23 | org.mybatis.scala
24 | mybatis-scala-parent_2.13
25 | 1.3.2-SNAPSHOT
26 |
27 |
28 | mybatis-scala-samples_2.13
29 | jar
30 | mybatis-scala-samples
31 |
32 |
33 | scm:git:ssh://github.com/mybatis/scala.git
34 | scm:git:ssh://git@github.com/mybatis/scala.git
35 | HEAD
36 | http://github.com/mybatis/scala
37 |
38 |
39 |
40 |
41 | org.mybatis.scala
42 | mybatis-scala-core_${scala.binary}
43 | ${project.version}
44 |
45 |
46 | org.scala-lang
47 | scala-library
48 |
49 |
50 | org.hsqldb
51 | hsqldb
52 | 2.7.4
53 | jdk8
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | ${project.basedir}/src/main/resources
62 |
63 |
64 | META-INF
65 | ${project.basedir}/../
66 |
67 | LICENSE
68 | NOTICE
69 |
70 |
71 |
72 |
73 |
74 | net.alchim31.maven
75 | scala-maven-plugin
76 |
77 |
78 |
79 | maven-deploy-plugin
80 |
81 | true
82 |
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/resources/mybatis.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/resources/sample-data.sql:
--------------------------------------------------------------------------------
1 | --
2 | -- Copyright 2011-2015 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 | INSERT INTO people_group (id_, name_)
18 | VALUES
19 | (1, 'Customers'),
20 | (2, 'Suppliers'),
21 | (3, 'Employees');
22 |
23 | INSERT INTO person (id_, first_name_, last_name_, group_id_)
24 | VALUES
25 | (1, 'Brenda', 'Gates', 1),
26 | (2, 'Sara', 'Jobs', 2),
27 | (3, 'Janeth', 'Gosling', 3),
28 | (4, 'John', 'Doe', 1),
29 | (5, 'Mary', 'Jackson', 2);
30 |
31 | INSERT INTO contact_info (owner_id_, street_address_, phone_number_)
32 | VALUES
33 | (1, '637 St Monica', '555-5647809'),
34 | (2, '23 Wall St', '555-0485959'),
35 | (2, '78 Road X', '554-8899888'),
36 | (3, '567 Kong St', '555-0989988'),
37 | (4, '5 Springfield', '555-0909090'),
38 | (5, 'Another place', '555-6978799');
39 |
40 | -- Postgresql only: update sequences
41 | SELECT setval('people_group_id__seq', 4);
42 | SELECT setval('person_id__seq', 6);
43 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/resources/schema.sql:
--------------------------------------------------------------------------------
1 | --
2 | -- Copyright 2011-2015 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 people_group (
18 | id_ serial,
19 | name_ varchar(255),
20 | primary key (id_)
21 | );
22 |
23 | CREATE TABLE person (
24 | id_ serial,
25 | first_name_ varchar(255),
26 | last_name_ varchar(255),
27 | group_id_ integer not null,
28 | primary key (id_),
29 | foreign key (group_id_) references people_group(id_)
30 | );
31 |
32 | CREATE TABLE contact_info (
33 | id_ serial,
34 | owner_id_ integer not null,
35 | street_address_ varchar(255),
36 | phone_number_ varchar(20),
37 | primary key (id_),
38 | foreign key (owner_id_) references person(id_)
39 | );
40 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/crud/Config.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.crud
17 |
18 | import org.mybatis.scala.config._
19 |
20 | object Config {
21 |
22 | // Load datasource configuration
23 | val config = Configuration("mybatis.xml")
24 |
25 | // Create a configuration space, add the data access method
26 | config.addSpace("item") { space =>
27 | space ++= ItemDAO
28 | }
29 |
30 | // Build the session manager
31 | val persistenceContext = config.createPersistenceContext
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/crud/Item.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.crud
17 |
18 | class Item {
19 | var id : Int = _
20 | var description : String = _
21 | var info : Option[String] = None
22 | var year : Option[Int] = None
23 | }
24 |
25 | object Item {
26 |
27 | def apply(description : String, info : Option[String] = None, year : Option[Int] = None) = {
28 | val i = new Item
29 | i.description = description
30 | i.info = info
31 | i.year = year
32 | i
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/crud/ItemDAO.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.crud
17 |
18 | import org.mybatis.scala.mapping._
19 | import org.mybatis.scala.mapping.Binding._
20 | import org.mybatis.scala.mapping.TypeHandlers._
21 | import org.mybatis.scala.session.Session
22 | import scala.language.postfixOps
23 |
24 | object ItemDAO {
25 |
26 | val ItemResultMap = new ResultMap[Item] {
27 | id ( column = "id_", property = "id" )
28 | result ( column = "description_", property = "description" )
29 | result ( column = "info_", property = "info", jdbcType=JdbcType.VARCHAR )
30 | result ( column = "year_", property = "year", typeHandler=T[OptIntegerTypeHandler] )
31 | }
32 |
33 | val SELECT_SQL =
34 |
35 | SELECT *
36 | FROM item
37 |
38 |
39 | val findAll = new SelectList[Item] {
40 | resultMap = ItemResultMap
41 | def xsql = SELECT_SQL
42 | }
43 |
44 | val findByDescription = new SelectListBy[String,Item] {
45 | resultMap = ItemResultMap
46 | def xsql =
47 |
48 | {SELECT_SQL}
49 | WHERE description_ LIKE {"description"?}
50 | ORDER BY description_
51 |
52 | }
53 |
54 | val findById = new SelectOneBy[Int,Item] {
55 | resultMap = ItemResultMap
56 | def xsql =
57 |
58 | {SELECT_SQL}
59 | WHERE id_ = {"id"?}
60 |
61 | }
62 |
63 | val insert = new Insert[Item] {
64 | def xsql =
65 |
66 | INSERT INTO item(description_, info_, year_)
67 | VALUES (
68 | { "description"? },
69 | {? ("info", jdbcType=JdbcType.VARCHAR)},
70 | {? ("year", jdbcType=JdbcType.INTEGER)}
71 | )
72 |
73 | }
74 |
75 | val update = new Update[Item] {
76 | def xsql =
77 |
78 | UPDATE item
79 | SET
80 | description_ = {"description"?},
81 | info_ = {? ("info", jdbcType=JdbcType.VARCHAR)},
82 | year_ = {? ("year", jdbcType=JdbcType.INTEGER)}
83 | WHERE id_ = {"id"?}
84 |
85 | }
86 |
87 | val DELETE_SQL =
88 |
89 | DELETE FROM item
90 | WHERE id_ = {"id"?}
91 |
92 |
93 | val delete = new Delete[Item] {
94 | def xsql = DELETE_SQL
95 | }
96 |
97 | val deleteById = new Delete[Int] {
98 | def xsql = DELETE_SQL
99 | }
100 |
101 | val dropTable = new Perform {
102 | def xsql =
103 |
104 | DROP TABLE IF EXISTS item
105 |
106 | }
107 |
108 | val createTable = new Perform {
109 | def xsql =
110 |
111 | CREATE TABLE item (
112 | id_ INTEGER GENERATED BY DEFAULT AS IDENTITY,
113 | description_ varchar(255) not null,
114 | info_ varchar(255),
115 | year_ integer,
116 | primary key (id_)
117 | )
118 |
119 | }
120 |
121 | def initdb(implicit s : Session) = {
122 | dropTable()
123 | createTable()
124 | }
125 |
126 | def bind = Seq(delete,update,insert,findById,findByDescription,deleteById,findAll,createTable,dropTable)
127 |
128 | }
129 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/crud/Main.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.crud
17 |
18 | import org.mybatis.scala.session._
19 |
20 | object Main extends App {
21 |
22 | val db = Config.persistenceContext
23 |
24 | db.transaction { implicit session =>
25 |
26 | // Init the DB: create table etc...
27 | ItemDAO.initdb
28 |
29 | // Insert some items
30 | ItemDAO insert Item("BMW")
31 | ItemDAO insert Item("Ford", Some("USA"), Some(1900))
32 | ItemDAO insert Item("Renault", Some("France"))
33 | ItemDAO insert Item("Chevrolet")
34 | ItemDAO insert Item("Hyundai", Some("Korea"))
35 | ItemDAO insert Item("Honda", year=Some(1997))
36 |
37 | // Show ...
38 | println("== Initial values ====================")
39 | ItemDAO.findAll() foreach (printItem _)
40 |
41 | // Change something ...
42 | for (item <- ItemDAO findById(3)) {
43 | item.description = "-CHANGED-"
44 | item.year = Some(2001)
45 | item.info = Some("-MEXICO-")
46 | ItemDAO update item
47 | }
48 |
49 | // Show again ...
50 | println("== With some changes =================")
51 | ItemDAO.findAll() foreach (printItem _)
52 |
53 | // Delete something ...
54 | for (item <- ItemDAO findById(3)) {
55 | ItemDAO delete item
56 | }
57 |
58 | // Show again ...
59 | println("== With some items removed ===========")
60 | ItemDAO.findAll() foreach (printItem _)
61 |
62 | // Show filtered ...
63 | println("== Filtered by H% ====================")
64 | ItemDAO.findByDescription("H%") foreach (printItem _)
65 |
66 | }
67 |
68 | def printItem(i : Item) =
69 | println("%d: %10s\t %10s\t %5s" format (i.id, i.description, i.info.getOrElse("-"), i.year.getOrElse("-")))
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/delete/DeleteSample.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.delete
17 |
18 | import org.mybatis.scala.mapping._
19 | import org.mybatis.scala.config._
20 | import org.mybatis.scala.session._
21 | import org.mybatis.scala.samples.util._
22 |
23 | object DeleteSample {
24 |
25 | // Simple Person POJO
26 | class Person {
27 | var id : Int = _
28 | var firstName : String = _
29 | var lastName : String = _
30 | }
31 |
32 | // Simple select method
33 | val findAll = new SelectList[Person] {
34 | def xsql =
35 |
36 | SELECT id_ as id, first_name_ as firstName, last_name_ as lastName
37 | FROM person
38 | ORDER BY id_
39 |
40 | }
41 |
42 | val findMaxId = new SelectOne[Int] {
43 | def xsql =
44 |
45 | SELECT MAX(id_) FROM person
46 |
47 | }
48 |
49 | val deletePersonById = new Delete[Int] {
50 | def xsql =
51 |
52 | DELETE FROM person WHERE id_ = #{{id}}
53 |
54 | }
55 |
56 | val deletePersonContacts = new Delete[Int] {
57 | def xsql =
58 |
59 | DELETE FROM contact_info WHERE owner_id_ = #{{id}}
60 |
61 | }
62 |
63 | // Load datasource configuration
64 | val config = Configuration("mybatis.xml")
65 |
66 | // Create a configuration space, add the data access method
67 | config.addSpace("ns1") { space =>
68 | space += findAll
69 | space += findMaxId
70 | space += deletePersonById
71 | space += deletePersonContacts
72 | space ++= DBSchema
73 | space ++= DBSampleData
74 | }
75 |
76 | // Build the session manager
77 | val db = config.createPersistenceContext
78 |
79 | // Do the Magic ...
80 | def main(args : Array[String]) : Unit = {
81 |
82 | db.transaction { implicit session =>
83 |
84 | DBSchema.create
85 | DBSampleData.populate
86 |
87 | println("Before =>")
88 | for (p <- findAll())
89 | println( "\tPerson(%d): %s %s".format(p.id, p.firstName, p.lastName) )
90 |
91 | for(id <- findMaxId()) {
92 | deletePersonContacts(id)
93 | deletePersonById(id)
94 | }
95 |
96 | println("After =>")
97 | for (p <- findAll())
98 | println( "\tPerson(%d): %s %s".format(p.id, p.firstName, p.lastName) )
99 |
100 | }
101 |
102 | }
103 |
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/insert/InsertSample.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.insert
17 |
18 | import org.mybatis.scala.samples.util._
19 | import org.mybatis.scala.mapping._
20 | import org.mybatis.scala.config._
21 | import org.mybatis.scala.session._
22 |
23 | object InsertSample {
24 |
25 | // Simple Group POJO
26 | class Group {
27 | var id : Int = _
28 | var name : String = _
29 | }
30 |
31 | // Simple Person POJO
32 | class Person {
33 | var id : Int = _
34 | var firstName : String = _
35 | var lastName : String = _
36 | var group : Group = _
37 | }
38 |
39 | // Simple insert method
40 | val insertPerson = new Insert[Person] {
41 | keyGenerator = JdbcGeneratedKey(null, "id")
42 | def xsql =
43 |
44 | INSERT INTO person (first_name_, last_name_, group_id_)
45 | VALUES (#{{firstName}}, #{{lastName}}, #{{group.id}})
46 |
47 | }
48 |
49 | // Simple insert method
50 | val insertGroup = new Insert[Group] {
51 | keyGenerator = JdbcGeneratedKey(null, "id")
52 | def xsql =
53 |
54 | INSERT INTO people_group (name_)
55 | VALUES (#{{name}})
56 |
57 | }
58 |
59 | // Load datasource configuration
60 | val config = Configuration("mybatis.xml")
61 |
62 | // Create a configuration space, add the data access method
63 | config.addSpace("ns1") { space =>
64 | space ++= Seq(insertPerson, insertGroup)
65 | space ++= DBSchema
66 | }
67 |
68 | // Build the session manager
69 | val db = config.createPersistenceContext
70 |
71 | // Do the Magic ...
72 | def main(args : Array[String]) : Unit = {
73 |
74 | db.transaction { implicit session =>
75 |
76 | DBSchema.create
77 |
78 | val g = new Group
79 | g.name = "New Group"
80 |
81 | val p = new Person
82 | p.firstName = "John"
83 | p.lastName = "Smith"
84 | p.group = g
85 |
86 | insertGroup(g)
87 | insertPerson(p)
88 |
89 | println( "Inserted Person(%d): %s %s".format(p.id, p.firstName, p.lastName) )
90 |
91 | }
92 |
93 | }
94 |
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/insert/InsertSampleBatch.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.insert
17 |
18 | import org.mybatis.scala.samples.util._
19 | import org.mybatis.scala.mapping._
20 | import org.mybatis.scala.config._
21 | import org.mybatis.scala.session._
22 |
23 | object InsertSampleBatch {
24 |
25 | // Simple Group POJO
26 | class Group {
27 | var id : Int = _
28 | var name : String = _
29 | }
30 |
31 | // Simple Person POJO
32 | class Person {
33 | var id : Int = _
34 | var firstName : String = _
35 | var lastName : String = _
36 | var group : Group = _
37 | }
38 |
39 | // Simple insert method
40 | val insertPerson = new Insert[Person] {
41 | keyGenerator = JdbcGeneratedKey(null, "id")
42 | def xsql =
43 |
44 | INSERT INTO person (first_name_, last_name_, group_id_)
45 | VALUES (#{{firstName}}, #{{lastName}}, #{{group.id}})
46 |
47 | }
48 |
49 | // Simple insert method
50 | val insertGroup = new Insert[Group] {
51 | keyGenerator = JdbcGeneratedKey(null, "id")
52 | def xsql =
53 |
54 | INSERT INTO people_group (name_)
55 | VALUES (#{{name}})
56 |
57 | }
58 |
59 | // Load datasource configuration
60 | val config = Configuration("mybatis.xml")
61 |
62 | // Create a configuration space, add the data access method
63 | config ++= Seq(insertPerson, insertGroup)
64 | config ++= DBSchema
65 |
66 | // Build the session manager
67 | val db = config.createPersistenceContext
68 |
69 | // Do the Magic ...
70 | def main(args : Array[String]) : Unit = {
71 |
72 | db.transaction(ExecutorType.BATCH) { implicit session =>
73 |
74 | DBSchema.create
75 | session.flushStatements()
76 |
77 | val g = new Group
78 | g.name = "New Group"
79 | insertGroup(g)
80 | session.flushStatements()
81 |
82 | Seq(("Jonh", "Smith"), ("Mary", "Jane"), ("Pepe", "Grillo")) map { (t) =>
83 | val p = new Person
84 | p.firstName = t._1
85 | p.lastName = t._2
86 | p.group = g
87 | insertPerson(p)
88 | }
89 |
90 | val created = session.flushStatements()
91 | for (result <- created) {
92 | println( "\n==========================================================" )
93 | println( result.getSql )
94 | println( "\nCalled " + result.getUpdateCounts.size + " times")
95 | println( "Total update counts: " + result.getUpdateCounts.foldLeft(0)((a,b)=>a + b) )
96 | }
97 |
98 | }
99 |
100 | }
101 |
102 |
103 | }
104 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/nestedselect/NestedSelectSample.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.nestedselect
17 |
18 | import org.mybatis.scala.mapping._
19 | import org.mybatis.scala.config._
20 | import org.mybatis.scala.session._
21 | import org.mybatis.scala.samples.util._
22 |
23 | // Model beans =================================================================
24 |
25 | // Simple Group POJO
26 | class Group {
27 | var id : Int = _
28 | var name : String = _
29 | }
30 |
31 | // Simple ContactInfo POJO
32 | class ContactInfo {
33 | var id : Int = _
34 | var address : String = _
35 | var phone : String = _
36 | }
37 |
38 | // Simple Person POJO with OneToMany to ContactInfo
39 | class Person {
40 | var id : Int = _
41 | var firstName : String = _
42 | var lastName : String = _
43 | var group : Group = _
44 | var contact : Seq[ContactInfo] = _
45 | }
46 |
47 | // Data access layer ===========================================================
48 |
49 | object Persistence {
50 |
51 | // Query for a Group
52 | val selectGroup = new SelectOneBy[Int,Group] {
53 | def xsql =
54 |
55 | SELECT id_ as id, name_ as name
56 | FROM people_group
57 | WHERE id_ = #{{id}}
58 |
59 | }
60 |
61 | // Query for a list of contact info
62 | val selectContact = new SelectListBy[Int,ContactInfo] {
63 | resultMap = new ResultMap[ContactInfo] {
64 | id(property="id", column="id_")
65 | result(property="address", column="street_address_")
66 | result(property="phone", column="phone_number_")
67 | }
68 | def xsql = SELECT * FROM contact_info WHERE owner_id_ = #{{id}}
69 | }
70 |
71 | // Query for a list of all persons
72 | val findAll = new SelectList[Person] {
73 |
74 | // Define the result mapping
75 | resultMap = new ResultMap[Person] {
76 |
77 | id(property="id", column="id_")
78 | result(property="firstName", column="first_name_")
79 | result(property="lastName", column="last_name_")
80 |
81 | association[Group] (property="group", column="group_id_", select=selectGroup)
82 |
83 | collection[ContactInfo] (property="contact", column="id_", select=selectContact)
84 |
85 | }
86 |
87 | // Define the actual query
88 | def xsql =
89 |
90 | SELECT *
91 | FROM person p
92 | ORDER BY first_name_
93 |
94 | }
95 |
96 | // Load datasource configuration from an external file
97 | val config = Configuration("mybatis.xml")
98 |
99 | // Add the data access function to the default namespace
100 | config += findAll
101 | config ++= DBSchema
102 | config ++= DBSampleData
103 |
104 | // Build the session manager
105 | lazy val context = config.createPersistenceContext
106 |
107 | }
108 |
109 | // Application code ============================================================
110 |
111 | object NestedSelectSample {
112 |
113 | // Do the Magic ...
114 | def main(args : Array[String]) : Unit = {
115 | Persistence.context.transaction { implicit session =>
116 |
117 | DBSchema.create
118 | DBSampleData.populate
119 |
120 | for (p <- Persistence.findAll()) {
121 | println("\nPerson(%d): %s %s (%s)".format(p.id, p.firstName, p.lastName, p.group.name))
122 | for (contact <- p.contact) {
123 | println(" Address: %s, Phone: %s".format(contact.address, contact.phone))
124 | }
125 | }
126 |
127 | }
128 | }
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/performance/ProfileTest.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.performance
17 |
18 | import org.mybatis.scala.mapping._
19 | import org.mybatis.scala.config._
20 | import org.mybatis.scala.session._
21 | import org.mybatis.scala.mapping.Binding._
22 | import scala.language.postfixOps
23 |
24 | class TestBean {
25 | var id : Int = 0
26 | var name : String = _
27 | }
28 |
29 | object ProfileTest extends App {
30 |
31 | // Simple DDL
32 | val createTable = new Perform {
33 | def xsql =
34 |
35 | CREATE TABLE test1 (
36 | id_ INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) not null,
37 | name_ varchar(255),
38 | primary key (id_)
39 | )
40 |
41 | }
42 |
43 | // Simple Insert
44 | val insert = new Insert[TestBean] {
45 | def xsql =
46 |
47 | INSERT INTO test1(name_) VALUES ({"name"?})
48 |
49 | }
50 |
51 | // Simple select
52 | val select = new SelectList[TestBean] {
53 | def xsql =
54 |
55 | SELECT id_ as id, name_ as name
56 | FROM test1
57 |
58 | }
59 |
60 | // Datasource configuration
61 | val config = Configuration(
62 | Environment(
63 | "default",
64 | new JdbcTransactionFactory(),
65 | new PooledDataSource(
66 | "org.hsqldb.jdbcDriver",
67 | "jdbc:hsqldb:mem:scala",
68 | "sa",
69 | ""
70 | )
71 | )
72 | )
73 |
74 | // Add the data access method to the default namespace
75 | config += createTable
76 | config += insert
77 | config += select
78 |
79 | // Insert 1.000.000 rows
80 | val context = config.createPersistenceContext
81 | context.transaction { implicit s =>
82 | createTable()
83 | for (i <- 1 to 1000000) {
84 | val bean = new TestBean()
85 | bean.name = "Bean " + i
86 | insert(bean)
87 | }
88 | }
89 |
90 | // Read 1.000.000 rows into memory
91 | context.readOnly { implicit s =>
92 | val resultSeq = select()
93 | }
94 |
95 | // Read 1.000.000 rows one by one
96 | context.readOnly { implicit s =>
97 | select.handle[TestBean] { context =>
98 | val bean = context.getResultObject
99 | }
100 | }
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/resultmap/SelectWithResultMapSample.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.resultmap
17 |
18 | import org.mybatis.scala.mapping._
19 | import org.mybatis.scala.config._
20 | import org.mybatis.scala.session._
21 | import org.mybatis.scala.samples.util._
22 |
23 |
24 | // Model beans =================================================================
25 |
26 | // Simple Group POJO
27 | class Group {
28 | var id : Int = _
29 | var name : String = _
30 | }
31 |
32 | // Simple ContactInfo POJO
33 | class ContactInfo {
34 | var id : Int = _
35 | var address : String = _
36 | var phone : String = _
37 | }
38 |
39 | // Simple Person POJO with OneToMany to ContactInfo
40 | class Person {
41 | var id : Int = _
42 | var firstName : String = _
43 | var lastName : String = _
44 | var group : Group = _
45 | var contact : Seq[ContactInfo] = _
46 | }
47 |
48 | // Data access layer ===========================================================
49 |
50 | object Persistence {
51 |
52 | // Simple select function (Nothing) => List[Person]
53 | val findAll = new SelectList[Person] {
54 |
55 | // Define the result mapping
56 | resultMap = new ResultMap[Person] {
57 |
58 | id(property="id", column="id_")
59 | result(property="firstName", column="first_name_")
60 | result(property="lastName", column="last_name_")
61 |
62 | association[Group] (property="group",
63 | resultMap= new ResultMap[Group] {
64 | id(property="id", column="group_id_")
65 | result(property="name", column="group_name_")
66 | }
67 | )
68 |
69 | collection[ContactInfo] (property="contact",
70 | resultMap= new ResultMap[ContactInfo] {
71 | id(property="id", column="cinfo_id_")
72 | result(property="address", column="street_address_")
73 | result(property="phone", column="phone_number_")
74 | }
75 | )
76 |
77 | }
78 |
79 | // Define the actual query
80 | def xsql =
81 |
82 | SELECT
83 | p.id_, p.first_name_, p.last_name_,
84 | p.group_id_, g.name_ as group_name_,
85 | c.id_ as cinfo_id_, c.street_address_, c.phone_number_
86 | FROM
87 | person p
88 | LEFT OUTER JOIN people_group g ON p.group_id_ = g.id_
89 | LEFT OUTER JOIN contact_info c ON c.owner_id_ = p.id_
90 |
91 | }
92 |
93 | // Load datasource configuration from an external file
94 | val config = Configuration("mybatis.xml")
95 |
96 | // Add the data access function to the default namespace
97 | config += findAll
98 | config ++= DBSchema
99 | config ++= DBSampleData
100 |
101 | // Build the session manager
102 | lazy val context = config.createPersistenceContext
103 |
104 | }
105 |
106 | // Application code ============================================================
107 |
108 | object SelectWithResultMapSample {
109 |
110 | // Do the Magic ...
111 | def main(args : Array[String]) : Unit = {
112 | Persistence.context.transaction { implicit session =>
113 |
114 | DBSchema.create
115 | DBSampleData.populate
116 |
117 | for (p <- Persistence.findAll()) {
118 | println("\nPerson(%d): %s %s is in group: %s".format(p.id, p.firstName, p.lastName, p.group.name))
119 | for (contact <- p.contact) {
120 | println(" Address: %s, Phone: %s".format(contact.address, contact.phone))
121 | }
122 | }
123 |
124 | }
125 | }
126 |
127 | }
128 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/select/SelectImmutableSample.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.select
17 |
18 | import org.mybatis.scala.mapping._
19 | import org.mybatis.scala.config._
20 | import org.mybatis.scala.session._
21 | import org.mybatis.scala.samples.util._
22 |
23 | // Model beans (Immutable case class) ==========================================
24 |
25 | case class CPerson(id : Int, firstName : String, lastName : String)
26 |
27 | // Data access layer ===========================================================
28 |
29 | object CDB {
30 |
31 | // Simple select function
32 | val findAll = new SelectListBy[String,CPerson] {
33 |
34 | // CPerson Constructor Mapping
35 | resultMap = new ResultMap[CPerson] {
36 | // Warning: Order is important (constructor arguments in order)
37 | idArg ("id_", javaType=T[Int])
38 | arg ("first_name_", javaType=T[String])
39 | arg ("last_name_", javaType=T[String])
40 | }
41 |
42 | def xsql =
43 | """
44 | SELECT
45 | id_, first_name_, last_name_
46 | FROM
47 | person
48 | WHERE
49 | first_name_ LIKE #{name}
50 | """
51 | }
52 |
53 | // Main configuration
54 | object ConfigurationSpec extends Configuration.Builder {
55 | // Connection settings
56 | environment(
57 | id = "default",
58 | transactionFactory = new JdbcTransactionFactory(),
59 | dataSource = new PooledDataSource("org.hsqldb.jdbcDriver", "jdbc:hsqldb:mem:scala", "sa", "")
60 | )
61 | // Add the data access methods to default namespace
62 | statements(findAll)
63 | mappers(DBSchema, DBSampleData)
64 | }
65 |
66 | // Build the session manager
67 | lazy val context = Configuration(ConfigurationSpec).createPersistenceContext
68 |
69 | }
70 |
71 | // Application code ============================================================
72 |
73 | object SelectImmutableSample {
74 |
75 | import CDB._
76 |
77 | // Do the Magic ...
78 | def main(args: Array[String]): Unit = context.transaction { implicit s =>
79 |
80 | // Create database and populate it with sample data
81 | DBSchema.create
82 | DBSampleData.populate
83 |
84 | // Query
85 | findAll("%a%").foreach {
86 | case CPerson(id, firstName, lastName) =>
87 | println("Person(%d): %s %s" format (id, firstName, lastName))
88 | }
89 |
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/select/SelectSample.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.select
17 |
18 | import org.mybatis.scala.mapping._
19 | import org.mybatis.scala.config._
20 | import org.mybatis.scala.session._
21 | import org.mybatis.scala.samples.util._
22 |
23 | // Model beans =================================================================
24 |
25 | class Person {
26 | var id : Int = _
27 | var firstName : String = _
28 | var lastName : String = _
29 | }
30 |
31 | // Data access layer ===========================================================
32 |
33 | object DB {
34 |
35 | // Simple select function
36 | val findAll = new SelectListBy[String,Person] {
37 | def xsql =
38 |
39 |
40 | SELECT
41 | id_ as id,
42 | first_name_ as firstName,
43 | last_name_ as lastName
44 | FROM
45 | person
46 | WHERE
47 | first_name_ LIKE #{{pattern}}
48 |
49 | }
50 |
51 | // Datasource configuration
52 | val config = Configuration(
53 | Environment(
54 | "default",
55 | new JdbcTransactionFactory(),
56 | new PooledDataSource(
57 | "org.hsqldb.jdbcDriver",
58 | "jdbc:hsqldb:mem:scala",
59 | "sa",
60 | ""
61 | )
62 | )
63 | )
64 |
65 | // Add the data access method to the default namespace
66 | config += findAll
67 | config ++= DBSchema
68 | config ++= DBSampleData
69 |
70 | // Build the session manager
71 | lazy val context = config.createPersistenceContext
72 |
73 | }
74 |
75 | // Application code ============================================================
76 |
77 | object SelectSample {
78 |
79 | // Do the Magic ...
80 | def main(args : Array[String]) : Unit = {
81 | DB.context.transaction { implicit session =>
82 |
83 | DBSchema.create
84 | DBSampleData.populate
85 |
86 | DB.findAll("a").foreach { p =>
87 | println( "Person(%d): %s %s".format(p.id, p.firstName, p.lastName) )
88 | }
89 |
90 | }
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/update/UpdateSample.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.update
17 |
18 | import org.mybatis.scala.mapping._
19 | import org.mybatis.scala.config._
20 | import org.mybatis.scala.session._
21 | import org.mybatis.scala.samples.util._
22 |
23 | object UpdateSample {
24 |
25 | // Simple Person POJO
26 | class Person {
27 | var id : Int = _
28 | var firstName : String = _
29 | var lastName : String = _
30 | }
31 |
32 | // Simple update method
33 | val updatePerson = new Update[Person] {
34 | def xsql =
35 |
36 | UPDATE person
37 | SET
38 | first_name_ = #{{firstName}},
39 | last_name_ = #{{lastName}}
40 | WHERE
41 | id_ = #{{id}}
42 |
43 | }
44 |
45 | // Simple select method
46 | val findPerson = new SelectOneBy[Int,Person] {
47 | def xsql =
48 |
49 | SELECT id_ as id, first_name_ as firstName, last_name_ as lastName
50 | FROM person
51 | WHERE id_ = #{{id}}
52 |
53 | }
54 |
55 |
56 | // Load datasource configuration
57 | val config = Configuration("mybatis.xml")
58 |
59 | // Create a configuration space, add the data access method
60 | config.addSpace("ns1") { space =>
61 | space += updatePerson += findPerson
62 | }
63 |
64 | config ++= DBSchema
65 | config ++= DBSampleData
66 |
67 | // Build the session manager
68 | val db = config.createPersistenceContext
69 |
70 | // Do the Magic ...
71 | def main(args : Array[String]) : Unit = {
72 |
73 | db.transaction { implicit session =>
74 |
75 | DBSchema.create
76 | DBSampleData.populate
77 |
78 | findPerson(1) match {
79 | case Some(p) =>
80 |
81 | // Show original
82 | println("Before =>\n\tPerson(%d): %s, %s".format(p.id, p.lastName, p.firstName))
83 |
84 | // Update a property
85 | p.firstName = "Sun (Updated " + new java.util.Date + ")"
86 | updatePerson(p)
87 |
88 | // Reload to verify
89 | for (p2 <- findPerson(1))
90 | println( "After =>\n\tPerson(%d): %s, %s".format(p2.id, p2.lastName, p2.firstName) )
91 |
92 | case None =>
93 | println("Person with id=1 does not exists!!!")
94 | }
95 |
96 | }
97 |
98 | }
99 |
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/util/DBSampleData.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.util
17 |
18 | import org.mybatis.scala.mapping._
19 | import org.mybatis.scala.session._
20 |
21 | object DBSampleData {
22 |
23 | val insertPerson = new Insert[java.util.Map[_,_]] {
24 | def xsql =
25 |
26 | INSERT INTO person(id_, first_name_, last_name_, group_id_)
27 | VALUES (#{{id}}, #{{firstname}}, #{{lastname}}, #{{group}})
28 |
29 | }
30 |
31 | val insertGroup = new Insert[java.util.Map[_,_]] {
32 | def xsql =
33 |
34 | INSERT INTO people_group(id_, name_)
35 | VALUES (#{{id}}, #{{name}})
36 |
37 | }
38 |
39 | val insertContactInfo = new Insert[java.util.Map[_,_]] {
40 | def xsql =
41 |
42 | INSERT INTO contact_info (owner_id_, street_address_, phone_number_)
43 | VALUES (#{{person}}, #{{address}}, #{{phone}})
44 |
45 | }
46 |
47 | def bind = Seq(insertContactInfo, insertGroup, insertPerson)
48 |
49 | def populate(implicit s : Session) = {
50 |
51 | import scala.jdk.CollectionConverters._
52 |
53 | insertGroup(Map("id" -> 1, "name" -> "Customers").asJava)
54 | insertGroup(Map("id" -> 2, "name" -> "Suppliers").asJava)
55 | insertGroup(Map("id" -> 3, "name" -> "Employees").asJava)
56 |
57 | insertPerson(Map("id" -> 1, "firstname" -> "John", "lastname" -> "Smart", "group" -> 1).asJava)
58 | insertPerson(Map("id" -> 2, "firstname" -> "Maria", "lastname" -> "Perez", "group" -> 2).asJava)
59 | insertPerson(Map("id" -> 3, "firstname" -> "Janeth", "lastname" -> "Ros", "group" -> 1).asJava)
60 | insertPerson(Map("id" -> 4, "firstname" -> "Paul", "lastname" -> "Jobs", "group" -> 3).asJava)
61 | insertPerson(Map("id" -> 5, "firstname" -> "Bill", "lastname" -> "Rich", "group" -> 1).asJava)
62 |
63 | insertContactInfo(Map("person" -> 1, "address" -> "222 Street", "phone" -> "555-0988998").asJava)
64 | insertContactInfo(Map("person" -> 2, "address" -> "333 Av", "phone" -> "554-7464363").asJava)
65 | insertContactInfo(Map("person" -> 2, "address" -> "1 Rose Ave", "phone" -> "836-8456463").asJava)
66 | insertContactInfo(Map("person" -> 3, "address" -> "444 St Rose", "phone" -> "665-9476558").asJava)
67 | insertContactInfo(Map("person" -> 4, "address" -> "555 Wall Street", "phone" -> "666-7474664").asJava)
68 | insertContactInfo(Map("person" -> 5, "address" -> "666 Mountain View", "phone" -> "571-9875923").asJava)
69 | insertContactInfo(Map("person" -> 5, "address" -> "777 Mars", "phone" -> "587-3984792").asJava)
70 |
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/main/scala/org/mybatis/scala/samples/util/DBSchema.scala:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2015 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.scala.samples.util
17 |
18 | import org.mybatis.scala.mapping._
19 | import org.mybatis.scala.session.Session
20 |
21 | object DBSchema {
22 |
23 | val createPeopleGroupTable = new Perform {
24 | def xsql =
25 |
26 | CREATE TABLE people_group (
27 | id_ INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) not null,
28 | name_ varchar(255),
29 | primary key (id_)
30 | )
31 |
32 | }
33 |
34 | val createPersonTable = new Perform {
35 | def xsql =
36 |
37 | CREATE TABLE person (
38 | id_ INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) not null,
39 | first_name_ varchar(255),
40 | last_name_ varchar(255),
41 | group_id_ integer not null,
42 | primary key (id_),
43 | foreign key (group_id_) references people_group(id_)
44 | )
45 |
46 | }
47 |
48 | val createContactInfoTable = new Perform {
49 | def xsql =
50 |
51 | CREATE TABLE contact_info (
52 | id_ INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) not null,
53 | owner_id_ integer not null,
54 | street_address_ varchar(255),
55 | phone_number_ varchar(20),
56 | primary key (id_),
57 | foreign key (owner_id_) references person(id_)
58 | )
59 |
60 | }
61 |
62 | val bind = Seq(createPeopleGroupTable, createPersonTable, createContactInfoTable)
63 |
64 | def create(implicit s: Session): Unit = {
65 | createPeopleGroupTable()
66 | createPersonTable()
67 | createContactInfoTable()
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/site/resources/images/ERD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mybatis/scala/806a7030b0ca2d773cb636a2b40cdbba3eb1d491/mybatis-scala-samples/src/site/resources/images/ERD.png
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/site/site.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
22 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/mybatis-scala-samples/src/site/xdoc/index.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
23 |
24 |
25 | MyBatis Scala
26 | The MyBatis Team
27 | $Date$
28 |
29 |
30 |
31 |
32 |
33 | There are some examples, each one is based on the same sample database.
34 | See
35 | ERD.png
36 |
37 |
38 |
39 |
40 |
41 |
42 | Also most of them share the same configuration file:
43 | mybatis.xml
44 |
33 | MyBatis is a persistence framework for Java, so you can use it in Scala as any other
34 | java library, nonetheless the main API is too java centric, it uses Java annotations
35 | and external xml files where you put your SQL.
36 |
37 |
38 | The MyBatis Scala API is a lightweight wrapper, it supports a 100% of the framework
39 | functionality, taking advantage of the elegant Scala syntax and its type system.
40 | With this API you can use the Scala collections and "Scala beans", and you can define
41 | all your dynamic SQL code directly in your scala code without String concatenation
42 | and with very clear syntax.
43 |
44 |
45 | Appart from the main configuration xml file where you define the datasource and transaction
46 | configurations, you will avoid use of external xml files and java Annotations.
47 |
48 |
49 | The main documentation is at the core project:
50 | mybatis-scala-core
51 |