前言
相信不少开发者跟我一样,每次都很烦恼自己写数据库,而且那些数据库语句也经常记不住。当然网上也有很多很好的数据库框架,你可以直接拿来用,但是 很多时候我们的项目,特别是一个小型的Andrond应用原本用到的数据库结构比较简单,没必要去用那些有点臃肿的框架。当然,即使你用那些框架,当你遇到问题时,你是否也得去修改它?你要修改别人的框架必须的读懂他人的设计代码。所以不管从那个角度出发,你都得掌握简单的数据库操作。那么这篇博客就从简单的数据库操作来学习Android数据库相关知识点,然后一步一步去搭建自己的简单型数据库框架,以后就再也不用担心害怕去写数据库了,直接拿自己的数据库框架用就好了。
框架功能
public long insert(Object obj);插入数据
public List findAll(Class clazz);查询所有数据
public List findByArgs(Class clazz, String select, String[] selectArgs) ;根据指定条件查询满足条件数据
public T findById(Class clazz, int id);根据id查询一条记录
public void deleteById(Class
创建数据库
Android系统中已经集成了Sqlite数据库,我们直接使用它就好了,同时Android系统提供了一个数据库帮助类SQLiteOpenHelper,该类是一个抽象类,所以得写一个类来继承它实现里面的方法。代码如下:
MySQLiteHelper类
publicclassMySQLiteHelperextendsSQLiteOpenHelper {publicMySQLiteHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); } @OverridepublicvoidonCreate(SQLiteDatabase db) { } @OverridepublicvoidonUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
当数据库创建时系统会调用其中的 onCreate方法,那么我们就可以来实现 onCreate 方法来创建数据库表。假设我们要创建一张 Person表,表中有 id,name,age,flag字段。那么代码如下:
publicclassMySQLiteHelperextendsSQLiteOpenHelper {publicstaticfinal String CREATE_TABLE = "create table Person (" + "id integer primary key autoincrement, " + "name text, " + "age integer, " + "flag boolean)"; publicMySQLiteHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); } @OverridepublicvoidonCreate(SQLiteDatabase db) { db.execSQL(CREATE_TABLE); } ...}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
由此我们的数据库帮助类就完成了,接下来是这么使用的:
privatestaticfinal String DB_NAME = "demo.db"; privatestaticfinalint DB_VERSION = 1; publicvoidoepnDB(){ MySQLiteHelper helper = new MySQLiteHelper(context, DB_NAME, null, DB_VERSION); SQLiteDatabase db = helper.getWritableDatabase(); }
1
2
3
4
5
6
7
有以上代码就已经完成了一个数据库创建以及一张表的创建,是不不是感觉不是很难呢?这么看起来的确不是很难,但是我的也不得不每次去继承SQLiteOpenHelper类来实现里面的方法。关键是每次都要去写创建表语句
public static final String CREATE_TABLE = "createtable Person (" + "id integerprimarykey autoincrement, " + "name text, " + "age integer, " + "flag boolean)";
1
2
3
4
5
这里表的字段只有4个,如果有一天你遇到表里的字段有10列怎么办?还继续按照上面的方法写创建表语句么?你就不嫌繁琐么?而且容易粗错。那么有没有超级简单的方法一步完成表语句的创建呢?你细想:存放在数据库中表的这些字段无非就是一个Person类中的所有成员变量,这么一来是否可以只通过Person类型直接创建表语句呢?答案是肯定的。我们通过java 的反射机制来一步一劳永逸的实现建表操作。代码如下:
/** * 得到建表语句 * * @param clazz 指定类 * @return sql语句 */private String getCreateTableSql(Class<?> clazz) { StringBuilder sb = new StringBuilder(); //将类名作为表名 String tabName = Utils.getTableName(clazz); sb.append("create table ").append(tabName).append(" (id INTEGER PRIMARY KEY AUTOINCREMENT, "); //得到类中所有属性对象数组 Field[] fields = clazz.getDeclaredFields(); for (Field fd : fields) { String fieldName = fd.getName(); String fieldType = fd.getType().getName(); if (fieldName.equalsIgnoreCase("_id") || fieldName.equalsIgnoreCase("id")) { continue; } else { sb.append(fieldName).append(Utils.getColumnType(fieldType)).append(", "); } } int len = sb.length(); sb.replace(len - 2, len, ")"); Log.d(TAG, "the result is " + sb.toString()); return sb.toString(); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
工具类代码如下:
package com.xjp.databasedemo;import android.text.TextUtils;import java.util.Locale;/** * Created by xjp on 2016/1/23. */publicclass DBUtils { //得到每一列字段的数据类型publicstatic String getColumnType(String type) { String value = null; if (type.contains("String")) { value = " text "; } elseif (type.contains("int")) { value = " integer "; } elseif (type.contains("boolean")) { value = " boolean "; } elseif (type.contains("float")) { value = " float "; } elseif (type.contains("double")) { value = " double "; } elseif (type.contains("char")) { value = " varchar "; } elseif (type.contains("long")) { value = " long "; } returnvalue; } //得到表名publicstatic String getTableName(Class<?> clazz){ return clazz.getSimpleName(); } publicstatic String capitalize(String string) { if (!TextUtils.isEmpty(string)) { returnstring.substring(0,