用单例模式和子线程实现查询数据库中的表单数据。

本文介绍了如何在Java中创建一个名为DatabaseQuery的类,实现Runnable接口并遵循单例模式。该类在构造函数中初始化数据库连接和Statement对象,通过getInstance()获取实例并在run()方法中执行SQL查询。在main()方法中启动查询子线程并输出结果。

1、创建一个名为DatabaseQuery的类,实现Runnable接口并实现单例模式。

2、在单例模式的构造函数中建立数据库连接,并创建Statement对象。

3、通过getInstance()方法获取DatabaseQuery类的实例。

4、在run()方法中执行数据库查询,并输出查询结果。

5、在main()方法中获取DatabaseQuery实例,创建一个线程并启动。

代码如下:单例模式的查询子线程。

 

package com.singletonmodel;

import java.sql.*;

public class DatabaseQuery implements Runnable {
	private static DatabaseQuery instance;
	private Connection connection;
	private Statement statement;

	private DatabaseQuery() {
		try {
			connection = DriverManager.getConnection("jdbc:mysql://localhost/test_data?user=root&password=admin");
			statement = connection.createStatement();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static DatabaseQuery getInstance() {
		if (instance == null) {
			instance = new DatabaseQuery();
		}
		return instance;
	}

	@Override
	public void run() {
		try {
			String query = "SELECT * FROM words_info";
			ResultSet resultSet = statement.executeQuery(query);

			while (resultSet.next()) {
				int id = resultSet.getInt("Id");
				String engName = resultSet.getString("eng_name");
				String chiVal = resultSet.getString("chi_val");
				String lastUsedTime = resultSet.getString("last_used_time");
				int usedTimes = resultSet.getInt("used_times");
				String createdTime = resultSet.getString("created_time");
				int priority = resultSet.getInt("priority");

				System.out.println("Id: " + id);
				System.out.println("eng_name: " + engName);
				System.out.println("chi_val: " + chiVal);
				System.out.println("last_used_time: " + lastUsedTime);
				System.out.println("used_times: " + usedTimes);
				System.out.println("created_time: " + createdTime);
				System.out.println("priority: " + priority);
				System.out.println("-----------------------------");
			}

			resultSet.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

 在主线程中启动查询子线程:

package com.singletonmodel;

public class Main {
	
	 public static void main(String[] args) {
	        DatabaseQuery databaseQuery = DatabaseQuery.getInstance();
	        Thread thread = new Thread(databaseQuery);
	        thread.start();
	    }
}

输出结果:

1.新建常量类StorageConstants: package com.diodz.base.constant; /** * 存储相关常量定义 */ public class StorageConstants { // SharedPreferences文件名 public static final String SP_NAME = "user_info_sp"; // 存储键 public static final String KEY_USERNAME = "username"; public static final String KEY_PASSWORD = "password"; // 文件存储文件名 public static final String FILE_NAME = "user_info.txt"; // SQLite数据库配置 public static final String DB_NAME = "user_db.db"; public static final int DB_VERSION = 1; public static final String DB_TABLE = "user"; // Service通信Action public static final String ACTION_WRITE = "com.diodz.base.ACTION_WRITE"; public static final String ACTION_READ = "com.diodz.base.ACTION_READ"; // Intent传递数据键 public static final String EXTRA_USERNAME = "extra_username"; public static final String EXTRA_PASSWORD = "extra_password"; public static final String EXTRA_STORAGE_TYPE = "extra_storage_type"; // 存储类型(1=SP, 2=文件, 3=SQLite) public static final int STORAGE_SP = 1; public static final int STORAGE_FILE = 2; public static final int STORAGE_SQLITE = 3; } 2.新建SQLite 数据库帮助类.SQLiteHelper package com.diodz.base; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import com.diodz.base.constant.StorageConstants; /** * SQLite数据库帮助类(创建表、升级) */ public class SQLiteHelper extends SQLiteOpenHelper { // 创建用户表SQL private static final String CREATE_TABLE_SQL = "CREATE TABLE " + StorageConstants.DB_TABLE + " (" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "username TEXT UNIQUE NOT NULL," + "password TEXT NOT NULL)"; public SQLiteHelper(Context context) { super(context, StorageConstants.DB_NAME, null, StorageConstants.DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_TABLE_SQL); // 创建表 } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + StorageConstants.DB_TABLE); onCreate(db); // 升级时删除旧表重建 } } 3.新建存储工具类StorageUtil package com.diodz.base.util; import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.diodz.base.SQLiteHelper; import com.diodz.base.constant.StorageConstants; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /** * 存储工具类(封装3种存储的读写逻辑) */ public class StorageUtil { // ==================== SharedPreferences ==================== public static void saveToSP(Context context, String username, String password) { SharedPreferences sp = context.getSharedPreferences(StorageConstants.SP_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putString(StorageConstants.KEY_USERNAME, username); editor.putString(StorageConstants.KEY_PASSWORD, password); editor.commit(); } public static String[] readFromSP(Context context) { SharedPreferences sp = context.getSharedPreferences(StorageConstants.SP_NAME, Context.MODE_PRIVATE); String username = sp.getString(StorageConstants.KEY_USERNAME, ""); String password = sp.getString(StorageConstants.KEY_PASSWORD, ""); return new String[]{username, password}; } // ==================== 文件存储 ==================== public static void saveToFile(Context context, String username, String password) throws IOException { String content = username + "|" + password; // 用分隔符区分用户名密码 FileOutputStream fos = context.openFileOutput(StorageConstants.FILE_NAME, Context.MODE_PRIVATE); fos.write(content.getBytes()); fos.flush(); fos.close(); } public static String[] readFromFile(Context context) throws IOException { FileInputStream fis = context.openFileInput(StorageConstants.FILE_NAME); byte[] bytes = new byte[fis.available()]; fis.read(bytes); fis.close(); String content = new String(bytes); return content.split("\\|"); // 分割字符串 } // ==================== SQLite ==================== public static void saveToSQLite(Context context, String username, String password) { SQLiteHelper dbHelper = new SQLiteHelper(context); SQLiteDatabase db = dbHelper.getWritableDatabase(); // 先删除旧数据(避免重复) db.delete(StorageConstants.DB_TABLE, "username=?", new String[]{username}); // 插入新数据 String insertSQL = "INSERT INTO " + StorageConstants.DB_TABLE + "(username, password) VALUES(?, ?)"; db.execSQL(insertSQL, new Object[]{username, password}); db.close(); } public static String[] readFromSQLite(Context context) { SQLiteHelper dbHelper = new SQLiteHelper(context); SQLiteDatabase db = dbHelper.getReadableDatabase(); String[] result = new String[]{"", ""}; Cursor cursor = db.query(StorageConstants.DB_TABLE, null, null, null, null, null, null); if (cursor.moveToFirst()) { result[0] = cursor.getString(cursor.getColumnIndex("username")); result[1] = cursor.getString(cursor.getColumnIndex("password")); } cursor.close(); db.close(); return result; } } 4.新建后台服务类StorageService package com.diodz.base; import android.app.Service; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.Message; import com.diodz.base.constant.StorageConstants; import com.diodz.base.util.StorageUtil; import java.io.IOException; /** * 后台服务(通过子线程执行存储操作,避免阻塞UI) */ public class StorageService extends Service { // 消息标识(主线程更新UI) private static final int MSG_READ_SUCCESS = 1001; private static final int MSG_ERROR = 1002; // Handler(子线程向主线程发送消息) private Handler mHandler = new Handler(msg -> { Intent broadcastIntent = new Intent(); broadcastIntent.setAction("com.diodz.base.STORAGE_RESULT"); switch (msg.what) { case MSG_READ_SUCCESS: String[] data = (String[]) msg.obj; broadcastIntent.putExtra(StorageConstants.KEY_USERNAME, data[0]); broadcastIntent.putExtra(StorageConstants.KEY_PASSWORD, data[1]); break; case MSG_ERROR: broadcastIntent.putExtra("error", msg.obj.toString()); break; } sendBroadcast(broadcastIntent); // 发送广播通知MainActivity return true; }); @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null) { String action = intent.getAction(); int storageType = intent.getIntExtra(StorageConstants.EXTRA_STORAGE_TYPE, StorageConstants.STORAGE_SP); String username = intent.getStringExtra(StorageConstants.EXTRA_USERNAME); String password = intent.getStringExtra(StorageConstants.EXTRA_PASSWORD); // 子线程执行存储操作 new Thread(() -> { try { if (StorageConstants.ACTION_WRITE.equals(action)) { // 写入数据 switch (storageType) { case StorageConstants.STORAGE_SP: StorageUtil.saveToSP(getApplicationContext(), username, password); break; case StorageConstants.STORAGE_FILE: StorageUtil.saveToFile(getApplicationContext(), username, password); break; case StorageConstants.STORAGE_SQLITE: StorageUtil.saveToSQLite(getApplicationContext(), username, password); break; } } else if (StorageConstants.ACTION_READ.equals(action)) { // 读取数据 String[] data; switch (storageType) { case StorageConstants.STORAGE_SP: data = StorageUtil.readFromSP(getApplicationContext()); break; case StorageConstants.STORAGE_FILE: data = StorageUtil.readFromFile(getApplicationContext()); break; case StorageConstants.STORAGE_SQLITE: data = StorageUtil.readFromSQLite(getApplicationContext()); break; default: data = new String[]{"", ""}; } // 发送读取成功消息 Message msg = mHandler.obtainMessage(MSG_READ_SUCCESS, data); mHandler.sendMessage(msg); } } catch (IOException e) { Message msg = mHandler.obtainMessage(MSG_ERROR, "文件操作失败:" + e.getMessage()); mHandler.sendMessage(msg); } catch (Exception e) { Message msg = mHandler.obtainMessage(MSG_ERROR, "操作失败:" + e.getMessage()); mHandler.sendMessage(msg); } }).start(); } return START_STICKY; } } 5.修改主界面 package com.diodz.base; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.diodz.base.constant.StorageConstants; /** * 主界面(用户交互入口) */ public class MainActivity extends AppCompatActivity { private EditText etUsername; private EditText etPassword; private Button btnWrite; private Button btnRead; // 选择存储类型(默认SharedPreferences) private int currentStorageType = StorageConstants.STORAGE_SP; // 广播接收器(接收Service的结果回调) private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String error = intent.getStringExtra("error"); if (error != null) { Toast.makeText(MainActivity.this, error, Toast.LENGTH_SHORT).show(); return; } // 读取成功,填充输入框 String username = intent.getStringExtra(StorageConstants.KEY_USERNAME); String password = intent.getStringExtra(StorageConstants.KEY_PASSWORD); etUsername.setText(username); etPassword.setText(password); Toast.makeText(MainActivity.this, "读取成功", Toast.LENGTH_SHORT).show(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化控件 initView(); // 注册广播接收器 registerReceiver(mReceiver, new IntentFilter("com.diodz.base.STORAGE_RESULT")); } private void initView() { etUsername = findViewById(R.id.et_username); etPassword = findViewById(R.id.et_password); btnWrite = findViewById(R.id.btn_write); btnRead = findViewById(R.id.btn_read); // 写入按钮点击事件 btnWrite.setOnClickListener(v -> { String username = etUsername.getText().toString().trim(); String password = etPassword.getText().toString().trim(); if (username.isEmpty() || password.isEmpty()) { Toast.makeText(MainActivity.this, "用户名密码不能为空", Toast.LENGTH_SHORT).show(); return; } // 启动Service执行写入操作 Intent intent = new Intent(MainActivity.this, StorageService.class); intent.setAction(StorageConstants.ACTION_WRITE); intent.putExtra(StorageConstants.EXTRA_USERNAME, username); intent.putExtra(StorageConstants.EXTRA_PASSWORD, password); intent.putExtra(StorageConstants.EXTRA_STORAGE_TYPE, currentStorageType); startService(intent); Toast.makeText(MainActivity.this, "写入中...", Toast.LENGTH_SHORT).show(); }); // 读取按钮点击事件 btnRead.setOnClickListener(v -> { // 启动Service执行读取操作 Intent intent = new Intent(MainActivity.this, StorageService.class); intent.setAction(StorageConstants.ACTION_READ); intent.putExtra(StorageConstants.EXTRA_STORAGE_TYPE, currentStorageType); startService(intent); Toast.makeText(MainActivity.this, "读取中...", Toast.LENGTH_SHORT).show(); }); } @Override protected void onDestroy() { super.onDestroy(); // 解绑广播接收器 unregisterReceiver(mReceiver); // 停止Service stopService(new Intent(this, StorageService.class)); } } 6.修改布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="20dp" android:gravity="center_horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="用户信息存储测试" android:textSize="24sp" android:layout_marginBottom="30dp"/> <EditText android:id="@+id/et_username" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="用户名" android:inputType="text" android:layout_marginBottom="15dp"/> <EditText android:id="@+id/et_password" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="密码" android:inputType="textPassword" android:layout_marginBottom="30dp"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="space-between"> <Button android:id="@+id/btn_write" android:layout_width="150dp" android:layout_height="wrap_content" android:text="写入"/> <Button android:id="@+id/btn_read" android:layout_width="150dp" android:layout_height="wrap_content" android:text="读取"/> </LinearLayout> </LinearLayout> 7.修改配置文件表单 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.diodz.base"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Base"> <!-- 注意:Theme.Base要项目实际主题一致,若报错可改为@style/Theme.AppCompat.Light.DarkActionBar --> <!-- 主Activity配置 --> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 后台服务配置 --> <service android:name=".StorageService" android:exported="false" /> </application> </manifest> 重写这段代码
12-25
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值