上一篇
安卓如何连接数据库服务器
- 行业动态
- 2025-04-21
- 2
安卓连接数据库服务器的实现方案
直接连接数据库(不推荐)
理论上安卓可以通过JDBC直接连接远程数据库,但存在安全风险和网络限制,实际开发中极少采用。
步骤 | 实现方式 | 风险提示 |
---|---|---|
添加依赖 | implementation 'mysql:mysql-connector-java:8.0.33' 需在 build.gradle 中配置 |
移动端直接暴露数据库端口存在安全破绽 |
配置连接参数 | “`java |
String url = “jdbc:mysql://服务器IP:3306/数据库名”;
Properties props = new Properties();
props.setProperty(“user”,”用户名”);
props.setProperty(“password”,”密码”);
Connection conn = DriverManager.getConnection(url, props);
| 3. 异步执行 | 必须使用`AsyncTask`或`Thread`处理<br>示例:`new Thread(() -> { /数据库操作/ }).start();` | 主线程操作会抛出`NetworkOnMainThreadException` |
# 二、推荐方案:通过后端服务连接(REST API)
架构图示:
Android客户端 <–REST API–> 应用服务器 <–JDBC–> 数据库服务器
## 1. 后端服务搭建(以Spring Boot为例)
| 功能模块 | 实现代码 | 作用说明 |
|----------|----------|----------|
| 数据源配置 | ```java
@Bean
public DataSource dataSource() {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:mysql://localhost:3306/db");
ds.setUsername("root");
ds.setPassword("123456");
return ds;
}
``` | 管理数据库连接池 |
| REST接口 | ```java
@RestController
@RequestMapping("/api")
public class UserController {
@Autowired
private UserRepository userRepo;
@GetMapping("/users")
public List<User> getUsers() {
return userRepo.findAll();
}
}
``` | 提供标准HTTP接口 |
## 2. Android端调用(Retrofit+Gson示例)
| 步骤 | 关键代码 | 说明 |
|------|----------|------|
| 1. 添加依赖 | ```gradle
implementation 'com.squareup.retrofit2:retrofit:2.9.0'<br>
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
``` | Retrofit网络库+Gson解析 |
| 2. 定义API接口 | ```java
public interface ApiService {
@GET("/api/users")
Call<List<User>> getUsers();
}
``` | 与后端接口对应 |
| 3. 创建Retrofit实例 | ```java
Retrofit retrofit = new Retrofit.Builder()<br>
.baseUrl("http://服务器IP:8080")<br>
.addConverterFactory(GsonConverterFactory.create())<br>
.build();
``` | 配置基础URL和转换器 |
| 4. 异步请求数据 | ```java
ApiService api = retrofit.create(ApiService.class);<br>
Call<List<User>> call = api.getUsers();<br>
call.enqueue(new Callback<List<User>>() {<br>
@Override<br>
public void onResponse(Call<List<User>> call, Response<List<User>> response) {<br>
// 处理返回数据<br>
}<br>
@Override<br>
public void onFailure(Call<List<User>> call, Throwable t) {<br>
// 处理错误<br>
}<br>
});
``` | 避免阻塞主线程 |
# 三、安全加固措施
| 防护类型 | 实施方案 |
|----------|----------|
| 传输加密 | 后端启用HTTPS<br>`server.port=8443<br>server.ssl.key-store=classpath:keystore.p12` |
| 身份验证 | JWT Token验证<br>```java
@RestController
public class AuthController {
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody UserCredentials credentials) {
// 验证后生成JWT
}
}
``` |
| IP白名单 | 服务器防火墙仅允许可信IP访问<br>`iptables -A INPUT -s 192.168.1.100 -j ACCEPT` |
# 四、常见问题解决方案
| 问题现象 | 解决方案 |
|----------|----------|
| 连接超时 | 检查服务器防火墙设置<br>确保路由器映射正确端口 |
| SSL证书不信任 | 将自签名证书导入安卓信任库<br>```java
CertificateFactory cf = CertificateFactory.getInstance("X.509");<br>
InputStream cert = context.getResources().openRawResource(R.raw.my_cert);<br>
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());<br>
ks.load(null, null);<br>
ks.setCertificateEntry("ca-cert", cf.generateCertificate(cert));<br>
``` |
| 跨域问题 | 后端添加CORS支持<br>```java
@CrossOrigin(origins = "http://安卓客户端IP:端口")<br>
@RestController<br>
public class MyController {}
``` |
相关问题与解答
# Q1:如何防止数据库连接信息泄露?
A1:三重防护措施:
1. 后端API不直接传递数据库账号,使用连接池管理
2. 敏感配置存入环境变量(如`.env`文件)
3. Android端使用ProGuard混淆代码,防止逆向破解
# Q2:如何处理高并发下的数据库连接?
A2:优化方案:
1. 后端使用HikariCP连接池,配置最大连接数(如`maximumPoolSize=20`)
2. 安卓端使用OkHttp连接池复用TCP连接
3. 数据库端开启查询缓存(如MySQL的`query_cache_size`参数