【Android 远程数据库操作】

按正常情况下,前端不应该直接进行远程数据库操作,这不是一个明智的方式,应该是后端提供对应接口来处理,奈何公司各方面原因需要前端这样做。

对此,我对远程数据库操作做了总结,便于自己复盘,同时,也分享给有需要的朋友们。

0、下载jdbc库

下载mysql官网:https://dev.mysql.com/downloads/connector/j/,按图片步骤下载所需jdbc的库
在这里插入图片描述在这里插入图片描述

1、添加jdbc驱动依赖包

在Android studio的项目工程app-bulid.grade添加依赖:implementation files(‘libs/mysql-connector-java-5.1.48.jar’)或implementation 'mysql:mysql-connector-java:5.1.48’这两种方式
在这里插入图片描述

2、数据库连接操作

			private String DB_URL = "jdbc:mysql://127.0.0.1:3306/远程数据库名";//换成远程地址private String USER = "admin";//账号private String PASS = "123456";	//密码// Step 1: 加载 JDBC driverClass.forName("com.mysql.jdbc.Driver");//mysql高版本这里:com.mysql.cj.jdbc.Driver// Step 2: 打开连接Connection connection = DriverManager.getConnection(DB_URL, USER, PASS);

3、执行数据库语句操作,进行相关业务处理

			String sql = "select name, age, sex from User";// sql语句Statement statement = connection.createStatement();ResultSet rs = statement.executeQuery(sql);while (rs.next() && !isStopped) {// todo 相应业务处理}

4、数据库关闭

			// 操作完毕,数据库关闭rs.close();statement.close();connection.close();

5、完整代码

远程数据库操作工具类DatabaseAccessUtil,由于是耗时动作,需要在线程处理。

public class DatabaseAccessUtil {private static final String TAG = "F100 DatabaseAccess";private String DB_URL = "jdbc:mysql://127.0.0.1:3306/数据库名";private String USER = "admin";private String PASS = "123456";private static DatabaseAccessUtil instance;private ExecutorService executorService;private volatile boolean isStopped = false;private Future<?> currentTask = null; // 用于保存当前的任务private ProgressDialogUtil progressDialogUtil;private Handler mainHandler;private DatabaseAccessUtil() {this.executorService = Executors.newSingleThreadExecutor();mainHandler = new Handler(Looper.getMainLooper());}public static synchronized DatabaseAccessUtil getInstance() {if (instance == null) {instance = new DatabaseAccessUtil();}return instance;}public void start(Context context) {stop();isStopped = false;if (executorService == null || executorService.isShutdown()) {executorService = Executors.newSingleThreadExecutor();}if (!isStopped && !executorService.isShutdown()) {currentTask = executorService.submit(() -> downloadData(context));}}public void stop() {isStopped = true;if (currentTask != null) {currentTask.cancel(true); // 尝试取消当前任务currentTask = null;executorService.shutdownNow(); // 停止执行器服务}}private void showProgressDialog(Context context) {mainHandler.post(() -> {if (progressDialogUtil == null) {progressDialogUtil = new ProgressDialogUtil(context);progressDialogUtil.setOnCancelListener(() -> {stop();});}progressDialogUtil.showProgressDialog();});}// 查询表的总数量private int getTotalCountFromDB(Connection connection) throws SQLException {String sql = "select count(*) from User";Statement statement = connection.createStatement();ResultSet rs = statement.executeQuery(sql);rs.next();int totalCount = rs.getInt(1);rs.close();statement.close();return totalCount;}// 下载数据(相应业务处理)private void downloadData(Context context) {if (isStopped) return;try {String sql = "select name, age, sex from User";// Step 1: Register JDBC driverClass.forName("com.mysql.jdbc.Driver");//mysql高版本这里:com.mysql.cj.jdbc.Driver// Step 2: Open a connectionConnection connection = DriverManager.getConnection(DB_URL, USER, PASS);// Step 3: Execute a queryint totalCount = getTotalCountFromDB(connection);if (totalCount == 0) {connection.close();EventBus.getDefault().post(new CommonEvent(EventCode.FLAG_NO_DATA));return;}// 显示进度条// todo showProgressDialog(context);// 执行sql 业务逻辑Statement statement = connection.createStatement();ResultSet rs = statement.executeQuery(sql);int count = 0;while (rs.next() && !isStopped) {// 进度条更新count++;int progress = (count * 100) / totalCount;updateProgress(progress);// Retrieve by column nameString name = rs.getString("name");int age = rs.getInt("age");String sex = rs.getString("sex");// todo 业务逻辑处理}// 关闭rs.close();statement.close();connection.close();// 主线程回调, 这里我使用订阅EventBus.getDefault().post(new CommonEvent(EventCode.FLAG_SUCCESS));} catch (Exception e) {// 主线程回调EventBus.getDefault().post(new CommonEvent(EventCode.FLAG_FAIL));} finally {// 进度条关闭mainHandler.post(() -> {if (progressDialogUtil != null) progressDialogUtil.dismissProgressDialog();});}}// 进度条更新private void updateProgress(int progress) {mainHandler.post(() -> {if (progressDialogUtil != null) {progressDialogUtil.updateProgress(progress);}});}}

进度条ProgressDialogUtil,布局:一个进度条+进度条进度+取消按钮,【取消】按钮是1分钟后可点击。代码如下:

public class ProgressDialogUtil {private final long DELAY_TIME = 1 * 60 * 1000;//2分钟  2 * 60 * 1000private Dialog progressDialog;private ProgressBar progressBar;private TextView tvProgress;private Button btnCancel;private Handler handler;private boolean cancelEnabled = false;public ProgressDialogUtil(Context context) {progressDialog = new Dialog(context, R.style.CustomProgressDialog);progressDialog.setContentView(R.layout.dialog_progress);progressDialog.setCancelable(false);progressBar = progressDialog.findViewById(R.id.progressBar);tvProgress = progressDialog.findViewById(R.id.tvProgress);btnCancel = progressDialog.findViewById(R.id.btnCancel);btnCancel.setEnabled(false);handler = new Handler();}public void showProgressDialog() {Window window = progressDialog.getWindow();if (window != null) {WindowManager.LayoutParams params = window.getAttributes();params.width = 650;window.setAttributes(params);}progressDialog.show();// 2分钟后显示handler.postDelayed(new Runnable() {@Overridepublic void run() {if (progressDialog.isShowing()) {cancelEnabled = true;btnCancel.setEnabled(true);}}}, DELAY_TIME);}public void dismissProgressDialog() {if (progressDialog != null && progressDialog.isShowing()) progressDialog.dismiss();}public void updateProgress(int progress) {
//        while (progress <= 97) {progressBar.setProgress(progress);tvProgress.setText(progress + "%");
//        }}public void setOnCancelListener(Runnable cancelAction) {btnCancel.setOnClickListener(v->{if (cancelEnabled) {cancelAction.run();dismissProgressDialog();}});}
}

这篇文章提供全部代码和操作思路,拿来就可以使用。

如果觉得还不错,给个一键三连呗~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/404281.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Qt】常用控件QCheckBox

常用控件QCheckBox QCheckBox表示复选按钮&#xff0c;可以允许选中多个。 QCheckBox继承自QAbstractButton 例子&#xff1a;获取复选按钮的取值 使用Qt Designer先大体进行设计 代码实现&#xff1a; #include "widget.h" #include "ui_widget.h"Widge…

【网络】套接字(socket)编程——TCP版

接着上一篇文章&#xff1a;http://t.csdnimg.cn/GZDlI 在上一篇文章中&#xff0c;我们实现的是UDP协议的&#xff0c;今天我们就要来实现一下TCP版本的 接下来接下来实现一批基于 TCP 协议的网络程序&#xff0c;本节只介绍基于IPv4的socket网络编程 基于 TCP 的网络编程开…

【leetcode详解】T3137(思路详解 代码优化感悟)

思路详解 要解决这个问题&#xff0c;我们的大致思路是这样&#xff1a;找到长度为k的字符串 (记为stringA) &#xff0c;统计重复次数最多的那一个&#xff0c;则最终对应的k周期字符串就是 [stringA * n] 的形式( n word.length() / k&#xff09; 要实现多对象的计数&…

iOS 18.1 Beta 2评测:新变化与体验升级

苹果公司近日向开发者推送了iOS 18.1 Beta 2更新&#xff0c;这一版本基于beta1版本进行多个方面优化和改进&#xff0c;为用户带来了更加流畅和个性化的使用体验。作为一位热衷于体验新系统的用户&#xff0c;小编也是第一时间升级了Beta 2版本&#xff0c;并对其进行了全面的…

51 无显式主键时 mysql 增加的 DB_ROW_ID

前言 这里主要是 探讨, 在我们创建了一个 无主键的数据表, 然后 mysql 会为我们增加的这一个 DB_ROW_ID 的相关 新建一个无主键字段的数据表如下 CREATE TABLE implicit_id_table (username varchar(16) DEFAULT NULL,age int(11) DEFAULT NULL ) ENGINEInnoDB DEFAULT CH…

Docker 部署loki日志 用于微服务

因为每次去查看日志都去登录服务器去查询相关日志文件&#xff0c;还有不同的微服务&#xff0c;不同日期的文件夹&#xff0c;超级麻烦&#xff0c;因为之前用过ELK&#xff0c;原本打算用ELK&#xff0c;在做技术调研的时候发现了一个轻量级的日志系统Loki&#xff0c;果断采…

如何一键删除iPhone相册所有照片

拍照已成为我们记录日常生活的常态。但是&#xff0c;大量照片便会积累在设备上&#xff0c;这不仅占用了大量存储空间&#xff0c;而且随着时间的推移&#xff0c;管理这些照片也变得越来越困难。如果你决定清理旧照片&#xff0c;或者出于隐私考虑需要删除所有照片&#xff0…

【数据结构】链式结构实现:二叉树

二叉树 一.快速创建一颗二叉树二.二叉树的遍历1.前序、中序、后序遍历&#xff08;深度优先遍历DFS&#xff09;2.层序遍历&#xff08;广度优先遍历BFS&#xff09; 三.二叉树节点的个数四.二叉树叶子节点的个数五.二叉树的高度六.二叉树第k层节点个数七.二叉树查找值为x的节点…

什么是机器人快换盘?

机器人快换盘&#xff0c;行业内也称作工具快换盘、换枪盘、快换工具盘、快速更换器、快换器、 快换夹具、治具快换等。是末端执行器快速更换装置&#xff08;End-Of-Arm Tooling&#xff0c;简称EOAT&#xff09;&#xff0c;是工业自动化领域中用于机器人手臂上的一种重要设备…

MiniCPM-V: A GPT-4V Level MLLM on Your Phone论文阅读

大模型的趋势&#xff1a;模型性能越来越好&#xff0c;模型参数变小&#xff0c;端边设备计算能力变强。 MiniCPM-V优点 结果好、OCR能力突出、多分辨率、多语言、易于部署 模型结构 图片encoder适用vit。输入整体以及切片。切片使用自适应算法&#xff0c;通过计算分数&am…

人机环境系统智能已经超越了传统的空间智能和物理世界的概念

人机环境系统智能已经超越了传统的空间智能和物理世界的概念&#xff0c;进入了更为复杂的层次。在人机环境系统中&#xff0c;智能不仅涉及对物理世界的感知和理解&#xff0c;还包括对人类语言、情感、意图等的理解和生成。人工智能技术的应用&#xff0c;如自然语言处理、机…

C++静态数组的用法

每日诗词&#xff1a; 疏影横斜水清浅&#xff0c;暗香浮动月黄昏。 ——《山园小梅其一》林逋 目录 数组的基础操作&#xff1a; 数组元素的增加&#xff1a; 演示&#xff1a; 数组元素的删除&#xff1a; 演示&#xff1a; 数组元素的访问和修改&#xff1a; 演示&am…

WLAN射频调优

射频调优的基本原则 信道优化的基本原则 2.4G射频在非高密部署场景中推荐采用1、6、11这种3个不重叠的信道进行规划&#xff0c;同理也可以选用2、7、12或3、8、13的组合方式&#xff1b;在高密部署场景中则推荐采用1、5、9、13共4个信道组合进行规划。5G射频推荐采用36、40、…

HQChart使用教程101-创建内置键盘精灵

HQChart使用教程101-创建内置键盘精灵 键盘精灵步骤1. 创建键盘精灵实例2. 设置事件回调3. 初始化键盘精灵4. 设置码表数据5. 监听"keydown","mousedown" 交流QQ群HQChart代码地址键盘精灵源码 完整实例 键盘精灵 键盘精灵是一种便捷操作软件的功能工具&a…

【人工智能】Python融合机器学习、深度学习和微服务的创新之路

1. &#x1f680; 引言1.1 &#x1f680; 人工智能的现状与发展趋势1.2 &#x1f4dc; 机器学习、深度学习和神经网络的基本概念1.3 &#x1f3c6; 微服务架构在人工智能中的作用 2. &#x1f50d; 机器学习的演变与创新2.1 &#x1f31f; 机器学习的历史回顾2.2 &#x1f9e0;…

UE----IPA 安装 在手机上后 显示 不受信任的开发者

进入设置 ----》 点击 通用 ----》点击 VPN与设备管理 点击信任 然后 再打开开发者模式即可 在隐私与安全性里 下滑 最底部 即可看到开发者模式

JavaScript学习笔记(十二):JS Web API

1、Web API - 简介 Web API 是开发人员的梦想。 它可以扩展浏览器的功能它可以极大简化复杂的功能它可以为复杂的代码提供简单的语法 1.1 什么是 Web API&#xff1f; API 指的是应用程序编程接口&#xff08;Application Programming Interface&#xff09;。 Web API 是 …

机器学习第十四章-概率图模型

目录 14.1 隐马尔可夫模型 14.2马尔科夫随机场 14.3条件随机场 14.4学习与推断 14.4.1变量消去 14.4.2信念传播 14.5近似推断 14.5.1 MCMC采样 14.5.2 变分推断 14.6 话题模型 14.1 隐马尔可夫模型 概率围棋型是一类用图来表达变量相关关系的概率模型.它以图为表示工具…

Python入门级[ 基础语法 函数... ] 笔记 例题较多

本文是刚学习Python的笔记&#xff0c;当时使用的编辑器是交互式编程&#xff0c;所以很多代码可能在你们的编译器上面不能运行&#xff0c;我用快引用引起来了&#xff0c;还需要大家自己动手试一试。 内容涉及的比较简单&#xff0c;主要还是Python的语法部分&#xff1a;三…

短链接系统设计方案

背景 需要设计一个短链接系统&#xff0c;主要功能主要有如下几点&#xff1a; ToB&#xff1a; 输入一个长链接&#xff0c;转换成短链接。这个短链接有时效性&#xff0c;可以设定指定过期时间。这个系统的每天会生成千万级别的短链接。数据具备可分析功能。 ToC&#xf…