Kotlin作为走在替代Java的路上可谓是越走越快,简洁的语法,现代化的人性化语法,总之作为Google大力推荐的Android第一开发语言越来越受到大家关注,而Spring出了针对Kotlin的快速入门的Springboot版本的入门,今天我们就来看看怎么在mybatis上使用Kotlin吧
1 依赖配置
自不必说都是基于pom的我们需要添加Kotlin依赖 mybatis依赖,MySQL依赖这些基本的依赖
代码语言:javascript复制 <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmTarget>1.8</jvmTarget>
</configuration>
</plugin>
</plugins>
</build>
这里说一点对于springboot打包是resource文件有缺失的可以参考上文方式中的include方式将文件打包进去,具体的根据个人需求来做,下面的是例子
代码语言:javascript复制 <build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</build>
我们配置了依赖需要配置环境属性变量---resources文件夹下新建application.yml将mybatis MySQL的基本配置进行配置
代码语言:javascript复制server:
port: 8080
spring:
freemarker:
suffix: .ftl # 设置模板后缀名
content-type: text/html # 设置文档类型
charset: UTF-8 # 设置页面编码格式
cache: false # 设置页面缓存
template-loader-path: classpath:/templates # 设置ftl文件路径
check-template-location: true
mvc:
static-path-pattern: /static
datasource:
url: jdbc:mysql://localhost:3306/app?useUnicode=true&characterEncoding=utf-8
username: root
password: 12345678
mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml
logging:
level:
app:
mapper: debug
mapper与model映射
单一model与mapper映射
什么叫做单一的映射也就是说model中只有基本的数据类型没有那些自定的model如:Person这个data class吧,内部属性只有 id age name
我们以一个电影的表示模型为例来实现
代码语言:javascript复制data class Movie(val id: Int = 0,
val title: String,
var brief: String?,
var directors: String? = null,
var actors: String? = null,
var categoryId: Int = 0,
val pic:String,
val parentCategoryId:Int = 0)
看似属性成员一大堆,但是由于都是基本数据类型因此它就是单一的模型,对应的mapper就十分单一,查询的sql就更加单一
代码语言:javascript复制<resultMap id="movie" type="app.entity.Movie">
<result property="id" column="ic"/>
<result column="title" property="title"/>
<result column="brief" property="brief"/>
<result column="directors" property="directors"/>
<result column="actors" property="actors"/>
<result column="category_id" property="categoryId"/>
<result column="pic" property="pic"/>
<result column="parent_category_id" property="parentCategoryId"/>
</resultMap>
<select id="indexMovie" resultMap="movie">
<bind name="off_set" value="(page-1)*pageSize"></bind>
select * from movie
<choose>
<when test="category==1"></when>
<otherwise>
<where>
<choose>
<when test="parentId ==0">
parent_category_id = #{category}
</when>
<otherwise>
category_id = #{category}
</otherwise>
</choose>
</where>
</otherwise>
</choose>
<if test="page>0">
limit #{off_set},#{pageSize}
</if>
</select>
上文中看似十分复杂的动态查询,其实逻辑十分简单:
①定义model对应的class类映射
② 动态sql查询数据然后与数据映射通过反射集合
复杂数据结构
我们以一个带有二级菜单的作为实例
代码语言:javascript复制 data class Menu(val id: Int) {
val name: String? = null
val status: Int = 0
val parent: Int = 0
val link: String? = null
}
data class MainMenu(val id: Int) {
val name: String? = null
val status: Int = 0
val parent: Int = 0
val link: String? = null
open var subs: List<Menu> = mutableListOf()
}
上面是一个稍微复杂的数据结构,对应的mapper映射会要想表达出MainMenu的方式需要用到collection这个方式,代码如下
代码语言:javascript复制 <resultMap id="menu" type="app.entity.MainMenu">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="status" property="status"/>
<result column="parent" property="parent"/>
<result column="link" property="link"/>
<collection property="subs" ofType="app.entity.Menu">
<id column="child_id" property="id"/>
<result column="child_name" property="name"/>
<result column="child_status" property="status"/>
<result column="child_parent" property="parent"/>
<result column="child_link" property="link"/>
</collection>
</resultMap>
无论是单一还是负责的映射模型定义,我们发现我们给的都是有构造函数的模型名义而在Java中使用话我们的模型定义往往是不需要指定构造函数的。然鹅我们能否在Kotlin也这么定义呢?加入你采用data class的方式那么你就必须要有构造函数针对数据库有id的方式最好的建议就是基于id的唯一构造参数定义模型(如我们文中的)
使用了collection方式踩坑,我们在举个associate的方式将主要的坑踩完,内ring我们不细说,自己慢慢体会,遇到了可以做个参考
代码语言:javascript复制data class Resource(var id: Int) {
constructor():this(id=0)
var status: Int = 0
var link: String?=null
var movieId: Int = 0
var type:ResourceType? = null
}
data class ResourceType(val id:Int = 0) {
var type: String =""
}
<resultMap id="resource" type="app.entity.Resource">
<id column="id" javaType="java.lang.Integer"/>
<result column="status" property="status"/>
<result column="link" property="link"/>
<result column="movie_id" property="movieId"/>
<association property="type" javaType="app.entity.ResourceType">
<id column="type_id" property="id"/>
<result property="type" column="type_type"/>
</association>
</resultMap>
<select id="resourceByMovieId" resultMap="resource">
select app_resource.*, app_resource_type.id type_id, app_resource_type.type type_type from app_resource , app_resource_type where movie_id = #{movieId} and app_resource_type.id = app_resource.type
</select>