做课设的时候摸索了好一阵子使用kotlin语言连接阿里云Mysql的方法,现在放出来供其他新手参考少走写弯路。
目录
实现步骤
1.配置阿里云数据库
登录阿里云账号->阿里云官网
购买或者申请一个云数据库RDS MySQL版(我是免费申请使用三个月) ->申请免费试用阿里云官网
配置结束后,即可点击控制台,点击云数据库RDS
点击实例列表,可以看到刚刚申请的数据库实例正在创建中,等待创建完毕。
创建完毕后,点击蓝色实例ID
进入后,在基本信息中点击设置白名单
修改default,将 0.0.0.0/0 加入白名单
返回实例列表界面,点击右侧数据库连接,开通外网地址(后续Android端使用的IP地址即为外网地址)
接着点击左侧账号管理,创建数据库账号,记录数据库账号密码,我的账号名为mac_mysql
至此,创建配置完成。右上角点击登录数据库。
输入账号密码后,即可进入数据库界面,点击数据库实例查看刚刚创建的账号
在SQL Console中使用建表语句,新建一个users表(注意,id为自增主键,后续编程时不用插入id,这点还是一位叫ZCG的大佬提醒的)
CREATE TABLE IF NOT EXISTS users (
user_id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL
)
点击执行,成功后可以看见新的表。
现在我们就已经完成了对数据库的所有配置了。SQL Console中可以点击数据可视化,输入“SELECT * FROM `users`”查询表users,点击执行后即可查看表内所有内容。
现在表中暂无数据,我们开始启动Android连接数据库。
2.Android代码
编写代码前,我们先进行清单文件和gradle配置。
1.在AndroidManifest.xml中加入网络权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
2.点开app模块的build.gradle.kts加入依赖。(注意,我使用的版本为5.1.47,若版本不匹配会造成错误:java.sql.SQLException: Unknown system variable ‘query_cache_size')
implementation ("mysql:mysql-connector-java:5.1.47")
刚刚用的是库依赖,也可以使用文件依赖,去MySQL官网上自行下载需要的版本MySQL依赖下载
将下载完的包直接复制进libs目录,右击后点击ADD AS LIBRARY,查看app模块的build.gradle.kts若出现类似下面的代码,即完成配置。(库依赖和文件依赖不要一起使用)
implementation files('libs/test_android_sdk_release_1_0_1.jar')//样例,文件不一样
完成上面两步后,就正式进入代码编写阶段。我先丢一个小例子只实现插入功能,不想浪费时间的直接跳过,后面有实现登录的代码。
MainActivity类
package com.example.testmysql
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import java.sql.Connection
import java.sql.DriverManager
import java.sql.PreparedStatement
import java.sql.SQLException
class MainActivity : AppCompatActivity() {
// 声明 UI 元素
private lateinit var etUserId: EditText
private lateinit var etUsername: EditText
private lateinit var etPassword: EditText
private lateinit var btnInsertData: Button
private lateinit var tvResult: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 初始化 UI 元素
etUserId = findViewById(R.id.etUserId)
etUsername = findViewById(R.id.etUsername)
etPassword = findViewById(R.id.etPassword)
btnInsertData = findViewById(R.id.btnInsertData)
tvResult = findViewById(R.id.tvResult)
// 为插入按钮设置点击监听器
btnInsertData.setOnClickListener {
Thread(Runnable {
val userId = etUserId.text.toString()
val username = etUsername.text.toString()
val password = etPassword.text.toString()
val sql = "INSERT INTO users (username, password) VALUES (?, ?)" //使用插入语句,向数据库中插入用户名和密码
try {
val connection = establishConnection()
executeInsert(connection, sql, userId, username, password)
executeQuery(connection, "SELECT * FROM users") // 使用查询语句,查询users表,并显示更新后的数据
} catch (e: SQLException) {
e.printStackTrace()
updateTextView("连接数据库时发生错误。")
}
}).start()
}
}
// 建立数据库连接的函数
private fun establishConnection(): Connection {
Class.forName("com.mysql.jdbc.Driver") //若依赖包版本过高可能要改为com.mysql.jc.jdbc.Driver
return DriverManager.getConnection(
"jdbc:mysql://你自己的阿里云数据外网地址:3306/数据库的名称",
"你的数据库账号名", "密码"
)
}
// 执行 INSERT 查询的函数
private fun executeInsert(connection: Connection, sql: String, userId: String, username: String, password: String) {
val preparedStatement: PreparedStatement = connection.prepareStatement(sql)
preparedStatement.setString(1, username)
preparedStatement.setString(2, password)
preparedStatement.executeUpdate()
preparedStatement.close()
}
// 执行 SELECT 查询并更新 TextView 的函数
private fun executeQuery(connection: Connection, sql: String) {
val statement = connection.createStatement()
val resultSet = statement.executeQuery(sql)
val resultStringBuilder = StringBuilder()
while (resultSet.next()) { //将收到的消息分为三个模块
val message =
"user_id: ${resultSet.getString("user_id")}, " +
"username: ${resultSet.getString("username")}, " +
"password: ${resultSet.getString("password")}"
// 将消息附加到 StringBuilder
resultStringBuilder.append(message).append("\n")
}
// 关闭资源
resultSet.close()
statement.close()
connection.close()
// 使用接收到的数据更新 TextView
runOnUiThread {
tvResult.text = resultStringBuilder.toString()
}
}
// 更新 TextView 的函数
private fun updateTextView(message: String) {
runOnUiThread {
tvResult.text = message
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/etUserId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="ID,不用插入" />
<EditText
android:id="@+id/etUsername"
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_below="@id/etUserId"
android:layout_marginTop="15dp"
android:hint="输入想插入的用户名" />
<EditText
android:id="@+id/etPassword"
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_below="@id/etUsername"
android:layout_marginTop="16dp"
android:hint="输入想插入的密码"
android:inputType="textPassword" />
<Button
android:id="@+id/btnInsertData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/etPassword"
android:layout_marginTop="16dp"
android:text="插入数据" />
<TextView
android:id="@+id/tvResult"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/btnInsertData"
android:layout_marginTop="16dp"
android:text="结果显示" />
</RelativeLayout>
成功界面展示:
其实登录也就是在插入的基础上多一个查询,匹配表内的信息罢了。
直接上代码,分为login,MainActivity,MySQLHelper,RegisterActivity四个类,分别负责登录界面,登录成功后的展示界面,提供数据库连接方法,注册界面。
login类
package com.example.testmqsql
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class login : AppCompatActivity() {
private val mySQLHelper = MySQLHelper()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
val usernameEditText: EditText = findViewById(R.id.usernameEditText)
val passwordEditText: EditText = findViewById(R.id.passwordEditText)
val loginButton: Button = findViewById(R.id.loginButton)
val registerButton: Button = findViewById(R.id.registerButton)
loginButton.setOnClickListener {
val username = usernameEditText.text.toString()
val password = passwordEditText.text.toString()
CoroutineScope(Dispatchers.Main).launch {
val isLoginSuccessful = withContext(Dispatchers.IO) {
mySQLHelper.checkLogin(username, password)
}
if (isLoginSuccessful) {
// Successful login, navigate to another activity
val intent = Intent(this@login, MainActivity::class.java)
startActivity(intent)
} else {
// Failed login, show error message
Toast.makeText(this@login, "账号密码错误!请重新输入!", Toast.LENGTH_SHORT).show()
}
}
}
registerButton.setOnClickListener {
// Navigate to registration activity
val intent = Intent(this, RegisterActivity::class.java)
startActivity(intent)
}
}
override fun onDestroy() {
super.onDestroy()
// Close the database connection when the activity is destroyed
CoroutineScope(Dispatchers.IO).launch {
}
}
}
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingTop="16dp"
android:paddingRight="16dp"
android:paddingBottom="16dp"
>
<EditText
android:id="@+id/usernameEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入用户名"/>
<EditText
android:id="@+id/passwordEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/usernameEditText"
android:layout_marginTop="8dp"
android:inputType="textPassword"
android:hint="请输入密码"/>
<Button
android:id="@+id/loginButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/passwordEditText"
android:layout_marginTop="16dp"
android:text="登录"/>
<Button
android:id="@+id/registerButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/loginButton"
android:layout_marginTop="8dp"
android:text="注册"/>
</RelativeLayout>
MainActivity
package com.example.testmqsql
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingTop="16dp"
android:paddingRight="16dp"
android:paddingBottom="16dp"
>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="恭喜你登录成功!"
></TextView>
</RelativeLayout>
MySQLHelper(加入自己的信息)
package com.example.testmqsql
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.sql.Connection
import java.sql.DriverManager
import java.sql.PreparedStatement
import java.sql.ResultSet
class MySQLHelper {
private val dbUrl = "jdbc:mysql://你自己的阿里云外网地址:3306/你的数据库名"
private val username = "数据库的用户名"
private val password = "数据库密码"
suspend fun establishConnection(): Connection = withContext(Dispatchers.IO) {
Class.forName("com.mysql.jdbc.Driver")
DriverManager.getConnection(dbUrl, username, password)
}
suspend fun insertUser(username: String, password: String) {
withContext(Dispatchers.IO) {
val connection = establishConnection()
val sql = "INSERT INTO users (username, password) VALUES (?, ?)" //建表语句,向users表内插入用户名和密码
try {
val preparedStatement: PreparedStatement = connection.prepareStatement(sql)
preparedStatement.setString(1, username)
preparedStatement.setString(2, password)
preparedStatement.executeUpdate()
} finally {
connection.close()
}
}
}
suspend fun checkLogin(username: String, password: String): Boolean = withContext(Dispatchers.IO) {
val connection = establishConnection()
val sql = "SELECT * FROM users WHERE username=? AND password=?" //查询语句
var result = false
try {
val preparedStatement: PreparedStatement = connection.prepareStatement(sql)
preparedStatement.setString(1, username)
preparedStatement.setString(2, password)
val resultSet: ResultSet = preparedStatement.executeQuery()
result = resultSet.next()
} finally {
connection.close()
}
result
}
}
RegisterActivity
package com.example.testmqsql
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
class RegisterActivity : AppCompatActivity() {
private val mySQLHelper = MySQLHelper()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register)
val registerUsernameEditText: EditText = findViewById(R.id.registerUsernameEditText)
val registerPasswordEditText: EditText = findViewById(R.id.registerPasswordEditText)
val confirmRegisterButton: Button = findViewById(R.id.confirmRegisterButton)
confirmRegisterButton.setOnClickListener {
val username = registerUsernameEditText.text.toString()
val password = registerPasswordEditText.text.toString()
CoroutineScope(Dispatchers.Main).launch {
withContext(Dispatchers.IO) {
mySQLHelper.insertUser(username, password)
}
// Show a Toast message indicating successful registration
Toast.makeText(this@RegisterActivity, "注册成功!", Toast.LENGTH_SHORT).show()
// Finish the registration activity
finish()
}
}
}
override fun onDestroy() {
super.onDestroy()
// Close the database connection when the activity is destroyed
CoroutineScope(Dispatchers.IO).launch {
}
}
}
activity_register.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingTop="16dp"
android:paddingRight="16dp"
android:paddingBottom="16dp"
tools:context=".RegisterActivity">
<EditText
android:id="@+id/registerUsernameEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入用户名"/>
<EditText
android:id="@+id/registerPasswordEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/registerUsernameEditText"
android:layout_marginTop="8dp"
android:inputType="textPassword"
android:hint="请输入密码"/>
<Button
android:id="@+id/confirmRegisterButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/registerPasswordEditText"
android:layout_marginTop="16dp"
android:text="确认注册"/>
</RelativeLayout>
完成啦!恭喜你!
觉得有用的话就点个赞吧!
第一次分享,若有不足请指出!
实现效果
注册1,1后登录