android--数据库简介
Android平台提供给我们一个数据库辅助类来创建或打开数据库,这个辅助类就是SQLiteOpenHelper类。但是这个类是一个抽象类,不能直接拿来用,需要我们
写一个具体的类来实现它。在该类的 构造器中,调用Context中的方法创建并打开一个指定名称的数据库对象。继承和扩展SQLiteOpenHelper类主要做的工作就是重写以下两个 方法。
onCreate(SQLiteDatabase db) : 当数据库被首次创建时执行该方法,一般将创建表等初始化操作在该方法中执行。
onUpgrade(SQLiteDatabse dv, int oldVersion,int new Version):当打开数据库时传入的版本号与当前的版本号不同时会调用该方法。
另外,对于数据库的一些常量,比如建表语句以及数据库名称、表名称,我们最好用一个类将它们写在一起。
如下是一个常量类:
package com.my.database; import java.util.ArrayList; public class TableDefine { /** * 数据库名 */ public static final String DB_NAME = "db_my_app"; /** * 数据库版本 */ public static final int DB_VERSION = 1; /** * 用户表 */ public static final String T_USER_NAME = "mUser"; public static final String COLUMN_ID = "user_id"; public static final String COLUMN_Name = "user_name"; public static final String COLUMN_PWD = "pwd"; public static final String COLUMN_EMAIL = "email"; /** * 创建用户表的语句 */ public static final String CREATE_TABLE_USER = new StringBuffer() .append("Create table ") .append(T_USER_NAME) .append(" (") .append(TableDefine.COLUMN_ID) .append(" integer primary key,") .append(COLUMN_Name) .append(" text not null,") .append(COLUMN_PWD) .append(" text not null,") .append(COLUMN_EMAIL) .append(" text not null)") .toString(); /** * 返回建表语句 * * @return */ public static ArrayList<String> getCreateTableSql() { ArrayList<String> list = new ArrayList<String>(); list.add(CREATE_TABLE_USER); return list; } }
package com.my.database; import java.util.ArrayList; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteDatabase.CursorFactory; public class MySQLiteHelper extends SQLiteOpenHelper { private final ArrayList<String> createTableSql; public MySQLiteHelper(Context context, String dbname, CursorFactory factory, int version, ArrayList<String> createTableSql) { super(context, dbname, factory, version); this.createTableSql = createTableSql; } @Override public void onCreate(SQLiteDatabase db) { if (createTableSql != null && createTableSql.size() > 0) { for (String sql : createTableSql) { db.execSQL(sql); } } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
最后是一个CRUD的使用类:
package com.my.database; import java.util.ArrayList; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.my.database.entity.User; public class DBUtils { private MySQLiteHelper dbManager; private SQLiteDatabase dbInstence; public DBUtils (Context context) { if(dbManager == null) dbManager = new MySQLiteHelper(context, TableDefine.DB_NAME, null, TableDefine.DB_VERSION, TableDefine.getCreateTableSql()); if(dbInstence == null) dbInstence = dbManager.getWritableDatabase(); } /** * 向表插入数据 * * @param tableName * 表名称 * @param values * 字段值 */ public void insert(String tableName, ContentValues values) { dbInstence.insert(tableName, null, values); } /** * 更新数据 * * @param tableName * 表名称 * @param values * 字段值 * @param whereClause * @param whereArgs */ public void update(String tableName, ContentValues values, String whereClause, String[] whereArgs) { dbInstence.update(tableName, values, whereClause, whereArgs); } /** * 删除数据 * * @param tableName * 表名称 * @param whereClause 表字段 * @param whereArgs 表字段值 */ public void delete(String tableName, String whereClause, String[] whereArgs) { dbInstence.delete(tableName, whereClause, whereArgs); } /** * 查询数据 * * @param sql * SQL语句,参数用?占位 * @param selectionArgs * 参数?的值数组 * @return Cursor 游标,注意,和JDBC的ResultSet一样,是在线数据集,所以处理完之前,不能调用close() */ public Cursor query(String sql, String[] selectionArgs) { return dbInstence.rawQuery(sql, selectionArgs); } public ArrayList<User> getUserList(){ String sql = "select * from " + TableDefine.T_USER_NAME; return getUserList(sql ,null); } /** * query user list * @param context * @param sql * @param args * @return */ public ArrayList<User> getUserList(String sql, String[] args) { ArrayList<User> userList = new ArrayList<User>(); Cursor cursor = dbInstence.rawQuery(sql, args); while (cursor.moveToNext()) { User user = new User(); user.setUserId(cursor.getInt(0)); user.setUserName(cursor.getString(1)); user.setPwd(cursor.getString(2)); user.setEmail(cursor.getString(3)); userList.add(user); } // 注意游标必须要关闭,否则多查询几次就会出现异常 if (!cursor.isClosed()) { cursor.close(); } return userList; } public void close() { dbManager.close(); } }
有了这个类,我们就完成了数据库的操作了。
来看看一个具体的使用例子:
下图是2个页面,一个是显示页,就是查询数据库里的user,另外的一个添加user的页面:
显示页面的实现:在显示页,我们直接调用数据库,查询出user的list
package com.my; import java.util.ArrayList; import com.my.database.DBUtils; import com.my.database.entity.User; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; public class Ext10databaseActivity extends Activity { private LinearLayout view; private Button addBtn; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); view = (LinearLayout) findViewById(R.id.view); addBtn = (Button) findViewById(R.id.add_btn); DBUtils db = new DBUtils(getApplicationContext()); ArrayList<User> list = db.getUserList(); db.close(); if(list != null && list.size() > 0) { for(User user : list){ TextView text = new TextView(this); text.setText(user.getUserId() + user.getUserName() + user.getPwd() + user.getEmail()); view.addView(text); } } addBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Ext10databaseActivity.this, AddUserActivity.class); startActivity(intent); } }); } }
package com.my; import android.app.Activity; import android.content.ContentValues; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import com.my.database.DBUtils; import com.my.database.TableDefine; public class AddUserActivity extends Activity { private EditText idText; private EditText nameText; private EditText pwdText; private EditText emailText; private Button saveBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.add); idText = (EditText) findViewById(R.id.id_text); nameText = (EditText) findViewById(R.id.name_text); pwdText = (EditText) findViewById(R.id.pwd_text); emailText = (EditText) findViewById(R.id.email_text); saveBtn = (Button) findViewById(R.id.save_btn); saveBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { DBUtils db = new DBUtils(getApplicationContext()); ContentValues values = new ContentValues(); values.put(TableDefine.COLUMN_ID, idText.getText().toString()); values.put(TableDefine.COLUMN_Name, nameText.getText().toString()); values.put(TableDefine.COLUMN_PWD, pwdText.getText().toString()); values.put(TableDefine.COLUMN_EMAIL, emailText.getText().toString()); db.insert(TableDefine.T_USER_NAME, values); db.close(); Intent intent = new Intent(AddUserActivity.this, Ext10databaseActivity.class); startActivity(intent); } }); } }
注:数据库使用完毕后必须要close.