数据库,记录存储本地数据,必不可少。基本操作增删改查。
接下来介绍一下最基本的数据库操作方法,基本可由这个逻辑举一反三。
有数据库,就有数据表;表上就有列项,实体类就是存储数据到数据表、或从数据库查询数据的中间存储器。就像是去银行取了钱,用钱包装起来,用的时候再从钱包里拿出来。
我们建立一个名为Person的实体类,记录人名、时间、消息。类似一种聊天记录的存储方式。
/**
* 实体类
* @author dlong
* created at 2019/3/13 10:29 AM
*/
public class Person {
/** 数据库自增ID */
public int id;
/** 用户名 */
public String name;
/** 发送时间 */
public long time;
/** 发送消息 */
public String msg;
public Person(){
}
public Person(String n,long t,String m){
name = n;
time = t;
msg = m;
}
/**
* 拼接字符串
* @return
*/
@NonNull
@Override
public String toString() {
StringBuilder builder = new StringBuilder("[");
builder.append(id).append("--");
builder.append(name).append("--");
// 将时间戳转换成特定格式的字符串
Date date = new Date(time);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
builder.append(format.format(date)).append("--");
builder.append(msg).append("]");
return builder.toString();
}
}
数据表的操作,如果每次都要手动写一次操作语句也太麻烦了,所以集中在操作帮助类里处理,其他地方调用这里的方法就好了。
/**
* 数据库操作类
* @author dlong
* created at 2019/3/13 10:33 AM
*/
public class DBDao {
/** 数据库名称 */
private static final String DB_NAME = "per.db";
/** 数据表名称 */
private static final String TABLE_NAME = "person_info";
/** 数据库版本 */
private static final int DB_VERSION = 1;
/** 表的字段名 */
private static String KEY_ID = "id";
private static String KEY_NAME = "name";
private static String KEY_TIME = "time";
private static String KEY_MSG = "msg";
private SQLiteDatabase mDatabase;
private Context mContext;
/** 数据库打开帮助类 */
private DBOpenHelper mDbOpenHelper;
public DBDao(Context context) {
mContext = context;
}
/**
* 打开数据库
*/
public void openDataBase() {
mDbOpenHelper = new DBOpenHelper(mContext, DB_NAME, null, DB_VERSION);
try {
mDatabase = mDbOpenHelper.getWritableDatabase();//获取可写数据库
} catch (SQLException e) {
mDatabase = mDbOpenHelper.getReadableDatabase();//获取只读数据库
}
}
/**
* 关闭数据库
*/
public void closeDataBase() {
if (mDatabase != null) {
mDatabase.close();
}
}
/**
* 插入一条数据
* @param per
* @return
*/
public long insertData(Person per) {
ContentValues values = new ContentValues();
values.put(KEY_NAME, per.name);
values.put(KEY_TIME, per.time);
values.put(KEY_MSG, per.msg);
return mDatabase.insert(TABLE_NAME, null, values);
}
/**
* 删除一条数据
* @param id
* @return
*/
public long deleteData(long id) {
return mDatabase.delete(TABLE_NAME, KEY_ID + "=" + id, null);
}
/**
* 删除所有数据
* @return
*/
public long deleteAllData() {
return mDatabase.delete(TABLE_NAME, null, null);
}
/**
* 更新一条数据
* @param id
* @param per
* @return
*/
public long updateData(long id, Person per) {
ContentValues values = new ContentValues();
values.put(KEY_NAME, per.name);
values.put(KEY_TIME, per.time);
values.put(KEY_MSG, per.msg);
return mDatabase.update(TABLE_NAME, values, KEY_ID + "=" + id, null);
}
/**
* 查询一条数据
* @param id
* @return
*/
public List<Person> queryData(long id) {
Cursor results = mDatabase.query(TABLE_NAME, new String[]{KEY_ID,
KEY_NAME,
KEY_TIME,
KEY_MSG},
KEY_ID + "=" + id, null, null, null, null);
return convertUtil(results);
}
/**
* 查询所有数据
* @return
*/
public List<Person> queryDataList() {
Cursor results = mDatabase.query(TABLE_NAME, new String[]{KEY_ID,
KEY_NAME,
KEY_TIME,
KEY_MSG},
null, null, null, null, null);
return convertUtil(results);
}
/**
* 转换工具
* @param cursor
* @return
*/
private List<Person> convertUtil(Cursor cursor) {
int resultCounts = cursor.getCount();
if (resultCounts == 0 || !cursor.moveToFirst()) {
return null;
}
List<Person> mList = new ArrayList<>();
for (int i = 0; i < resultCounts; i++) {
Person per = new Person();
per.id = (cursor.getInt(0));
per.name = (cursor.getString(cursor.getColumnIndex(KEY_NAME)));
per.time = (cursor.getLong(cursor.getColumnIndex(KEY_TIME)));
per.msg = (cursor.getString(cursor.getColumnIndex(KEY_MSG)));
mList.add(per);
cursor.moveToNext();
}
return mList;
}
/**
* 数据表打开帮助类
*/
private static class DBOpenHelper extends SQLiteOpenHelper {
public DBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
final String sqlStr = "create table if not exists " + TABLE_NAME + " (" +
KEY_ID + " integer primary key autoincrement, " +
KEY_NAME + " text not null, " +
KEY_TIME + " integer, " +
KEY_MSG + " text );";
db.execSQL(sqlStr);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
final String sqlStr = "DROP TABLE IF EXISTS " + TABLE_NAME;
db.execSQL(sqlStr);
onCreate(db);
}
}
}
这里头有个比较可能出错的点,就是数据库初次建立的时候的onCreate()方法
@Override
public void onCreate(SQLiteDatabase db) {
final String sqlStr = "create table if not exists " + TABLE_NAME + " (" +
KEY_ID + " integer primary key autoincrement, " +
KEY_NAME + " text not null, " +
KEY_TIME + " integer, " +
KEY_MSG + " text );";
db.execSQL(sqlStr);
}
关键在于下图的红色圈位置,一定要有空格隔开,不然字符串就从 “create table if not exists name”
变成了 “create table if not existsname” ,这样子是无法成功建表的。
另外,在数据库更新的时候,也不能直接参照我这里的方法,我这里是直接删了原来的表,重新建立。要根据实际项目需求来做,不然,就这样删了之前的数据,亏成马都不知道。
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
final String sqlStr = "DROP TABLE IF EXISTS " + TABLE_NAME;
db.execSQL(sqlStr);
onCreate(db);
}
demo:DataBaseTest