Kotlin – Exposed框架入门


简介

  Exposed1是JetBrains官方支持的SQL/ORM框架,风格颇为类似Django ORM,并且充分发挥了Kotlin的强类型优势。而且简单易学。

配置

  这里采用Gradle来构建项目,相关配置如下:

buildscript {
    ext.kotlin_version = '1.2.31'
    //使用国内阿里云的仓库,mavenCentral在国内实在太慢了
    repositories {
        //mavenCentral()
        maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
        maven { url 'https://plugins.gradle.org/m2/' }
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
allprojects {
    repositories {
        maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
        maven { url 'https://plugins.gradle.org/m2/' }
    }
}

group 'sino_crazy_snail'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'kotlin'


sourceCompatibility = 1.8

repositories {
    //mavenCentral()
    maven {
        url  "https://dl.bintray.com/kotlin/exposed"//添加Exposed源
    }
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    compile 'org.jetbrains.exposed:exposed:0.10.1'
    compile ("mysql:mysql-connector-java:5.1.46")
    compile "org.apache.poi:poi:3.14"//apache的这两个库用来解析Excel文档
    compile "org.apache.poi:poi-ooxml:3.14"
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

数据表


  我们要的数据只有时间、账目分类、账目金额以及账目备注这些信息。

代码

import org.jetbrains.exposed.sql.Table

/** * @Author sino_crazy_snail@qq.com * @Create on: 2018-03-27 */
//使用单例创建数据表的模版
object Money_Data : Table() {
    val time = datetime("time").primaryKey()
    val item = varchar("item",50).primaryKey()//账目分类
    val money = varchar("money", 8).primaryKey()
    val remark = text("remark")
}

Bean:

import org.joda.time.DateTime

/** * @Author sino_crazy_snail@qq.com * @Create on: 2018-03-27 */

data class ItemInfo(val time: DateTime, val item: String, val money: String, val remark: String)

解析Excel:

import bean.ItemInfo
import dao.Money_Data
import org.apache.poi.ss.usermodel.DataFormatter
import org.apache.poi.ss.usermodel.Workbook
import org.apache.poi.ss.usermodel.WorkbookFactory
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.SchemaUtils.create
import org.jetbrains.exposed.sql.StdOutSqlLogger
import org.jetbrains.exposed.sql.batchInsert
import org.jetbrains.exposed.sql.transactions.transaction
import org.joda.time.DateTime
import java.io.File
import java.text.SimpleDateFormat
import java.util.*

/** * @Author sino_crazy_snail@qq.com * @Create on: 2018-03-27 */
class ParseExcelMoneyData(file: File) {
    private val wb: Workbook
    private val formatter: DataFormatter
    private val dateFormatter: SimpleDateFormat
    val items: MutableList<ItemInfo>

    init {
        items = ArrayList()
        wb = WorkbookFactory.create(file)
        //wb = XSSFWorkbook(file) //如果是.xlsx格式的Excel,则用这一行
        formatter = DataFormatter()
        dateFormatter = SimpleDateFormat("yyyy-MM-dd")
    }

    fun parseItemsInfo(sheetIndex: Int = 0) {
        val sheet = wb.getSheetAt(sheetIndex)
        for (row_index in 1..sheet.lastRowNum) {//第0行是表单,我们不用,所以下标从一开始
            val row = sheet.getRow(row_index)
            val time = DateTime(
                    dateFormatter.parse(
                            formatter.formatCellValue(row.getCell(0))).time)
            val item = formatter.formatCellValue(row.getCell(5))
            val money = formatter.formatCellValue(row.getCell(6))
            val remark = formatter.formatCellValue(row.getCell(8))
            items.add(ItemInfo(time = time, item = item,
                    money = money, remark = remark))
        }
    }
}

主函数:

fun main(args: Array<String>) {
    val (user, password) = with(Scanner(System.`in`)) {//获取用户名和密码
        println("enter user and password :")
        return@with (next() to next())
    }
    val db = Database.connect(user = user,//连接数据库
            password = password,
            url = "jdbc:mysql://localhost/ktdb",
            driver = "com.mysql.jdbc.Driver")
    val file_path = "F:\\moneydata\\2018_03_06.xls"
    val parse = ParseExcelMoneyData(File(file_path))
    parse.parseItemsInfo()//解析Excel // parse.items.map { println(it) }//打印集合
    val itemInfos = parse.items
    transaction(db) {//操纵数据库
        logger.addLogger(StdOutSqlLogger)//添加日志,输出到标准输出
        create(Money_Data)//创建表
        Money_Data.batchInsert(itemInfos) {//(batchInsert函数参数是一个可迭代的对象)插入数据
            this[Money_Data.time] = it.time
            this[Money_Data.item] = it.item
            this[Money_Data.money] = it.money
            this[Money_Data.remark] = it.remark
        }
    }
}

运行结果

mysql> desc money_data; +--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+
| time   | datetime(6) | NO   | PRI | NULL    |       |
| item   | varchar(50) | NO   | PRI | NULL    |       |
| money  | varchar(8)  | NO   | PRI | NULL    |       |
| remark | text | NO | | NULL | | +--------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
mysql> select * from money_data; +----------------------------+----------+-------+------------+
| time | item | money | remark | +----------------------------+----------+-------+------------+
| 2018-03-03 00:00:00.000000 | 夜宵     | -5    |            |
| 2018-03-03 00:00:00.000000 | 打车     | -12   |            |
| 2018-03-04 00:00:00.000000 | 午餐     | -6.7  |            |
| 2018-03-04 00:00:00.000000 | 晚餐     | -5.7  |            |
| 2018-03-04 00:00:00.000000 | 服饰     | -152  | 两件衣服   |
| 2018-03-04 00:00:00.000000 | 水果     | -9    |            |
| 2018-03-04 00:00:00.000000 | 洗澡水   | -1.22 |            |
| 2018-03-04 00:00:00.000000 | 美容美发 | -18   |            |
| 2018-03-04 00:00:00.000000 | 购物     | -111  | 两副练字帖 |
| 2018-03-04 00:00:00.000000 | 鞋帽     | -22.5 | 拖鞋和纸巾 |
| 2018-03-05 00:00:00.000000 | 午餐     | -7    |            |
| 2018-03-05 00:00:00.000000 | 早餐     | -6    |            |
| 2018-03-05 00:00:00.000000 | 晚餐     | -7.5  |            |
| 2018-03-05 00:00:00.000000 | 洗澡水   | -1.64 |            |
| 2018-03-05 00:00:00.000000 | 话费网费 | -100  |            |
| 2018-03-06 00:00:00.000000 | 午餐     | -8    |            |
| 2018-03-06 00:00:00.000000 | 早餐     | -3.5  |            |
| 2018-03-06 00:00:00.000000 | 晚餐     | -6.5  |            |
| 2018-03-06 00:00:00.000000 | 洗澡水 | -2.19 | | +----------------------------+----------+-------+------------+
19 rows in set (0.00 sec)