kotlin以jdbc的方式连接操作SQLite数据库

首先要做的事是在build.gradle中引入jdbc驱动包的依赖:

implementation "org.xerial:sqlite-jdbc:3.32.3.2"

引入依赖包后,就可以写代码了,这里我封装了一个获取数据库连接并执行数据库操作的方法

    private const val url = "jdbc:sqlite:resources/static/file/hyjiao.db"
    /**
    * 获取数据库连接并执行数据库操作
    */
    private fun dose(block: (Connection) -> Unit) {
        try {
            DriverManager.getConnection(url).use {
                block(it)
            }
        } catch (e: SQLException) {
            System.err.println(e.message)
        }
    }

url中resources/static/file/hyjiao.db是我的SQLite数据库在项目中的相对路径,写绝对路径当然也是可以的。
写一个update方法,用于更新类型的操作:

    /**
     * 支持drop table、create table、insert into、update……等sql语句
     * @param sql 数据库查询语句
     * @param params PreparedStatement使用的参数
     * @param timeout 超时时间
     * @param block 接收返回的每一行数据
     */
    fun update(sql: String, params: Array<Any?>? = null, timeout: Int = 30): Boolean {
        var state = 0
        dose {
            if (params != null) {
                val statement = getPreparedStatement(it, sql, timeout, params)
                state = statement.executeUpdate()
            } else {
                val statement = it.createStatement()
                statement.queryTimeout = timeout
                state = statement.executeUpdate(sql)
            }
        }
        return state > 0
    }

根据是否传参数来选择使用PreparedStatement或Statement,PreparedStatement可以防止sql注入攻击,Statement没有这个功能。
再写一个query方法,用于查询操作:

    /**
     * 查询操作
     * @param sql 数据库查询语句
     * @param params PreparedStatement使用的参数
     * @param timeout 超时时间
     * @param block 接收返回的每一行数据
     */
    fun query(sql: String, params: Array<Any?>? = null, timeout: Int = 30, block: (ResultSet) -> Unit) {
        dose {
            if (params != null) {
                //使用PreparedStatement
                val statement = getPreparedStatement(it, sql, timeout, params)
                val rs = statement.executeQuery()
                while (rs.next()) {
                    block(rs)
                }
            } else {
                //使用Statement
                val statement = it.createStatement()
                statement.queryTimeout = timeout
                val rs = statement.executeQuery(sql)
                while (rs.next()) {
                    block(rs)
                }
            }
        }
    }

getPreparedStatement方法获取PreparedStatement并设置参数

    /**
     * 获取PreparedStatement并设置参数
     */
    private fun getPreparedStatement(
        it: Connection,
        sql: String,
        timeout: Int,
        params: Array<Any?>
    ): PreparedStatement {
        val statement = it.prepareStatement(sql)
        statement.queryTimeout = timeout
        for (i in 1..params.size) {
            when (val a = params[i - 1]) {
                null -> statement.setNull(i, Types.NULL)
                is String -> {
                    when {
                        RegexUtil.isTimestamp(a) -> {
                            statement.setTimestamp(i, Timestamp.valueOf(a))
                        }
                        RegexUtil.isShortDate(a) -> {
                            statement.setDate(i, Date.valueOf(a))
                        }
                        RegexUtil.isShortTime(a) -> {
                            statement.setTime(i, Time.valueOf(a))
                        }
                        else -> {
                            statement.setString(i, a)
                        }
                    }
                }
                is Boolean -> statement.setBoolean(i, a)
                is Byte -> statement.setByte(i, a)
                is Short -> statement.setShort(i, a)
                is Int -> statement.setInt(i, a)
                is Long -> statement.setLong(i, a)
                is Float -> statement.setFloat(i, a)
                is Double -> statement.setDouble(i, a)
                is BigDecimal -> statement.setBigDecimal(i, a)
                is ByteArray -> statement.setBytes(i, a)
                is Date -> statement.setDate(i, a)
                is Time -> statement.setTime(i, a)
                is Timestamp -> statement.setTimestamp(i, a)
                else -> statement.setString(i, a.toString())
            }
        }
        return statement
    }

上面这段代码写的比较啰嗦,其实可以写少一些类型判断的。
向数据库表中插入数据

val user = User("hyjiao","123456")
val sql = "insert into User(name,password) values(?,?)"
val flag = DBUtil.update(sql, arrayOf(user.name, user.password))

查询操作

val name = "hyjiao"
var user: User? = null
val sql = "select * from User where name=?"
DBUtil.query(sql, arrayOf(name)) {
    user = User(it.getString("name"), it.getString("password"), it.getInt("id"))
}

Comment

您的电子邮箱地址不会被公开。 必填项已用 * 标注