当前位置:首页 > 行业动态 > 正文

安卓开发连接sql数据库连接

安卓本地SQLite数据库连接

创建数据库帮助类

安卓内置支持SQLite,通过SQLiteOpenHelper实现数据库创建与升级。

public class DatabaseHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "app_data.db";
    private static final int DATABASE_VERSION = 1;
    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        // 创建表结构
        String createTable = "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)";
        db.execSQL(createTable);
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // 数据库升级逻辑(如表结构变更)
        db.execSQL("DROP TABLE IF EXISTS users");
        onCreate(db);
    }
}

基本CRUD操作

// 插入数据
ContentValues values = new ContentValues();
values.put("name", "Alice");
values.put("age", 25);
database.insert("users", null, values);
// 查询数据
Cursor cursor = database.query("users", null, null, null, null, null, null);
if (cursor.moveToFirst()) {
    do {
        int id = cursor.getInt(cursor.getColumnIndex("id"));
        String name = cursor.getString(cursor.getColumnIndex("name"));
        int age = cursor.getInt(cursor.getColumnIndex("age"));
        // 处理数据
    } while (cursor.moveToNext());
}
cursor.close();

连接远程SQL数据库(如MySQL/SQL Server)

架构设计

安卓无法直接连接远程数据库,需通过中间层服务(如REST API)进行交互。

!架构图
图:安卓与远程数据库交互架构

安卓开发连接sql数据库连接

后端接口示例(PHP)

// api.php(MySQL示例)
$host = 'localhost';
$db = 'test_db';
$user = 'root';
$pass = 'password';
$conn = new mysqli($host, $user, $pass, $db);
$json = file_get_contents('php://input');
$data = json_decode($json, true);
// 查询示例
$sql = "SELECT  FROM users WHERE id = $data[id]";
$result = $conn->query($sql);
$row = $result->fetch_assoc();
echo json_encode($row);

安卓端网络请求(Retrofit示例)

// 定义API接口
public interface ApiService {
    @GET("users")
    Call<List<User>> getUsers();
}
// 使用Retrofit发起请求
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://yourserver.com/api/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
ApiService apiService = retrofit.create(ApiService.class);
Call<List<User>> call = apiService.getUsers();
call.enqueue(new Callback<List<User>>() {
    @Override
    public void onResponse(Call<List<User>> call, Response<List<User>> response) {
        // 处理返回数据
    }
    @Override
    public void onFailure(Call<List<User>> call, Throwable t) {
        // 处理错误
    }
});

关键差异对比表

特性 本地SQLite 远程数据库(MySQL/SQL Server)
部署位置 应用安装目录(/data/data/包名/) 独立服务器(需域名/IP+端口)
网络依赖 必须联网
并发处理 单设备访问 多设备并发(需考虑连接池/事务隔离)
数据同步 实时可用 需设计同步机制(如时间戳/版本号)
典型场景 轻量级本地存储(如缓存、配置) 多端共享数据、复杂业务逻辑

安全注意事项

  1. 参数化查询:防止SQL注入

    // 错误示例(易被注入)
    String sql = "SELECT  FROM users WHERE name = '" + userInput + "'";
    // 正确示例(使用?占位符)
    String sql = "SELECT  FROM users WHERE name = ?";
    PreparedStatement pstmt = conn.prepareStatement(sql);
    pstmt.setString(1, userInput);
  2. 传输加密:强制使用HTTPS

    <!-AndroidManifest.xml -->
    <application>
        <network-security-config>
            <domain-config cleartextTrafficPermitted="false">
                <domain includeSubdomains="true">yourserver.com</domain>
            </domain-config>
        </network-security-config>
    </application>
  3. 权限控制:后端API需验证Token/Session

    安卓开发连接sql数据库连接

    // PHP示例:验证JWT Token
    $token = $_SERVER['HTTP_AUTHORIZATION'];
    if (!validateJWT($token)) {
        echo json_encode(['error' => 'Unauthorized']);
        exit;
    }

相关问题与解答

Q1:为什么安卓不能直接用JDBC连接远程数据库?

A

  1. 安全性:直接暴露数据库IP和端口会导致未授权访问风险。
  2. 兼容性:不同数据库驱动在安卓端的适配性差(如MySQL驱动体积大)。
  3. 网络限制:多数数据库服务部署在内网,外部访问需额外配置。
  4. 架构规范:违背分层架构原则,耦合度过高,不利于扩展维护。

Q2:如何处理异步数据库操作的UI阻塞问题?

A

  1. 使用异步框架
    • Retrofit结合enqueue方法自动异步回调
    • Kotlin协程withContext(Dispatchers.IO)
    • AsyncTask(已过时,建议用前两者)
  2. 进度指示器:在等待期间显示ProgressBarDialog
  3. 生命周期感知:使用LiveDataViewModel确保UI组件销毁时取消操作
    // Kotlin协程示例
    viewModelScope.launch {
        try {
            val data = withContext(Dispatchers.IO) { apiService.getData() }
            viewModel.updateData(data) // 自动切换到主线程
        } catch (e: Exception) {
            viewModel.showError(e)
        }
    }