近期需要完成一個(gè)Android項(xiàng)目,那先從與數(shù)據(jù)庫(kù)交互最簡(jiǎn)單的登陸注冊(cè)開(kāi)始吧,現(xiàn)記錄過(guò)程如下:
此篇文章的小demo主要涉及數(shù)據(jù)庫(kù)的連接,以及相應(yīng)信息的查找與插入。
我已將源碼上傳至GitHub:
https://github.com/changyan-maker/LoginApp
首先展示一下完成效果。
數(shù)據(jù)庫(kù)設(shè)計(jì):
數(shù)據(jù)庫(kù)內(nèi)容:
登錄結(jié)果展示:
此處默認(rèn)您已經(jīng)安裝好Android studio 與MySQL軟件。
首先需要?jiǎng)?chuàng)建一個(gè)空項(xiàng)目,關(guān)于空的項(xiàng)目如何創(chuàng)建,請(qǐng)參考我本篇文章:
https://blog.csdn.net/changyana/article/details/122948513
接下來(lái)需要連接MySQL,首先需要開(kāi)啟網(wǎng)絡(luò)權(quán)限。需要添加一句話,具體位置如圖:(將項(xiàng)目切換成Android模式比較好找)
之后是導(dǎo)入Mysql-connection的jar包
關(guān)于這個(gè)jar包需要我們?nèi)ス倬W(wǎng)下載:https://downloads.mysql.com/archives/c-j/
關(guān)于版本的選擇個(gè)人建議選擇老一點(diǎn)的,比較穩(wěn)定。選擇ZIP格式進(jìn)行下載。
下載完成后在里邊找到mysql-connector-java-5.1.47-bin.jar并復(fù)制到粘貼板。
然后將Android studio的項(xiàng)目頁(yè)面切換到Project模式,找到如下文件的位置進(jìn)行粘貼。
粘貼完成后需要把剛才導(dǎo)入的jar包右擊Add as Library
然后切換回Android視圖,操作如下,新建一個(gè)package
然后粘貼代碼如下:
本篇文章從圖片可以看到我的項(xiàng)目名稱為HelloWorld,這個(gè)項(xiàng)目只是我用來(lái)做測(cè)試的。但是代碼是我完善后放在另一個(gè)項(xiàng)目為party中的,所有的位置都是一樣的,只是項(xiàng)目名稱不一樣,這個(gè)不用擔(dān)心。你只需要把我的代碼里的包名改成你項(xiàng)目的名稱就好了。
注意數(shù)據(jù)庫(kù)的連接:要連接的數(shù)據(jù)庫(kù),還有用戶名和密碼都要和自己的Mysql對(duì)應(yīng)。
package com.example.party.utils;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* function: 數(shù)據(jù)庫(kù)工具類,連接數(shù)據(jù)庫(kù)用
*/
public class JDBCUtils {
private static final String TAG = "mysql-party-JDBCUtils";
private static String driver = "com.mysql.jdbc.Driver";// MySql驅(qū)動(dòng)
private static String dbName = "party";// 數(shù)據(jù)庫(kù)名稱
private static String user = "root";// 用戶名
private static String password = "";// 密碼
public static Connection getConn(){
Connection connection = null;
try{
Class.forName(driver);// 動(dòng)態(tài)加載類
String ip = "10.0.2.2";// 寫(xiě)成本機(jī)地址,不能寫(xiě)成localhost,同時(shí)手機(jī)和電腦連接的網(wǎng)絡(luò)必須是同一個(gè)
// 嘗試建立到給定數(shù)據(jù)庫(kù)URL的連接
connection = DriverManager.getConnection("jdbc:mysql://" + ip + ":3306/" + dbName,
user, password);
}catch (Exception e){
e.printStackTrace();
}
return connection;
}
}
接著創(chuàng)建entity和User
位置如圖,創(chuàng)建方法與上述創(chuàng)建JDBCUtils一樣
代碼如下:
package com.example.party.entity;
public class User {
private int id;
private String userAccount;
private String userPassword;
private String userName;
private int userType;
private int userState;
private int userDel;
public User() {
}
public User(int id, String userAccount, String userPassword, String userName, int userType, int userState, int userDel) {
this.id = id;
this.userAccount = userAccount;
this.userPassword = userPassword;
this.userName = userName;
this.userType = userType;
this.userState = userState;
this.userDel = userDel;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserAccount() {
return userAccount;
}
public void setUserAccount(String userAccount) {
this.userAccount = userAccount;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getUserType() {
return userType;
}
public void setUserType(int userType) {
this.userType = userType;
}
public int getUserState() {
return userState;
}
public void setUserState(int userState) {
this.userState = userState;
}
public int getUserDel() {
return userDel;
}
public void setUserDel(int userDel) {
this.userDel = userDel;
}
}
之后創(chuàng)建dao和UserDao
package com.example.party.dao;
import com.example.party.entity.User;
import com.example.party.utils.JDBCUtils;
import android.util.Log;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
/**
* author: yan
* date: 2022.02.17
* **/
public class UserDao {
private static final String TAG = "mysql-party-UserDao";
/**
* function: 登錄
* */
public int login(String userAccount, String userPassword){
HashMap<String, Object> map = new HashMap<>();
// 根據(jù)數(shù)據(jù)庫(kù)名稱,建立連接
Connection connection = JDBCUtils.getConn();
int msg = 0;
try {
// mysql簡(jiǎn)單的查詢語(yǔ)句。這里是根據(jù)user表的userAccount字段來(lái)查詢某條記錄
String sql = "select * from user where userAccount = ?";
if (connection != null){// connection不為null表示與數(shù)據(jù)庫(kù)建立了連接
PreparedStatement ps = connection.prepareStatement(sql);
if (ps != null){
Log.e(TAG,"賬號(hào):" + userAccount);
//根據(jù)賬號(hào)進(jìn)行查詢
ps.setString(1, userAccount);
// 執(zhí)行sql查詢語(yǔ)句并返回結(jié)果集
ResultSet rs = ps.executeQuery();
int count = rs.getMetaData().getColumnCount();
//將查到的內(nèi)容儲(chǔ)存在map里
while (rs.next()){
// 注意:下標(biāo)是從1開(kāi)始的
for (int i = 1;i <= count;i++){
String field = rs.getMetaData().getColumnName(i);
map.put(field, rs.getString(field));
}
}
connection.close();
ps.close();
if (map.size()!=0){
StringBuilder s = new StringBuilder();
//尋找密碼是否匹配
for (String key : map.keySet()){
if(key.equals("userPassword")){
if(userPassword.equals(map.get(key))){
msg = 1; //密碼正確
}
else
msg = 2; //密碼錯(cuò)誤
break;
}
}
}else {
Log.e(TAG, "查詢結(jié)果為空");
msg = 3;
}
}else {
msg = 0;
}
}else {
msg = 0;
}
}catch (Exception e){
e.printStackTrace();
Log.d(TAG, "異常login:" + e.getMessage());
msg = 0;
}
return msg;
}
/**
* function: 注冊(cè)
* */
public boolean register(User user){
HashMap<String, Object> map = new HashMap<>();
// 根據(jù)數(shù)據(jù)庫(kù)名稱,建立連接
Connection connection = JDBCUtils.getConn();
try {
String sql = "insert into user(userAccount,userPassword,userName,userType,userState,userDel) values (?,?,?,?,?,?)";
if (connection != null){// connection不為null表示與數(shù)據(jù)庫(kù)建立了連接
PreparedStatement ps = connection.prepareStatement(sql);
if (ps != null){
//將數(shù)據(jù)插入數(shù)據(jù)庫(kù)
ps.setString(1,user.getUserAccount());
ps.setString(2,user.getUserPassword());
ps.setString(3,user.getUserName());
ps.setInt(4,user.getUserType());
ps.setInt(5, user.getUserState());
ps.setInt(6,user.getUserDel());
// 執(zhí)行sql查詢語(yǔ)句并返回結(jié)果集
int rs = ps.executeUpdate();
if(rs>0)
return true;
else
return false;
}else {
return false;
}
}else {
return false;
}
}catch (Exception e){
e.printStackTrace();
Log.e(TAG, "異常register:" + e.getMessage());
return false;
}
}
/**
* function: 根據(jù)賬號(hào)進(jìn)行查找該用戶是否存在
* */
public User findUser(String userAccount) {
// 根據(jù)數(shù)據(jù)庫(kù)名稱,建立連接
Connection connection = JDBCUtils.getConn();
User user = null;
try {
String sql = "select * from user where userAccount = ?";
if (connection != null){// connection不為null表示與數(shù)據(jù)庫(kù)建立了連接
PreparedStatement ps = connection.prepareStatement(sql);
if (ps != null) {
ps.setString(1, userAccount);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
//注意:下標(biāo)是從1開(kāi)始
int id = rs.getInt(1);
String userAccount1 = rs.getString(2);
String userPassword = rs.getString(3);
String userName = rs.getString(4);
int userType = rs.getInt(5);
int userState = rs.getInt(6);
int userDel = rs.getInt(7);
user = new User(id, userAccount1, userPassword, userName, userType, userState, userDel);
}
}
}
}catch (Exception e){
e.printStackTrace();
Log.d(TAG, "異常findUser:" + e.getMessage());
return null;
}
return user;
}
}
編寫(xiě)登錄頁(yè)面
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:layout_editor_absoluteX="219dp"
tools:layout_editor_absoluteY="207dp"
android:padding="50dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="15sp"
android:text="賬號(hào):" />
<EditText
android:id="@+id/uesrAccount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="phone"
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="15sp"
android:text="密碼:"
/>
<EditText
android:id="@+id/userPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPersonName"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
<Button
android:layout_marginTop="50dp"
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登錄"
android:onClick="login"
/>
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="reg"
android:text="注冊(cè)" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
效果如圖:
完善MainActivity
package com.example.party;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.example.party.dao.UserDao;
/**
* function:連接頁(yè)面加載首頁(yè)
*/
public class MainActivity extends AppCompatActivity {
private static final String TAG = "mysql-party-MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void reg(View view){
startActivity(new Intent(getApplicationContext(),register.class));
}
/**
* function: 登錄
* */
public void login(View view){
EditText EditTextAccount = findViewById(R.id.uesrAccount);
EditText EditTextPassword = findViewById(R.id.userPassword);
new Thread(){
@Override
public void run() {
UserDao userDao = new UserDao();
int msg = userDao.login(EditTextAccount.getText().toString(),EditTextPassword.getText().toString());
hand1.sendEmptyMessage(msg);
}
}.start();
}
@SuppressLint("HandlerLeak")
final Handler hand1 = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 0){
Toast.makeText(getApplicationContext(), "登錄失敗", Toast.LENGTH_LONG).show();
} else if (msg.what == 1) {
Toast.makeText(getApplicationContext(), "登錄成功", Toast.LENGTH_LONG).show();
} else if (msg.what == 2){
Toast.makeText(getApplicationContext(), "密碼錯(cuò)誤", Toast.LENGTH_LONG).show();
} else if (msg.what == 3){
Toast.makeText(getApplicationContext(), "賬號(hào)不存在", Toast.LENGTH_LONG).show();
}
}
};
}
編寫(xiě)注冊(cè)頁(yè)面
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".register">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:layout_editor_absoluteX="219dp"
tools:layout_editor_absoluteY="207dp"
android:padding="50dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="15sp"
android:text="賬號(hào):" />
<EditText
android:id="@+id/userAccount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="phone"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="15sp"
android:text="昵稱:" />
<EditText
android:id="@+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPersonName"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="15sp"
android:text="密碼:"
/>
<EditText
android:id="@+id/userPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPassword"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
<Button
android:layout_marginTop="50dp"
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="注冊(cè)"
android:onClick="register"
/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
頁(yè)面如圖
完善register
上一步創(chuàng)建activity_register.xml的時(shí)候會(huì)自動(dòng)生成一個(gè)Class,位置如圖,如果沒(méi)有的話自己右鍵創(chuàng)建一個(gè)Class就可以。
package com.example.party;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.example.party.dao.UserDao;
import com.example.party.entity.User;
/**
* function:連接注冊(cè)頁(yè)面
*/
public class register extends AppCompatActivity {
private static final String TAG = "mysql-party-register";
EditText userAccount = null;
EditText userPassword = null;
EditText userName = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
userAccount = findViewById(R.id.userAccount);
userPassword = findViewById(R.id.userPassword);
userName = findViewById(R.id.userName);
}
public void register(View view){
String userAccount1 = userAccount.getText().toString();
String userPassword1 = userPassword.getText().toString();
String userName1 = userName.getText().toString();
User user = new User();
user.setUserAccount(userAccount1);
user.setUserPassword(userPassword1);
user.setUserName(userName1);
user.setUserType(1);
user.setUserState(0);
user.setUserDel(0);
new Thread(){
@Override
public void run() {
int msg = 0;
UserDao userDao = new UserDao();
User uu = userDao.findUser(user.getUserAccount());
if(uu != null){
msg = 1;
}
else{
boolean flag = userDao.register(user);
if(flag){
msg = 2;
}
}
hand.sendEmptyMessage(msg);
}
}.start();
}
@SuppressLint("HandlerLeak")
final Handler hand = new Handler()
{
public void handleMessage(Message msg) {
if(msg.what == 0) {
Toast.makeText(getApplicationContext(),"注冊(cè)失敗",Toast.LENGTH_LONG).show();
} else if(msg.what == 1) {
Toast.makeText(getApplicationContext(),"該賬號(hào)已經(jīng)存在,請(qǐng)換一個(gè)賬號(hào)",Toast.LENGTH_LONG).show();
} else if(msg.what == 2) {
Toast.makeText(getApplicationContext(), "注冊(cè)成功", Toast.LENGTH_LONG).show();
Intent intent = new Intent();
//將想要傳遞的數(shù)據(jù)用putExtra封裝在intent中
intent.putExtra("a","注冊(cè)");
setResult(RESULT_CANCELED,intent);
finish();
}
}
};
}
下面匯總一下都需要改變的文件!
然后運(yùn)行就可以啦!文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-796219.html
心得建議
我的大部分時(shí)間感覺(jué)都是花費(fèi)在了連接數(shù)據(jù)庫(kù)上。剛開(kāi)始數(shù)據(jù)庫(kù)一直連接無(wú)法連接,原因是連接的請(qǐng)求要放在一個(gè)新的線程里,不能直接在當(dāng)前線程請(qǐng)求連接數(shù)據(jù)庫(kù)。之后解決了連接問(wèn)題后得到數(shù)據(jù)進(jìn)行匹配都是比較簡(jiǎn)單的事情。
個(gè)人建議:如果出問(wèn)題可以先建一個(gè)臨時(shí)的項(xiàng)目然后按照【連接數(shù)據(jù)庫(kù)】–> 【請(qǐng)求數(shù)據(jù)并在控制臺(tái)輸出】 --> 【建立前端頁(yè)面交互】這樣的過(guò)程一步一步進(jìn)行調(diào)試。
祝成功!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-796219.html
到了這里,關(guān)于Android studio連接MySQL并完成簡(jiǎn)單的登錄注冊(cè)功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!