Ktor 從入門到放棄(四) 資料庫操作
其實這一篇與Ktor
關係不大,主要講一下如何操作資料庫,我們經常使用的資料庫操作方法在 Ktor 裡一樣適用。
還是讓我們先安裝起mysql
吧,在 Ubuntu 下可以這麼做:
$ sudo apt install mysql-server
這裡需要額外提一下,在 Ubuntu 18.04 以後,安裝 mysql 不再提示輸入 root 使用者的密碼,而是要在安裝完成後額外配置。在完成配置前,無法使用 root 使用者登入 mysql。我們需要讀取/etc/mysql/debian.cnf
檔案,如下:
$ sudo cat /etc/mysql/debian.cnf
[client] host= localhost user= debian-sys-maint password = 7hWj7C23Uf5nPHcT socket= /var/run/mysqld/mysqld.sock [mysql_upgrade] host= localhost user= debian-sys-maint password = 7hWj7C23Uf5nPHcT socket= /var/run/mysqld/mysqld.sock
可以看到如上面所示的內容,mysql 為我們分配了預設的密碼,使用預設的資料庫的密碼進行登入並進行修改:
$ mysql -udebian-sys-maint -p7hWj7C23Uf5nPHcT mysql > use mysql; mysql > ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root'; mysql > SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456'); mysql > flush privileges;
完成後即可以使用 root 使用者和密碼 123456 來進行登入了。
接下來回到 Ktor 專案,在 build.gradle 內加入對 mysql 的引用:
compile "mysql:mysql-connector-java:8.0.15"
然後先寫一個定義檔案,來描述如何連線 mysql:
const val JDBC_DRIVER = "com.mysql.jdbc.Driver" const val DB_URL = "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8" const val DB_USER = "root" const val DB_PASSWORD = "123456"
通常情況下,連線字串寫成jdbc:mysql://localhost:3306/mydb
就夠了,後面的引數標識了需要使用 Unicode 以及預設的字元編碼為 UTF-8,當然此處會有個坑,後面再講。
後面的事情就簡單了,按以下操作方式進行就好了,你會發現這些程式碼都很熟悉:
Class.forName(JDBC_DRIVER) val conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD) val stmt = conn.prepareStatement("SELECT * FROM MyTable WHERE id = ?") stmt.setInt(1, 10000) val rs = stmt.executeQuery() while (rs.next()) { println(rs.getString(rs.findColumn("name"))) } rs.close() stmt.close() conn.close()
這樣就完成了一個最簡單的查詢。在實際專案中,為了不頻繁開啟和關閉資料庫連線,通常會將getConnection
的部分用連線池來管理。
好了,下面再來看一個程式碼,簡單的 insert:
val stmt = conn.prepareStatement("INSERT INTO MyTable(user) VALUES (?)") stmt.setString(1, userName) stmt.executeUpdate() stmt.close()
這裡的userName
是從外部傳入的,這不重要,重要的是當這個userName
含有表情或一些特殊符號時,insert 進去的資料是亂碼。這個問題必須被解決,不然那些喜歡在名字或簽名里加表情的同學們就要說話了。
這裡我們選擇的方法是將 mysql 的編碼更改為utf8mb4
,關於這個編碼,網上已有非常多的討論,此處不贅述,我們只需要編寫一個utf8mb4.cnf
並且讓 mysql 載入即可:
[client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci innodb_file_format=barracuda innodb_file_format_max=barracuda innodb_file_per_table=1 innodb_large_prefix=1
把這段程式碼儲存到/etc/mysql/conf.d/utf8mb4.cnf
然後重啟 mysql 即可。
$ sudo service mysql restart
理論上到了這裡也差不多應該結束本篇了,但是考慮到會有不少人需要將資料內容轉換為 json,特此寫個擴充套件,查詢得到的 ResultSet 用它就好了:
fun ResultSet.toJsonArray(): String { var str = "[" if (first()) { do { var item = "{" for (i in 0 until metaData.columnCount) { item += "\"${metaData.getColumnName(i)}\": \"${getString(i)}\"," } item += "}," str += item } while (next()) } str = str.trimEnd(',') str += "]" return str }
上面那個查詢如果改成轉為 JSON 就可以直接這麼寫了:
val rs = stmt.executeQuery() val jsonstr = rs.toJsonArray() rs.close()
下一篇預告:《Ktor 從入門到放棄(五) session 管理與 caching headers》