失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 最详细Android连接远程的MySQL数据库实例

最详细Android连接远程的MySQL数据库实例

时间:2024-07-15 05:16:15

相关推荐

最详细Android连接远程的MySQL数据库实例

最详细Android连接远程的MySQL数据库实例

tags:MySQL

文章目录

最详细Android连接远程的MySQL数据库实例前言环境配置查看MySQL:version方法新建Android工程build.gradleactivity_main.xml布局文件MainActivity类修改为继承于Activity新建一个基类新建一个子页面将EthMainPager页面放入MainActivity中并显示。初步运行界面子页面的完善编写子页面的布局ethmainpager.xml文件实例化控件导入jar包数据库连接工具类获得数据更新getData()handlergetVersion()versionhandle最终运行的结果软件运行结果数据库中的数据

前言

第一次连接远程MySQL数据,在此留下笔记,针对遇到的总是也一并给出,在此说明,连接远程数据库在我没遇到的问题暂时无法给出,我尽量按写程的时间最全的给出代码。连接的方法是采用mysql-connector-java-5.1.30-bin.jar包进行连接。欢迎讨论。

说明:

以下记录按时间先后顺利给出,采用同样的环境应该可以重现。代码部分也由顺序给出,如:某一个方法或者类后面的代码可能比前面贴出的全,也可能是增加了内容,也可能是解决了前面的某个问题。为了程序的可扩展性,本示例采用数据与UI分离写法,自定义了页面的基类BasePager,initView()和initData()

环境配置

服务器:阿里云服务器 ECS

操作系统:centos 7

MySQL:version: 5.7.27

连接服务器软件:FinalShell

MySQL管理软件:RoboDB MySQL Manager

安卓开发软件:Androi Studio 3.5.2

查看MySQL:version方法

在登陆务务器后输入mysql -uroot -p再输入密码。

[root@njzhw ~]# mysql -uroot -pEnter password: Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 1234354Server version: 5.7.27 MySQL Community Server (GPL)Copyright (c) 2000, , Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>

新建Android工程

新建一个空白Activity的工程文,目前采用最新的各类文件版本,

build.gradle

app的build.gradle文件如下:所有支持均已最新版本。minSdkVersion 19因受我电脑外挂android模拟器的限制,采用了19。高了模拟器运行不起来。

apply plugin: 'com.android.application'android {compileSdkVersion 29buildToolsVersion "29.0.3"defaultConfig {applicationId "cn.plczl.myapplication"minSdkVersion 19targetSdkVersion 29versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}}dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])implementation 'androidx.appcompat:appcompat:1.1.0'implementation 'androidx.constraintlayout:constraintlayout:1.1.3'testImplementation 'junit:junit:4.13'androidTestImplementation 'androidx.test.ext:junit:1.1.1'androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'}

activity_main.xml布局文件

MainActivity所对应的activity_main.xml的布局文只有一个FrameLayout,所有数据显示采用另外的代码实现。

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><FrameLayoutandroid:id="@+id/fl_main"android:layout_width="match_parent"android:layout_height="match_parent" /></RelativeLayout>

MainActivity类修改为继承于Activity

新建好的MainActivity是继承于AppCompatActivity。区别是软件运行时不需要其默认的标题栏

百度的区别:

Activity 是其它 Activity 的基类,包括 AppCompatActivity。默认带标题栏,从字面理解,App兼容Activity,意思是允许我们轻易地将API 21+的特性应用到之前的那些老的,不兼容的Activity上面。例如很容易地将Toolbar添加到Activity上

代码如下:

package cn.plczl.mysql;import android.app.Activity;import android.os.Bundle;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}}

新建一个基类

用于子页面来继承,这样可以有多个页面采用自定义的一类进行界面、数据分离处理。

在工程中新建一个base的包,包中建立一个BasePager的类。代码如下:本基类无需要继承,

主要代码如下:

其中有一个构造函数public BasePager(Context context),用于获取上下文和初始化视图(rootView);一个抽象的initView方法,强制由调用的页面来实现,以实现不同页面有不同的UI结构;一个初始化数据的方法(initData),本方法为一个空方法,由继承它的子页面来实现数据填充。在子页面中还可以在本方法中进行耗时的联网,数据请求,数据显示的操作。

注意:因public abstract View initView();这个是一个抽象的方法,所对应的public abstract class BasePager 类也必须是抽象的,也就是由abstract关键字。public Context conetxt;要修改为public,如果自生成时可能是这样的,private final Context conetxt;因为这个conetxt要被其它的类调用。

package com.atguigu.mysql_dome.Base;import android.content.Context;import android.view.View;public abstract class BasePager {public Context conetxt;public View rootview;//本类的构造函数public BasePager(Context context){this.conetxt=context;rootview=initView();}//初始化视图的抽象类。强制由继承本类的其它类来实现public abstract View initView();//初始化视图的空方法,执行联网、数据请求、数据显示操作,本空方法不能缺少。public void initData(){}}

新建一个子页面

在工程中新建一个包(pager)来存放各子页面,在其包下新建一个EthMainPager的子页面,

代码如下:初步的实现了构造方法,initView()方法和initData方法。

其在程序中显示“初始化了EthMainPager”的文字。

package cn.plczl.mysql.pager;import android.content.Context;import android.view.Gravity;import android.view.View;import android.widget.TextView;import cn.plczl.mysql.base.BasePager;import cn.plczl.mysql.utils.LogUtil;public class EthMainPager extends BasePager {private TextView textView;public EthMainPager(Context context) {super(context);}@Overridepublic View initView() {textView=new TextView(conetxt);textView.setGravity(Gravity.CENTER);textView.setTextSize(20);return textView;}@Overridepublic void initData() {super.initData();LogUtil.e("初始化了EthMainPager");textView.setText("初始化了EthMainPager");}}

将EthMainPager页面放入MainActivity中并显示。

修改MainActivity,为程序扩展,将EthMainPager放入一个basePagers的集合中,自定义了setFragment、getEthMainPager方法,新建了一个ReplacePager类

public class MainActivity extends FragmentActivity {private ArrayList<BasePager> basePagers;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);basePagers = new ArrayList<>();basePagers.add(new EthMainPager(this));setFragment();}private void setFragment() {FragmentManager fragmentManager = getSupportFragmentManager();FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();//这里采用了replace方法,如果只是一个页面,也可以采用add方法。fragmentTransaction.replace(R.id.fl_main,new ReplacePager(getEthMainPager()));mit();}private BasePager getEthMainPager() {BasePager basePager=basePagers.get(0);if(basePager!=null){basePager.initData();}return basePager;}public static class ReplacePager extends Fragment {public BasePager currPager;public ReplacePager(BasePager basePager) {this.currPager=basePager;}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);}@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return currPager.rootView;}}}

为使程序看起来简捷,将public static class ReplacePager extends Fragment抽取出来形成一个单独的类。

将其抽取至base目录中。文件名为ReplacePager

在MainActivity加入包含import cn.plczl.mysql.base.ReplacePager;

package cn.plczl.mysql.base;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import androidx.annotation.NonNull;import androidx.annotation.Nullable;import androidx.fragment.app.Fragment;public class ReplacePager extends Fragment {public BasePager currPager;public ReplacePager(BasePager basePager) {this.currPager=basePager;}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);}@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return currPager.rootView;}}

初步运行界面

以上代码完成初步的界面搭建,初步运行起来的画面如下:

子页面的完善编写

接下来的基本操作都将在EthMainPager子页面中去实现界面,联网和数据请示以及数据显示的操作。

子页面的布局

在EthMainPager的public View initView() 加入一条View view=View.inflate(conetxt, R.layout.ethmainpager,null);语名,用于加载ethmainpager.xml布局文,不再采用上面程序中的如下代码来初始化子页面了,initView体现了页面的初始化,

textView=new TextView(conetxt);textView.setGravity(Gravity.CENTER);textView.setTextSize(20);return textView;

@Overridepublic View initView() {View view=View.inflate(conetxt, R.layout.ethmainpager,null);return view;}

ethmainpager.xml文件

这里采用简单的一个线性布局,里面有四个TextView,这个程序是Dome性质,只要参调出MySQL数据一张表中库中的两个数据和另一张表中的一个数据,

这里设定能调出数据库最近更新的日期和时间就完成任务。

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"android:background="#23D3FE"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:layout_marginBottom="5dp"android:layout_marginRight="20dp"android:layout_marginLeft="20dp"><TextViewandroid:id="@+id/tv_1"android:layout_width="wrap_content"android:layout_height="25dp"android:text="数据更新时间"android:padding="2dp"android:textSize="16sp"android:gravity="left"android:layout_marginLeft="5dp"/><TextViewandroid:id="@+id/tv_data1"android:layout_width="wrap_content"android:layout_height="25dp"android:text="-01-27"android:padding="2dp"android:textSize="16sp"android:gravity="left"android:layout_toRightOf="@id/tv_1"android:layout_marginLeft="5dp"/><TextViewandroid:id="@+id/tv_time"android:layout_width="wrap_content"android:layout_height="25dp"android:text="21:00:00"android:padding="2dp"android:textSize="16sp"android:gravity="left"android:layout_toRightOf="@id/tv_data1"android:layout_marginRight="20dp"/></RelativeLayout><TextViewandroid:id="@+id/tv_version"android:layout_width="wrap_content"android:layout_height="25dp"android:text="21:00:00"android:padding="2dp"android:textSize="16sp"android:gravity="left"android:layout_marginLeft="22dp"android:layout_toRightOf="@id/tv_data"android:layout_marginRight="20dp"/></LinearLayout>

实例化控件

将用于要显进日期和时间的两个TextView实例化。

private TextView tv_data;private TextView tv_time;private TextView tv_version;public EthMainPager(Context context) {super(context);}@Overridepublic View initView() {View view = View.inflate(conetxt, R.layout.ethmainpager,null);tv_data = view.findViewById(R.id.tv_data);tv_time = view.findViewById(R.id.tv_time);tv_version = view.findViewById(R.id.tv_version);return view;}

导入jar包

采用mysql-connector-java-5.1.30-bin.jar进行MySQL连接,

将下载好的mysql-connector-java-5.1.30-bin.jar复制到工程的libs文件夹下,然点在mysql-connector-java-5.1.30-bin.jar点右键——>点击Add As Library…

完成后build.gradle文件中有这个包的加入。

导入后的build.gradle如下,最后一行代码就是导入了mysql-connector-java-5.1.30-bin.jar

apply plugin: 'com.android.application'android {compileSdkVersion 29buildToolsVersion "29.0.3"defaultConfig {applicationId "cn.plczl.myapplication"minSdkVersion 19targetSdkVersion 29versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}}dependencies {implementation fileTree(include: ['*.jar'], dir: 'libs')implementation 'androidx.appcompat:appcompat:1.1.0'implementation 'androidx.constraintlayout:constraintlayout:1.1.3'testImplementation 'junit:junit:4.13'androidTestImplementation 'androidx.test.ext:junit:1.1.1'androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'implementation files('libs/mysql-connector-java-5.1.30-bin.jar')}

数据库连接工具类

编写了连接数据库的工具类DBUtils.jave。用于要对数据操作的调用,代码如下:

其中有三个方法:

getConn用于连接数据,其中String dbName参数为要连接的数据名字,getEthData方法是获得eth数据库中的apidate表的最新一行的数据方法。getVersion方法是eth数据库中的version表中的version字段的的最新一行的数据方法。

调用的方法分别以一个数组和字符串返回。

package cn.plczl.mysql.utils;import android.util.Log;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;//连接mySql数据库方法public class DBUtils {private static final String TAG ="Dbutils";private static String driver="com.mysql.jdbc.Driver";//这里是MySQL的用户名private static String user="root";//这里是我的MySQL密码,本文作了隐藏处理,private static String password = "xxxxxxx";public static Connection getConn(String dbName){Connection connection = null;try{Class.forName(driver);//数据的IP地址,本文中的地址不是我的真实地址,请换为你的真实IP地址。String ip="39.10.011";String port="3306";String url = "jdbc:mysql://" + ip + ":" + port +"/" + dbName;connection= DriverManager.getConnection(url, user, password);Log.e("数据库连接", "成功!");} catch (Exception e) {Log.e("数据库连接", "失败!");e.printStackTrace();}return connection;}public static String[] getEthData() {String rsdata[]=new String[24];Connection connection = getConn("eth");if (connection!=null){String sql="select * from apidate order by id DESC limit 1";try{java.sql.Statement statement = connection.createStatement();ResultSet rSet = statement.executeQuery(sql);while (rSet.next()) {rsdata[0]=rSet.getString("date");//日期rsdata[1]=rSet.getString("time");//时间rsdata[2]=rSet.getString("capital").substring(0,4);//人民币总收益rsdata[3]=rSet.getString("worker_length");//矿机总数rsdata[4]=rSet.getString("worker_lenght_online");//在线矿机数rsdata[5]=rSet.getString("worker_length_offline");//离线矿机数rsdata[6]=rSet.getString("dead_sl");//失线矿机数rsdata[7]=rSet.getString("hash_24_hour");//24小时平均算力rsdata[8]=rSet.getString("last_day_value").substring(0,9);//过去24小时收益rsdata[9]=rSet.getString("hash_15");//15分钟平均算力rsdata[10]=rSet.getString("balance").substring(0,9);//当前余额rsdata[11]=rSet.getString("local_hash");//本地算力rsdata[12]=rSet.getString("value").substring(0,9);//总收益rsdata[13]=rSet.getString("quanwangsl")+" TH/s";//全网算力rsdata[14]=rSet.getString("f2poolsl")+" TH/s";//全网算力rsdata[15]=rSet.getString("meiM_Eth")+" ETH ≈ ¥"+String.valueOf(Double.valueOf(rSet.getString("meiM_Eth"))*Double.valueOf(rSet.getString("meiyuanzhisu"))*Double.valueOf(rSet.getString("usdCnyRate"))).substring(0,5);//每M收益rsdata[16]= String.valueOf(Double.valueOf(rSet.getString("waikuangnandu"))/10000/10000/10000/1000).substring(0,5)+" P";//当前难度rsdata[17]="$"+rSet.getString("price")+" ≈ ¥"+String.valueOf(Double.valueOf(rSet.getString("price"))*Double.valueOf(rSet.getString("usdCnyRate"))).substring(0,4);//币价usdCnyRatersdata[18]="¥"+rSet.getString("ETC_index");//etc指数rsdata[19]=rSet.getString("ETC_zhangdie");//etc涨跌rsdata[20]=rSet.getString("ETH_zuigaojia");//eth最高价rsdata[21]=rSet.getString("ETH_zuidijia");//eth最低价rsdata[22]=rSet.getString("riseandfall");//ETH涨跌rsdata[23]=rSet.getString("id");//数据库数据条数Log.e(TAG,"数组组装成功");}connection.close();} catch (SQLException e) {e.printStackTrace();}};Log.e(TAG,"数组已返回");return rsdata;}public static String getVersion() {String version=null;Connection connection = getConn("eth");if (connection!=null){String sql="select version from version";try{java.sql.Statement statement = connection.createStatement();ResultSet rSet = statement.executeQuery(sql);while (rSet.next()) {version=rSet.getString("version");//日期Log.e(TAG,"数组组装成功==="+version);}connection.close();} catch (SQLException e) {e.printStackTrace();}};Log.e(TAG,"数组已返回==========");return version;}}

获得数据更新

在EthMainPagerr的initData()方法中写了两个方法,分别连接两个数据库获得数据并显示。

getData()方法是调用DBUtils数据库连接工具中的getEthData()

getVersion();方法是调用DBUtils数据库连接工具中的getVersion()

采用在子线程中连接数据库和Handler切换到主线程进行数据更新。

@Overridepublic void initData() {super.initData();LogUtil.e("初始化了EthMainPager");getData();getVersion();}

getData()

简单的new了一个Thread子线程,用于调用 ethdata=DBUtils.getEthData();方法,将数据存入ethdata数组中。通过handler.sendEmptyMessage(0);返回主线程。

private void getData() {new Thread(){@Overridepublic void run() {super.run();ethdata=DBUtils.getEthData();handler.sendEmptyMessage(0);}}.start();}

handler

在handler中更换tv_data.setText(ethdata[0]);tv_time.setText(ethdata[1]);获得的数据。

private Handler handler = new Handler(){@Overridepublic void handleMessage(@NonNull Message msg) {super.handleMessage(msg);LogUtil.e(String.valueOf(ethdata.length));tv_data.setText(ethdata[0]);tv_time.setText(ethdata[1]);}};

getVersion()

与 getData()类似。

version=DBUtils.getVersion();方法,将数据存入version数组中。通过versionhandle.sendEmptyMessage(1);返回主线程。

private void getVersion() {new Thread(){@Overridepublic void run() {super.run();version=DBUtils.getVersion();versionhandle.sendEmptyMessage(1);}}.start();}

versionhandle

在versionhandle中更新tv_version.setText(version);获得的数据。

private Handler versionhandle = new Handler(){@Overridepublic void handleMessage(@NonNull Message msg) {super.handleMessage(msg);LogUtil.e(String.valueOf(ethdata.length));tv_version.setText(version);}};

最终运行的结果

软件运行结果

数据库中的数据

如果觉得《最详细Android连接远程的MySQL数据库实例》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。