You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从SQL Server获取数据并在Android的TextView中展示?代码求助

你的SQL Server数据展示代码问题修正

嘿,我帮你梳理下这段代码里的几个关键问题,然后给你调整后的版本:

原代码里的问题点

  • 严重的SQL注入风险:直接把UID变量拼接到SQL语句里,恶意用户很容易通过构造特殊值篡改SQL逻辑,导致数据泄露或破坏。
  • PreparedStatement使用错误:你用了con.prepareStatement(query)却赋值给Statement类型变量,而且调用executeQuery(query)时还传了SQL语句——PreparedStatement不需要这么做,应该用参数绑定的方式。
  • UI元素重复查找:在while循环里每次都调用findViewById(R.id.name),这会重复消耗资源,应该提前在Activity/Fragment的初始化阶段找到这个TextView。
  • 资源泄漏:Connection、Statement/PreparedStatement、ResultSet用完后没有关闭,会导致数据库连接池资源耗尽。
  • 主线程风险:如果这是Android代码,直接在点击事件里做数据库连接操作会阻塞主线程,引发ANR(应用无响应),必须放到异步线程执行。

修正后的代码示例

第一步:提前初始化TextView(比如在Activity的onCreate里)

private TextView nameTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_layout);
    
    // 提前找到TextView,避免重复查找
    nameTextView = findViewById(R.id.name);
    Button Connect = findViewById(R.id.your_connect_button_id);
    
    Connect.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            // 用AsyncTask执行数据库操作(Android中推荐用Coroutine或WorkManager替代AsyncTask,但先给你基础示例)
            new FetchDriverTask().execute(UID);
        }
    });
}

第二步:异步任务处理数据库操作

private class FetchDriverTask extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        String uid = params[0];
        String firstName = null;
        
        Connection con = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        
        try {
            con = connectionClass.CONN();
            if (con != null) {
                // 使用参数绑定避免SQL注入
                String query = "SELECT FirstName FROM Driver WHERE UID=?";
                pstmt = con.prepareStatement(query);
                pstmt.setString(1, uid); // 绑定第一个参数(?的位置从1开始)
                
                rs = pstmt.executeQuery();
                if (rs.next()) { // 因为UID应该是唯一的,用if代替while更合理
                    firstName = rs.getString("FirstName");
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
            // 这里可以添加错误日志或提示用户
        } finally {
            // 关闭资源,避免泄漏
            try {
                if (rs != null) rs.close();
                if (pstmt != null) pstmt.close();
                if (con != null) con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        
        return firstName;
    }

    @Override
    protected void onPostExecute(String firstName) {
        super.onPostExecute(firstName);
        // 在主线程更新UI
        if (firstName != null) {
            nameTextView.setText(firstName);
        } else {
            nameTextView.setText("未找到该用户");
        }
    }
}

额外注意事项

  • 确保你的connectionClass.CONN()方法是正确的,并且在Android中已经配置了SQL Server的JDBC驱动(注意权限和依赖)。
  • 如果你用的是较新的Android版本,AsyncTask已经被标记为废弃,推荐使用Coroutines或者RxJava来处理异步操作,代码会更简洁且更符合现代Android开发规范。
  • 一定要处理连接失败的情况,比如给用户弹出Toast提示“数据库连接失败”。

内容的提问来源于stack exchange,提问作者Jacent Biares Torrato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:41:37