上一篇
安卓开发连接sql数据库连接
- 行业动态
- 2025-04-21
- 3101
安卓本地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)进行交互。
!架构图
图:安卓与远程数据库交互架构
后端接口示例(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+端口) |
网络依赖 | 无 | 必须联网 |
并发处理 | 单设备访问 | 多设备并发(需考虑连接池/事务隔离) |
数据同步 | 实时可用 | 需设计同步机制(如时间戳/版本号) |
典型场景 | 轻量级本地存储(如缓存、配置) | 多端共享数据、复杂业务逻辑 |
安全注意事项
参数化查询:防止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);
传输加密:强制使用HTTPS
<!-AndroidManifest.xml --> <application> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">yourserver.com</domain> </domain-config> </network-security-config> </application>
权限控制:后端API需验证Token/Session
// PHP示例:验证JWT Token $token = $_SERVER['HTTP_AUTHORIZATION']; if (!validateJWT($token)) { echo json_encode(['error' => 'Unauthorized']); exit; }
相关问题与解答
Q1:为什么安卓不能直接用JDBC连接远程数据库?
A:
- 安全性:直接暴露数据库IP和端口会导致未授权访问风险。
- 兼容性:不同数据库驱动在安卓端的适配性差(如MySQL驱动体积大)。
- 网络限制:多数数据库服务部署在内网,外部访问需额外配置。
- 架构规范:违背分层架构原则,耦合度过高,不利于扩展维护。
Q2:如何处理异步数据库操作的UI阻塞问题?
A:
- 使用异步框架:
- Retrofit结合
enqueue
方法自动异步回调 - Kotlin协程
withContext(Dispatchers.IO)
AsyncTask
(已过时,建议用前两者)
- Retrofit结合
- 进度指示器:在等待期间显示
ProgressBar
或Dialog
- 生命周期感知:使用
LiveData
或ViewModel
确保UI组件销毁时取消操作// Kotlin协程示例 viewModelScope.launch { try { val data = withContext(Dispatchers.IO) { apiService.getData() } viewModel.updateData(data) // 自动切换到主线程 } catch (e: Exception) { viewModel.showError(e) } }