Android連接MySQL數(shù)據(jù)庫實(shí)現(xiàn)方法詳解
前言
- 要為MySQL添加 非root用戶 并設(shè)置權(quán)限。一定要設(shè)置權(quán)限!!!默認(rèn)是沒有權(quán)限的!!!
請注意為用戶設(shè)置主機(jī)時(shí),主機(jī)設(shè)置為%時(shí)表示通配符,即任何主機(jī)均可使用本用戶連接,但不能使用localhost(但可以使用本機(jī)ipv4地址連接),想使用localhost連接需將用戶主機(jī)設(shè)置為localhost。
Android連MySQL因?yàn)椴淮_定連接地址,所以用戶主機(jī)要設(shè)置為%
- 在Android中連接MySQL的目標(biāo)ip不能用
//localhost
或//127.0.0.1
,應(yīng)使用真實(shí)的ip地址
(可用cmd查詢本機(jī)ip,cmd->ipconfig)
- Android連接的MySQL版本應(yīng)為5.X版本(8.X版本無法使用)驅(qū)動(dòng)程序通用
- 請注意!??!Android中連接/對數(shù)據(jù)庫操作 只能在子線程進(jìn)行!!!!(單開一個(gè)線程)
因?yàn)槭呛臅r(shí)操作!!!
如果url、賬號、密碼正確還報(bào)錯(cuò)大概率是沒有在子線程操作數(shù)據(jù)庫。
- 應(yīng)為程序添加網(wǎng)絡(luò)及WIFI權(quán)限(通過網(wǎng)絡(luò)連接數(shù)據(jù)庫)
//必須加 <uses-permission android:name="android.permission.INTERNET"/> //可不加 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
- 添加MySQL驅(qū)動(dòng)程序
將JAR程序放入Project視圖模式下 app/libs中,并右鍵->Add As Library
- 在url后加入如下語句能避免許多麻煩
"?useUnicode=true&characterEncoding=utf-8&useSSL=false"
- 打開電腦的telnet服務(wù),使其他人可以訪問
- 打開電腦防火墻的MySQL端口,使其他人可以訪問
- 建議以如下格式寫連接代碼
(1)ConnectionUtils 連接工具類,用于連接數(shù)據(jù)庫
(2)User 存儲內(nèi)容類,用于存儲MySQL回傳數(shù)據(jù)
(3)UserDao 數(shù)據(jù)訪問對象,執(zhí)行SQL操作返回存儲內(nèi)容類
- 連接關(guān)閉后ResultSet中內(nèi)容會消失(將其內(nèi)容在連接關(guān)閉前存在其他地方)
- 讀ResultSet內(nèi)容前先移動(dòng)指針 .next();如果ResultSet中無搜索結(jié)果,.next()方法返回false,有搜索結(jié)果返回true。
- 設(shè)置連接MySQL超時(shí) DriverManager.setLoginTimeout(2000);
- 盡量復(fù)用通道,避免反復(fù)連接造成延遲!!!
- ip地址問題
個(gè)人電腦一般在局域網(wǎng)內(nèi),其ip為NAT局域網(wǎng)ip,只能被同局域網(wǎng)設(shè)備訪問,無法直接被其他網(wǎng)絡(luò)訪問,可使用內(nèi)網(wǎng)穿透軟件(如花生殼)進(jìn)行處理。
- MySQL其實(shí)就是服務(wù)器,可以直接進(jìn)行遠(yuǎn)程連接,不用再做服務(wù)器
- MySQL自帶的4個(gè)數(shù)據(jù)庫不能刪?。?!
information_schema、mysql、performation_schema、test
- 可以多人同時(shí)使用同個(gè)用戶名及密碼登錄,但不建議
- MySQL中建議使用PreparedStatement而不是使用Statement,PreparedStatement的執(zhí)行速度比Statement快并且可以防止SQL注入攻擊。在使用PreparedStatement時(shí)可以用?代替值,然后使用
.setString(int index , String value)
方法設(shè)置?的值,但請注意,PreparedStatement的index起始是1而不是0。要復(fù)用PreparedStatement!!
實(shí)例
- ConnectionUtils 連接工具類,用于連接數(shù)據(jù)庫
- User 存儲內(nèi)容類,用于存儲MySQL回傳數(shù)據(jù)
- UserDao 數(shù)據(jù)訪問對象,執(zhí)行SQL操作返回存儲內(nèi)容類
//主線程 以監(jiān)聽為例 Thread thread=null; public void onClick(View view){ if(thread==null){ //連接數(shù)據(jù)庫不能在主線程,單開一個(gè)線程 thread=new Thread(new Runnable(){ User user=UserDao.findUser(1); }); } }
//連接工具類 public class ConnectionUtils { public static Connection getConn(){ String url="jdbc:mysql://255.255.255.1:3306/databaseName"+"?useUnicode=true&characterEncoding=utf-8&useSSL=false"; String username="firstUser"; String password="123456"; try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } Connection connection_jdbc = null; try { DriverManager.setLoginTimer(2000); connection_jdbc= DriverManager.getConnection(url,username,password); } catch (SQLException e) { throw new RuntimeException(e); } return connection_jdbc; } public static boolean close(Connection connection){ if(connection!=null){ try { connection.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } }
//存儲內(nèi)容類 public class User { private int id; private String username; private String password; private int storyid; public int getId() { return id; } public String getUsername() { return username; } public String getPassword() { return password; } public int getStoryid() { return storyid; } public User(int id,String username,String password,int storyid){ this.id=id; this.username=username; this.password=password; this.storyid=storyid; } public String toString(){ String str="id:"+id+" username:"+username+" password:"+password+" storyid:"+storyid; return str; } }
//數(shù)據(jù)訪問對象類 public class Dao { private Connection conn; public static User findUser(int id){ //盡量復(fù)用通道,避免反復(fù)連接造成延遲 if(conn==null){ conn=ConnectionUtils.getConn(); } try { Statement statement=conn.createStatement(); String sql="select * from mysql where id ='"+id+"'"; ResultSet resultSet=statement.executeQuery(sql); Boolean bool = resultSet.next();//先移動(dòng)指針再獲取值 //如果ResultSet無結(jié)果,next()返回false if(bool){ int resultSetId=resultSet.getInt("id"); String resultSetSex=resultSet.getString("sex"); String resultSetName=resultSet.getString("name"); User user=new User(resultSetId,resultSetSex,resultSetName); return user; } } catch (SQLException e) { throw new RuntimeException(e); } //確定不使用再關(guān)閉通道 //ConnectionUtils.close(conn); } }
常見報(bào)錯(cuò)原因
- 程序 對/連接 數(shù)據(jù)庫操作 是否在子線程
- mysql用戶主機(jī)是否設(shè)置%(任意主機(jī))或其他
- mysql用戶權(quán)限是否設(shè)置
- 程序連接時(shí)的用戶名與密碼是否正確
連接緩慢原因
- 程序是否復(fù)用通道connection,反復(fù)連接數(shù)據(jù)庫會導(dǎo)致緩慢
- prepareStatement代替statement,減少命令的創(chuàng)建(要復(fù)用PreparedStatement)
tag: java ,遠(yuǎn)程連接 ,mysql ,Android ,安卓,MySQL
到此這篇關(guān)于Android連接MySQL數(shù)據(jù)庫實(shí)現(xiàn)方法詳解的文章就介紹到這了,更多相關(guān)Android連接MySQL內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android fragment實(shí)現(xiàn)多個(gè)頁面切換效果
這篇文章主要為大家詳細(xì)介紹了fragment實(shí)現(xiàn)多個(gè)頁面切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04Android帶進(jìn)度條的文件上傳示例(使用AsyncTask異步任務(wù))
這篇文章主要介紹了Android帶進(jìn)度條的文件上傳示例(使用AsyncTask異步任務(wù)),使用起來比較方便,將幾個(gè)方法實(shí)現(xiàn)就行,感興趣的小伙伴們可以參考一下。2016-11-11Android快速開發(fā)系列 10個(gè)常用工具類實(shí)例代碼詳解
今天特此整理出10個(gè)基本每個(gè)項(xiàng)目中都會使用的工具類,用于快速開發(fā),對android開發(fā)常用工具類感興趣的朋友跟隨小編一起看看吧2018-09-09flutter傳遞值到任意widget(當(dāng)需要widget嵌套使用需要傳遞值的時(shí)候)
這篇文章主要介紹了flutter傳遞值到任意widget(當(dāng)需要widget嵌套使用需要傳遞值的時(shí)候),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07Android開發(fā)實(shí)現(xiàn)帶清空按鈕的EditText示例
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)帶清空按鈕的EditText,結(jié)合具體實(shí)例形式分析了Android實(shí)現(xiàn)EditText清空按鈕功能相關(guān)操作技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-11-11