在Android中使用JDBC优化mysql数据库的执行

问题描述

我在android中有一些代码正在运行对我在线托管的数据库的查询。 我在此活动中使用AsyncTask来执行数据库操作,类似地,我也有其他活动,它们具有相似的代码和连接过程。我想知道这是否是在android中使用JDBC连接连接到mysql db的最佳方法,或者可以对此进行改进

与MainActivity类一样,该代码需要大约3秒钟的登录时间。

public class MainActivity extends AppCompatActivity {

private ProgressDialog mProgress;
final int REQUEST_PERMISSION_CODE = 1000;

private static final String url = "jdbc:mysql://192.168.0.103/pos";
private static final String user = "root";
private static final String pass = "";
private EditText mPassword,mUsername;
private Button loginBtn;
private ProgressBar mLoginProgress;
private TextView mLoginFeedbackText;
String password,username;
ProgressDialog progressDialog;
Boolean CheckEditText;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);

    if (!checkPermissionFromDevice())
        requestPermission();

    mPassword = findViewById(R.id.password);
    mUsername = findViewById(R.id.username);
    loginBtn = findViewById(R.id.generate_btn);
    mLoginProgress = findViewById(R.id.login_progress_bar);
    mLoginFeedbackText = findViewById(R.id.login_form_feedback);
    mProgress = new ProgressDialog(this);
    
    loginBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            CheckEditTextIsEmptyOrNot();
            if (CheckEditText) {
                UserLoginFunction(username,password);
            } else {
                Toast.makeText(MainActivity.this,"Please fill all form fields.",Toast.LENGTH_LONG).show();
            }
        }
    });
}

public void CheckEditTextIsEmptyOrNot() {
    username = mUsername.getText().toString();
    password = mPassword.getText().toString();
    if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) {
        CheckEditText = false;
    } else {
        CheckEditText = true;
    }
}

private void requestPermission() {
    ActivityCompat.requestPermissions(this,new String[]{
            Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.RECORD_AUDIO
    },REQUEST_PERMISSION_CODE);
}

private boolean checkPermissionFromDevice() {
    int write_external_storage_result = ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE);
    int record_audio_result = ContextCompat.checkSelfPermission(this,Manifest.permission.RECORD_AUDIO);
    return write_external_storage_result == PackageManager.PERMISSION_GRANTED &&
            record_audio_result == PackageManager.PERMISSION_GRANTED;
}
public void UserLoginFunction(final String username,final String password) {
    class UserLoginClass extends AsyncTask<String,Void,String> {
        @Override
        protected void onPreExecute() {
            System.out.println("In onPreExecute");
            super.onPreExecute();

            progressDialog = ProgressDialog.show(MainActivity.this,"Loading Data",null,true,true);
        }

        @Override
        protected void onPostExecute(String httpResponseMsg) {
            System.out.println("In onPostExecute");
            super.onPostExecute(httpResponseMsg);

            progressDialog.dismiss();

            if (httpResponseMsg.equalsIgnoreCase("It matches")) {

                finish();

                Intent intent = new Intent(MainActivity.this,StartActivity.class);
                System.out.println("USERNAME" + username);
                intent.putExtra("USERNAME",username);
                startActivity(intent);

            } else {
                mLoginFeedbackText.setText("Verification Failed,please try again.");
                mLoginFeedbackText.setVisibility(View.VISIBLE);
                mLoginProgress.setVisibility(View.INVISIBLE);
                loginBtn.setEnabled(true);
                Toast.makeText(MainActivity.this,httpResponseMsg,Toast.LENGTH_LONG).show();
            }

        }

        @Override
        protected String doInBackground(String... params) {
            System.out.println("In doInBackground");
            try {
                StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
                StrictMode.setThreadPolicy(policy);

                Class.forName("com.mysql.jdbc.Driver");
                Connection con = DriverManager.getConnection(url,user,pass);

                Statement st = con.createStatement();
                ResultSet rs = st.executeQuery("SELECT * FROM `users` WHERE username='BobMartin'");


                while (rs.next()) {
                    String queryPassword = rs.getString("password");
                    String hash_php = queryPassword.replaceFirst("2y","2a");
                    if (BCrypt.checkpw(password,hash_php)) {
                        con.close();
                        System.out.println("It matches");
                        return "It matches";
                    } else {
                        System.out.println("It does not match");
                        return "It does not match";
                    }
                }
            } catch (ClassNotFoundException | SQLException e) {
                e.printStackTrace();
                System.out.println("result in catch");
            }
            return "It does not match";
        }
    }
    UserLoginClass userLoginClass = new UserLoginClass();
    userLoginClass.execute(username,password);
}


}

类似地,对于其他活动,我也再次以如图所示的方式创建连接并关闭它们。

public class StartActivity extends AppCompatActivity {
Button startButton;
String userName;
private static final String url = "jdbc:mysql://192.168.0.103/pos";
private static final String user = "root";
private static final String pass = "";

ArrayList<String> dbQuestions = new ArrayList<String>();
ArrayList<String> dbAnswers = new ArrayList<String>();

ProgressDialog progressDialog;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    userName = getIntent().getStringExtra("USERNAME");
    new StartDb().execute();

    startButton = findViewById(R.id.startButton);
    startButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            System.out.println("USERNAMEstart" + userName);
            Intent intent = new Intent(StartActivity.this,BillActivity.class);
            Bundle args = new Bundle();
            args.putSerializable("ANSWERS",(Serializable) dbAnswers);
            args.putSerializable("QUESTIONS",(Serializable) dbQuestions);
            intent.putExtra("USERNAME",userName);
            intent.putExtra("BUNDLE",args);
            startActivity(intent);
        }
    });
}

@Override
public void onBackPressed() {
    // super.onBackPressed();
    Toast.makeText(StartActivity.this,"There is no back action",Toast.LENGTH_LONG).show();
    return;
}

class StartDb extends AsyncTask<String,String> {

    @Override
    protected void onPreExecute() {
        System.out.println("In onPreExecute");
        super.onPreExecute();

        progressDialog = ProgressDialog.show(StartActivity.this,true);
    }

    @Override
    protected void onPostExecute(String httpResponseMsg) {
        System.out.println("In onPostExecute");
        super.onPostExecute(httpResponseMsg);
        progressDialog.dismiss();
    }

    @Override
    protected String doInBackground(String... params) {
        System.out.println("In doInBackground");
        try {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);

            Class.forName("com.mysql.jdbc.Driver");
            Connection con = DriverManager.getConnection(url,pass);

            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM `company_details`");

            while (rs.next()) {

                String que = rs.getString("questions");
                JSONObject obj1 = new JSONObject(que);
                for (Iterator<String> it = obj1.keys(); it.hasNext(); ) {
                    String key = it.next();
                    dbQuestions.add(obj1.getString(key));
                }

                String ans = rs.getString("answers");
                JSONObject obj2 = new JSONObject(ans);
                for (Iterator<String> it = obj2.keys(); it.hasNext(); ) {
                    String key = it.next();
                    dbAnswers.add(obj2.getString(key));
                }

                con.close();
            }
        } catch (ClassNotFoundException | SQLException | JSONException e) {
            e.printStackTrace();
            System.out.println("resilt in catch");
        }
        return "It does not match";
    }
}

}

请提出如何增加执行时间的建议。

解决方法

MySQL协议在长距离上无法完全正常运行。这只是事实。

如果您需要远距离访问MySQL,则应在数据库前面放置一个rest / api,使其在物理上尽可能靠近MySQL运行,然后让您的应用进行查询,例如在容器中运行多个API网关以进行故障转移和负载平衡。

[MySQL]-[REST/API Gateway]-----------{Internet}------------[Client]

我从未使用过它,但是看起来这种事情可以满足您的要求-https://www.progress.com/odata/mysql

或者这个“从现有的MySQL数据库自动生成REST API”-https://www.indiehackers.com/product/noco/auto-generate-a-rest-api-from-an-existing-mysql-db--Lt2CGDHrNrZVLZLMpaI

您使用哪种rest / api取决于您最喜欢哪种后端语言。

说实话,您真正应该做的是将特定于应用程序的rest / api放在数据库的前面,这样,如果存储在您应用程序中的数据库凭据被黑客入​​侵,人们就不能仅仅破坏数据库。

即您应该有一个rest / api,它对客户端应用程序可以执行的操作施加特定于应用程序的安全限制。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...