上一篇
安卓开发怎么连数据库
- 行业动态
- 2025-04-22
- 2
安卓连接数据库的实现方式
本地数据库(SQLite/Room)
SQLite
- 特点:安卓内置轻量级数据库,支持SQL语法,适合存储少量结构化数据。
- 步骤:
- 创建
SQLiteOpenHelper
子类,重写onCreate()
和onUpgrade()
方法。 - 通过
getWritableDatabase()
获取数据库实例。 - 使用
SQLiteDatabase
的增删改查方法(如insert()
、query()
)。
- 创建
- 代码示例:
public class MyDBHelper extends SQLiteOpenHelper { public MyDBHelper(Context context) { super(context, "test.db", null, 1); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE user (id INTEGER PRIMARY KEY, name TEXT)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 更新逻辑 } }
Room持久化库
- 特点:基于SQLite的抽象层,提供编译时校验,支持LiveData响应式编程。
- 优势:避免手写SQL,减少运行时错误,简化多表操作。
- 步骤:
- 添加依赖:
implementation "androidx.room:room-runtime:2.5.1"
- 定义
@Entity
实体类,标注@PrimaryKey
。 - 创建
@Dao
接口,定义增删改查方法。 - 创建
RoomDatabase
子类并初始化。
- 添加依赖:
- 代码示例:
@Entity public class User { @PrimaryKey(autoGenerate = true) public int id; public String name; } @Dao public interface UserDao { @Insert void insert(User user); @Query("SELECT FROM User") List<User> getAll(); } @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
远程数据库(MySQL/PostgreSQL等)
直接连接(不推荐)
- 风险:直接暴露数据库IP和端口可能导致安全破绽,且需处理主线程网络限制。
- 实现方式:
- 添加JDBC驱动依赖(如
mysql-connector-java
)。 - 在子线程中通过
DriverManager.getConnection()
连接数据库。
- 添加JDBC驱动依赖(如
- 代码示例:
new Thread(() -> { try { Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://ip:port/db", "user", "password"); // 执行SQL语句 } catch (Exception e) { e.printStackTrace(); } }).start();
通过API间接操作(推荐)
- 流程:安卓 → RESTful API(如Retrofit+Spring Boot) → 远程数据库。
- 优势:隐藏数据库细节,提高安全性,便于扩展和维护。
- 实现步骤:
- 后端提供CRUD接口(如
/user/add
)。 - 安卓使用Retrofit或OkHttp发送HTTP请求。
- 解析JSON响应并更新UI。
- 后端提供CRUD接口(如
- 代码示例(Retrofit):
public interface ApiService { @POST("/user/add") Call<User> addUser(@Body User user); } // 使用Retrofit.Builder初始化并调用接口
常见问题与解决方案
问题 | 解决方案 |
---|---|
主线程网络操作崩溃 | 使用异步任务(AsyncTask、Coroutine、RxJava)或WorkManager处理网络请求。 |
SQL注入攻击 | 使用参数化查询(占位符),或通过API层过滤输入数据。 |
本地与远程数据同步 | 利用Room的TypeConverters 或自定义同步逻辑,结合LiveData实时更新。 |
数据库文件过大 | 定期清理无用数据,或分表存储(如按时间分区)。 |
相关问题与解答
问题1:Room相比SQLite的优势是什么?
解答:
- 编译时校验:Room在编译阶段检查SQL语句和实体类映射,减少运行时错误。
- 简化代码:通过注解自动生成DAO实现类,无需手写
ContentValues
或Cursor
。 - 响应式支持:结合LiveData实现数据库变更的自动通知(如
@Query("SELECT FROM user") LiveData<List<User>>
)。 - 类型安全:避免因字段类型不匹配导致的崩溃。
问题2:如何通过Retrofit调用带参数的API接口?
解答:
- 定义接口方法:使用
@Query
或@Path
标注动态参数。public interface ApiService { @GET("/user/search") Call<List<User>> searchUser(@Query("name") String name); }
- 传递参数:调用接口方法时传入实际参数。
ApiService apiService = retrofit.create(ApiService.class); Call<List<User>> call = apiService.searchUser("John");
- 处理响应:通过
enqueue
异步获取结果。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) { // 处理失败逻辑 } });