文章目录

  • 注意
    • 基础
  • Androidstudio通过JDBC连接数据库巨坑介绍(这里呢,我使用我所做项目的修改密码界面来做介绍)
    • 1.网络权限问题(打不开apk)
    • 2.jar包问题(找不到driver)
    • 3.连接方法问题(返回连接对象为null)
    • 4.异步启动问题(返回连接对象为null)
      • 同步启动
      • 异步启动
    • 5.同一个线程不能多次调用异步启动函数(threads.start()------>new Thread(threads).start();)(java.lang.IllegalThreadStateException报错,闪退问题)
    • 6.线程函数中弹出Toast问题
    • 7.修改密码框架模式问题(judge_before + judge +judge_after)
  • 总结

注意

很多朋友用IDEA通过JDBC的方式去连接MYSQL数据库,JDBC之获取数据库连接方法详解,然后看到这里用Androidstudio通过JDBC的方式去连接MYSQL数据库是不是也是像我前两天一样,不以为然呢?是不是以为贴过java代码就行了呢?还请听我细细道来

基础

需要会使用IDEA编译器用java代码通过JDBC的方式,来连接MySQL数据库,最好还是先看完这篇博客:JDBC之获取数据库连接方法详解,然后再看Androidstudio 这篇

Androidstudio通过JDBC连接数据库巨坑介绍(这里呢,我使用我所做项目的修改密码界面来做介绍)

1.网络权限问题(打不开apk)

Android Studio默认是不允许访问Internet的。因此需要在app/src/main/AndroidManifest.xml中的<manifest>...</manifest>区域内添加一行在 ,AndroidManifest.xml 中(别去加在<application></application>里面)添加:

<uses-permission android:name="android.permission.INTERNET" />

2.jar包问题(找不到driver)


我的jar包用的是5.0.8版本的,jar包的话,去官网下载,建议版本不要太高,版本太高问题超级多

3.连接方法问题(返回连接对象为null)

 Connection conn=DriverManager.getConnection(url,user,password);
 Driver driver=new com.mysql.jdbc.Driver();Properties info =new Properties();info.setProperty("user","root0");info.setProperty("password","abc123");
Connection conn=driver.connect(url,info);

连接之前记得加载一下驱动类就行,刚开始我的Connection返回对象一直为null,我一直以为是连接方式有问题,我试完这两种连接方式,于是Connection返回对象一直为null,至于为什么返回null的话,请看下一个巨坑。

4.异步启动问题(返回连接对象为null)

同步启动

刚开始我直接把连接过程写在主线程里面,所以造成了上面那种尴尬的情况,Connection返回对象一直是null,查了一下原因如下:
一个APP如果在主线程中请求网络操作,将会抛出NetworkOnMainThreadException异常。Android这个设计是为了防止网络请求时间过长而导致界面假死的情况发生,我试了直接不是假死,而是直接返回null值,然后就gg了。

  static void connect(){//1.读取配置文件中的四个基本信息String url = "jdbc:mysql://"+ip+"/"+数据库名;String user_server = 用户名;String password_server = 密码;String driverclass = "com.mysql.jdbc.Driver";//2.加载驱动try {Class.forName(driverclass);} catch (ClassNotFoundException e) {e.printStackTrace();}conn = null;//3.获取连接try {conn = DriverManager.getConnection(url, user_server, password_server);} catch (SQLException throwables) {throwables.printStackTrace();}//4.预编译sql语句,返回PreparedStatement的实例sql="select * from login ";try {ps=conn.prepareStatement(sql);//6.执行并返回结果集ResultSet resultSet =ps.executeQuery();while(resultSet.next()){String usertest=resultSet.getString(1);String passwordtest=resultSet.getString(2);if(usertest.equals(user)){if(password_before.equals(passwordtest)) {String sql2 = "update login set password=? where user=?";ps = conn.prepareStatement(sql2);//5.填充占位符ps.setString(1, password_after);ps.setString(2, user);//6.执行操作ps.execute();flag_test=1;return;}flag_test=2;return;}}flag_test=0;} catch (SQLException e) {e.printStackTrace();}flag_test=0;return ;}

当你执行到下面这行的时候,然后就会返回null值,紧接着下面也就没有任何意义

conn = DriverManager.getConnection(url, user_server, password_server);

可以断点调试看看

异步启动

Android在子线程中是不可以进行ui操作的。Toast也是不可以在子线程中使用的。

Thread threads=new Thread(new Runnable() {public void run() {//1.读取配置文件中的四个基本信息String url = "jdbc:mysql://"+ip+"/"+数据库名;String user_server = 用户名;String password_server = 密码;String driverclass = "com.mysql.jdbc.Driver";//2.加载驱动try {Class.forName(driverclass);} catch (ClassNotFoundException e) {e.printStackTrace();}conn = null;//3.获取连接try {conn = DriverManager.getConnection(url, user_server, password_server);} catch (SQLException throwables) {throwables.printStackTrace();}//4.预编译sql语句,返回PreparedStatement的实例sql="select * from login ";try {ps=conn.prepareStatement(sql);//6.执行并返回结果集ResultSet resultSet =ps.executeQuery();while(resultSet.next()){String usertest=resultSet.getString(1);String passwordtest=resultSet.getString(2);if(usertest.equals(user)){if(password_before.equals(passwordtest)) {String sql2 = "update login set password=? where user=?";ps = conn.prepareStatement(sql2);//5.填充占位符ps.setString(1, password_after);ps.setString(2, user);//6.执行操作ps.execute();flag_test=1;return;}flag_test=2;return;}}flag_test=0;} catch (SQLException e) {e.printStackTrace();}flag_test=0;return ;}});
threads.start();

这样的话,就能启动成功喽,但是注意一点,这种方式,只能运行一次,如果点击了两次的话,那么也就相当于,这个线程对象调用了两次start函数,这能行吗?????。但是我们进行修改密码然后点击按钮判断的时候,就只是点击一次,然后手动返回上个页面了吗?,答案肯定不是的。

5.同一个线程不能多次调用异步启动函数(threads.start()------>new Thread(threads).start();)(java.lang.IllegalThreadStateException报错,闪退问题)

这里也就是解决4的问题,threads.start();,你点击几次按钮,那么它就会调用几次start函数,你能把一个thread对象连续start吗?肯定不能!所以等你点击第二次的时候,那么就报错了,IllegalThreadStateException紧接着闪退了,

这算是一次点击,对吧?也就是相当于调用了一次threads.start();,如果我们继续在这页面输入内容加密码这些东西,再次进行判断,是不是相当于第二次调用threads.start(),然后就闪退,变成如下界面,也就是上一个activity了,并且IllegalThreadStateException报错

那么我们该如何解决呢?出发点肯定是不能让一个线程调用两次start函数,对吧?那么每次都new一个thread不就得了嘛,对吧,或者搞一个thread数组,换着使用

  new Thread(threads).start();

6.线程函数中弹出Toast问题

如果在连接上的时候需要一个toast提示一下,连接成功(修改密码前提肯定是连接数据库嘛)或者修改密码成功的话,那么是不是会在线程函数中写上:

 Toast.makeText(getApplicationContext(), "修改密码成功", Toast.LENGTH_SHORT).show();

线程函数中能不能直接toast呢?(答案肯定是不能呀 ,如果在线程函数中,直接写的话,毫无疑问报错java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()Android在子线程中是不可以进行ui操作的。Toast也是不可以在子线程中使用的。
在调用Toast之前,需要先创建一个Looper对象,这样做,我们所调用的Toast才能加入到一个消息队列中,并向屏幕进行输出显示。而我们之所以在MainActivity类中可以直接调用Toast而无需在其前面创建一个Looper对象,是因为当我们进行程序编译时,Android框架会默认为我们创建出一个Looper对象。
所以在线程函数中调用 Toast的话,需要如下操作:

Looper.prepare();
Toast.makeText(getApplicationContext(), "修改密码成功", Toast.LENGTH_SHORT).show();
Looper.loop();

那么我们可不可以设置一个全局变量flag,然后在线程函数里面设置flag的值,然后出来之后,利用一个judge_after函数来进行toast操作呢?在线程函数里面保证只进行连接和设置flag 的作用,其它的在主线程里面进行会比较方便,因为异步线程,没法进行断点调试,那样做起来调试时候比较让人难以接受,

7.修改密码框架模式问题(judge_before + judge +judge_after)

 Thread threads=new Thread(new Runnable() {public void run() {//1.读取配置文件中的四个基本信息String url = "jdbc:mysql://"+ip+"/"+数据库名;String user_server = 用户名;String password_server = 密码;String driverclass = "com.mysql.jdbc.Driver";//2.加载驱动try {Class.forName(driverclass);} catch (ClassNotFoundException e) {e.printStackTrace();}conn = null;//3.获取连接try {conn = DriverManager.getConnection(url, user_server, password_server);} catch (SQLException throwables) {throwables.printStackTrace();}//4.预编译sql语句,返回PreparedStatement的实例sql="select * from login ";try {ps=conn.prepareStatement(sql);//6.执行并返回结果集ResultSet resultSet =ps.executeQuery();while(resultSet.next()){String usertest=resultSet.getString(1);String passwordtest=resultSet.getString(2);if(usertest.equals(user)){if(password_before.equals(passwordtest)) {String sql2 = "update login set password=? where user=?";ps = conn.prepareStatement(sql2);//5.填充占位符ps.setString(1, password_after);ps.setString(2, user);//6.执行操作ps.execute();flag_test=1;return;}flag_test=2;return;}}flag_test=0;} catch (SQLException e) {e.printStackTrace();}flag_test=0;return ;}});public boolean thread_before(){EditText user_text = findViewById(R.id.username);user = user_text.getText().toString();EditText password_text = findViewById(R.id.password_before);password_before = password_text.getText().toString();EditText password_text_ = findViewById(R.id.password_after);password_after = password_text_.getText().toString();if(user.equals("")&&password_before.equals("")&&password_after.equals("")){Toast.makeText(getApplicationContext(), "请输入用户名,原密码和修改密码", Toast.LENGTH_SHORT).show();return false;}else if(user.equals("")&&password_before.equals("")&&(!password_after.equals(""))){Toast.makeText(getApplicationContext(), "请输入用户名和原密码", Toast.LENGTH_SHORT).show();return false;}else if(user.equals("")&&(!password_before.equals(""))&&password_after.equals("")){Toast.makeText(getApplicationContext(), "请输入用户名和修改密码", Toast.LENGTH_SHORT).show();return false;}else if((!user.equals(""))&&password_before.equals("")&&password_after.equals("")){Toast.makeText(getApplicationContext(), "请输入原密码和修改密码", Toast.LENGTH_SHORT).show();return false;}else if(user.equals("")&&(!password_before.equals(""))&&(!password_after.equals(""))){Toast.makeText(getApplicationContext(), "请输入用户名", Toast.LENGTH_SHORT).show();return false;}else if((!user.equals(""))&&password_before.equals("")&&(!password_after.equals(""))){Toast.makeText(getApplicationContext(), "请输入原密码", Toast.LENGTH_SHORT).show();return false;}else if((!user.equals(""))&&(!password_before.equals(""))&&password_after.equals("")){Toast.makeText(getApplicationContext(), "请输入修改密码", Toast.LENGTH_SHORT).show();return false;}else if((!user.equals(""))&&(!password_before.equals(""))&&(!password_after.equals(""))&&password_before.equals(password_after)){Toast.makeText(getApplicationContext(), "原密码不能和修改密码相等", Toast.LENGTH_SHORT).show();return  false;}else if((!user.equals(""))&&(!password_before.equals(""))&&(!password_after.equals(""))&&(password_after.length()<6)){Toast.makeText(getApplicationContext(), "修改后密码长度不能小于6位", Toast.LENGTH_SHORT).show();return  false;}return true;}public void thread_after(){if(flag_test==1){Toast.makeText(getApplicationContext(), "修改密码成功", Toast.LENGTH_SHORT).show();}else if(flag_test==0){Toast.makeText(getApplicationContext(), "用户名错误", Toast.LENGTH_SHORT).show();}else if(flag_test==2){Toast.makeText(getApplicationContext(), "原密码错误", Toast.LENGTH_SHORT).show();}}}

总结

这次Android的jdbc之旅呢,收获了很多,本以为和IDEA一样的操作,小改一下就行,结果踩中了那么坑,下次注意喽

AndroidStudio通过JDBC连接MySQL数据库六大巨坑相关推荐

  1. 原生JDBC连接MySQL数据库踩的坑

    前几天被一个项目对接要搞死了,搞了好几天,各种方法去试.各种百度去搜.各个门道去问,最终终于解决了心头一缕缕思愁!!!

  2. java jdbc 连接mysql数据库 实现增删改查

    好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...

  3. Java新手入门200例124之用JDBC连接Mysql数据库

    文章目录 作者简介 引言 导航 热门专栏推荐 一.创建web项目 二.加入Mysql驱动 三.编写查询代码 四.测试查询代码 五.编写插入代码 六.编写修改代码 七.编写删除代码 小结 导航 热门专栏 ...

  4. JDBC连接MySQL数据库及演示样例

    JDBC是Sun公司制定的一个能够用Java语言连接数据库的技术. 一.JDBC基础知识         JDBC(Java Data Base Connectivity,java数据库连接)是一种用 ...

  5. JAVA-数据库之JDBC连接MySQL数据库

    相关资料: <21天学通Java Web开发> JDBC连接MySQL数据库 1.如果需要通过JDBC来连接MySQL数据库,还必须先在MySQL数据库服务器中创建数据库和表. Conne ...

  6. JDBC连接MySQL数据库代码模板

    下面这个例子是最简单的JDBC连接MySQL数据库的例子. 一般步骤: 1.注册驱动: 2.建立连接: 3.创建语句: 4.处理结果: 5.释放资源. 注意: 1.软件开发环境:MyEclipse 8 ...

  7. jaba窗体连接mysql增删改查_知识实现——Java使用jdbc连接MySql数据库,实现增删改查...

    Java使用jdbc连接MySql数据库,实现增删改查 首先,导入MySql连接数据库的jar包,我用的是 mysql连接jar包 DB类,用于获得数据库连接 import java.sql.Driv ...

  8. JDBC连接MySQL数据库及示例

    JDBC是Sun公司制定的一个可以用Java语言连接数据库的技术. 一.JDBC基础知识         JDBC(Java Data Base Connectivity,java数据库连接)是一种用 ...

  9. JDBC连接 Mysql数据库

    IDEA使用JDBC连接Mysql数据库 在项目中添加连接Mysql数据库的jar包 在项目中创建util包和DBUtil类用来存放数据库连接的java代码. 完整代码 package com.zsh ...

最新文章

  1. 如何给DataGrid添加自动增长列
  2. s3c2410下利用TL16C554扩展4个全功能串口
  3. php作为弱语言是最棒的~哈哈哈哈
  4. 【CF#2A】Winner(模拟 STL-map)☆
  5. 并发计算 VS 并行计算
  6. 常用の工具(update 22.11.11)
  7. 如何为java添加日历控件_laydate日历控件使用方法详解
  8. 历经8年美团成功上市!回到起点看王兴,梦想并非遥不可及!
  9. 硬件钱包 Ledger使用教程
  10. mysql 百分比两位小数_SQL中如何让百分比后面保留2位小数?
  11. 阿里云ECS服务器跨账号迁移
  12. 在中国搞自动驾驶,没有人不羡慕滴滴
  13. lol黑屏显示服务器,LOL英雄联盟进去开始就黑屏,英雄服务器中断进不去
  14. 2021年中国LED工业照明市场趋势报告、技术动态创新及2027年市场预测
  15. 「解析」语义分割性能指标 附代码
  16. 小程序 height: 100vh; onReachBottom触底事件不触发
  17. C51 ADC0804LCN 应用
  18. 【数据结构与算法】【14】以树状形式打印二叉树
  19. Ubuntu 桥接模式连不上网的解决办法
  20. MOF (Meta Object Facility) 规范

热门文章

  1. Python:python语言中与时间有关的库函数简介、安装、使用方法之详细攻略
  2. ML之SVM:基于Js代码利用SVM算法的实现根据Kaggle数据集预测泰坦尼克号生存人员
  3. 元计算:《元计算破解生命密码》听课笔记
  4. Laravel中一些要记住 的写法
  5. BZOJ1202 [HNOI2005]狡猾的商人 【并查集】
  6. 倒计时321控制器设置
  7. 物联网网络编程和web编程
  8. ios app的真机调试与发布配置
  9. str.length() 与 str.getBytes().length
  10. 【基础】利用thrift实现一个非阻塞带有回调机制的客户端