小言_互联网的博客

Android 学习笔记 -- MySql直连

323人阅读  评论(0)

1、在Android工程中引入JDBC驱动,直接连接。

新建项目 connection_mysql 在Project视图下可以找到 app/libs文件夹下

将mysql-connector-java-5.1.44-bin.jar 复制到libs文件夹下

点击导航栏 File ⋙ Project Structure

选择 Dependencies ⋙ app ⋙ libs ,点击 + 号,下拉Step 1.,选择对应jar包,点击Apply

当显示如下图,则说明JDBC驱动添加成功

2、写一个单独的类连接数据库

注意: 连接数据库是需要网络的,千万别忘了在AndroidManifest.xml 添加访问网络权限:

<uses-permission android:name="android.permission.INTERNET" />
public class Dbconn {

    private static String driver = "com.mysql.jdbc.Driver";
    private static Connection conn;

    public static Connection getConn(){
        try {
            Class.forName(driver);
            Log.d("数据库连接", "getConn: 数据库驱动加载成功");

            String url = "jdbc:mysql://10.0.2.2/test?useUnicode=true&characterEncoding=utf-8";
            String user = "root";
            String password = "root";

            conn = DriverManager.getConnection(url,user,password);
            Log.d("数据库连接", "getConn: 数据库连接成功");
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
            Log.d("数据库连接", "getConn: 数据库连接失败");
            return  null;
        }
        return conn;
    }

    public static void closeConn(Connection conn, PreparedStatement preStmt, ResultSet rs){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(preStmt!=null){
            try {
                preStmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
	}

注意: String url = “jdbc:mysql://10.0.2.2/test?useUnicode=true&characterEncoding=utf-8”;

如果访问的是本地数据库,localhost或者127.0.0.1的ip其实是不对的  

连接数据库超时,可能是因为ip不对,网上使用jdbc连接数据库,
有一部分数据库ip中为	localhost或者127.0.0.1数据库是安装才本机上的,
安卓程序运行访问的数据库ip地址是localhost,
安卓程序是独立在Virtual Device中的,虚拟机中无法安装了数据库
所以说,电脑和安卓虚拟机其实是两个ip地址,应该改为本机数据库地址,

可以在cmd中输入ipconfig查看Ipv4地址,换掉localhost 或者127.0.0.1

或者ip改为10.0.2.2,这是Android虚拟机的默认宿主IP地址

其他方法可以参见:CSDN博主「土豆是我的最爱」
链接:https://blog.csdn.net/qq_37141773/article/details/84326163

3、具体实现代码

3.1 创建 Dao.java 文件
public class Dao {

    private static Connection conn;
    private static PreparedStatement preStmt;
    private static ResultSet rs;

    private String sql1 = "select * from login where account=? and password=?";

    public boolean login(String account, String password) throws SQLException {
        boolean flag = false;
        conn = Dbconn.getConn();
        Log.d("数据库连接返回值", "login: "+conn);
        preStmt = conn.prepareStatement(sql1);
        preStmt.setString(1,account);
        preStmt.setString(2,password);
        rs = preStmt.executeQuery();
        flag = rs.first();
        Dbconn.closeConn(conn,preStmt,rs);
        return flag;
    }
}
3.2 修改layout/activity_main.xml 布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_marginTop="160dp"
        android:layout_marginLeft="40dp"
        android:id="@+id/account_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="用户名:"
        android:textSize="28dp"
        />

    <EditText
        android:layout_alignTop="@id/account_textView"
        android:layout_alignLeft="@id/account_textView"
        android:layout_marginLeft="120dp"
        android:id="@+id/account_editView"
        android:layout_width="200dp"
        android:layout_height="42dp"
        android:textSize="21dp" />

    <TextView
        android:layout_alignTop="@id/account_textView"
        android:layout_alignLeft="@id/account_textView"
        android:layout_marginTop="50dp"
        android:id="@+id/password_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="密码:"
        android:textSize="28dp"
        />

    <EditText
        android:layout_alignTop="@id/account_editView"
        android:layout_alignLeft="@id/password_textView"
        android:layout_marginLeft="120dp"
        android:layout_marginTop="50dp"
        android:id="@+id/password_editView"
        android:layout_width="200dp"
        android:layout_height="42dp"
        android:textSize="21dp" />
    
    <Button
        android:id="@+id/submit_button"
        android:layout_marginRight="26dp"
        android:layout_marginTop="60dp"
        android:layout_marginLeft="60dp"
        android:layout_alignLeft="@id/password_textView"
        android:layout_alignTop="@id/password_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登陆"
        android:textSize="21dp"
        />
    <Button
        android:id="@+id/zc_button"
        android:layout_alignTop="@id/submit_button"
        android:layout_toRightOf="@id/submit_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="注册"
        android:textSize="21dp"
        />
</RelativeLayout>

效果图

3.3 修改 MainActivity.java 文件
public class MainActivity extends AppCompatActivity implements View.OnClickListener{

   private static final String TAG = "MainActivity活动";
    private EditText editText_account;
    private EditText editText_password;
    private Button button_login;
    private Button button_zc;

    private String account;
    private String password;

Handler有个特点,在执行 new Handler() 的时候,默认情况下Handler会绑定当前代码执行的线程,我们在主线程中实例化了myHandler,所以myHandler就自动绑定了主线程,即UI线程。

重写Handler的handleMessage方法,根据Message的what值进行不同的处理操作

msg.what 是我们自定义的一个 Message的识别码 ,以便于在Handler的handleMessage方法中 根据what识别出不同的Messag ,以便我们做出不同的处理操作

 //myHandler在主线程中创建,所以自动绑定主线程
    @SuppressLint("HandlerLeak")
    private Handler myHandler = new Handler(){
        @Override
        public void handleMessage(Message msg){
            switch (msg.what){
                case 1:
                	//登陆成功将弹出
                    Toast.makeText(MainActivity.this,"登陆成功",Toast.LENGTH_SHORT).show();
                    Log.d(TAG, "run: UI更新成功");
                    break;
                default:
                    break;
            }
        }
    };

加载布局文件

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editText_account = (EditText)findViewById(R.id.account_editView);
        editText_password = (EditText)findViewById(R.id.password_editView);
        button_login = (Button)findViewById(R.id.submit_button);
        button_zc = (Button)findViewById(R.id.zc_button);
        //给按钮注册监听器
        button_login.setOnClickListener(this);
    }

Android4.0之后,不允许在主线程中进行比较耗时的操作(连接数据库就属于比较耗时的操作),需要开一个新的线程来处理这种耗时的操作

因为这个活动(MainActivity)实现了 View.OnClickListener 接口,所以直接在活动内重写onClick()方法即可实现监听注册

 @Override
    public void onClick(View view) {
        switch(view.getId()){
            case R.id.submit_button:
                account = editText_account.getText().toString();
                password = editText_password.getText().toString();
                Log.d(TAG, "onClick: 账号:"+account+" 密码:"+password);
                //创建子线程
                MyThread1 myThread1= new MyThread1();
                //启动子线程 thread1.start();
                Thread thread1 = new Thread(myThread1);
                thread1.start();
                break;
            default:
                break;
        }
    }

创建一个私有的内部类(子线程)MyThread1实现Runnable接口 来实现连接数据库验证功能;

   private class MyThread1 implements Runnable{
        @Override
        public void run() {
            Dao dao = new Dao();
            boolean flag = false;
            try {
                flag = dao.login(account, password);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            if(flag){
                Log.d(TAG, "run: 登陆成功");
                //Message的构造函数式public的
                //还可以通过Message.obtain()
                //Handler.obtainMessage()来获得一个Message对象(Handler.obtainMessage()内部其实调用了Message.obtain())
                Message msg = new Message();
                msg.what = 1;
                //通过Handler.sendMessage(Message)方法将Message传入Handler中让其在handleMessage中对其进行处理
                myHandler.sendMessage(msg);
                Log.d(TAG, "run: Message 唯一识别码 msg.what 发送成功");
            }
        }
    }
}

对于Android中Handler的使用参见:CSDN博主「孙群」
链接:https://blog.csdn.net/iispring/article/details/47115879

对于Android中Handler的防泄漏参见:CSDN博主「魔法少女 厄加特」
链接:https://blog.csdn.net/qq_37321098/article/details/81535449

4、程序执行结果

启动虚拟机,验证结果(我的数据库已经写入数据account : “123” ,password : “123”)

新手,请大佬勿喷,仅仅只是作个笔记。


转载:https://blog.csdn.net/weixin_44462664/article/details/102565639
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场