基本思路
今天来说说数据库方面的东西,在该AudioVideo中,当进入应用的时候,会查询数据库,如果数据库有内容,我们就不全盘扫描,否则,进行全盘扫描,解析音频文件基本信息,生成对应的属于承载bean。然后再通过ORM模型将bean存入数据库.
继承SQLiteOpenHelper
这里是通过继承SQLiteOpenHelper 来管理我们的数据库的,重载我们的构造方法
/**
* Created by yzz
* 2017/4/25 0025.
*/
public class DbManager extends SQLiteOpenHelper {
public DbManager(Context context, String name, int version){
super(context,name,null,version);
}
//这里是在创建数据库后会调用的,可以用来创建表
@Override
public void onCreate(SQLiteDatabase db) {
}
//这里是当version>=当前的verision时会被调用,可以进行数据库标的增删
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//更新
}
}
设计注解和枚举为Bean映射为表做准备
这里,我定义了tableName(表名),isKet(是否是主键),isAutoincrement(是否自动增长),type(DbType.class,类型),length(类型的长度,例如varchar(length))
/**
* Created by yzz
* 2017/4/25 0025.
*/
@Target({ElementType.TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DbAnn {
String tableName()default "";
boolean isKey()default false;
boolean isAutoincrement()default false;
DbType type()default DbType.TEXT;
int length() default -1;
}
定义类型的枚举,限制用户智能使用枚举中的变量,更加方便统一
/**
* Created by yzz
* 2017/4/25 0025.
*/
public enum DbType {
INTEGER,
REAL,
TEXT,
BLOB,
/**
* 16 位元的整数。
*/
SMALLINT,
/**
* 32 位元的整数。
*/
INTERGER,
/**
* (p,s) p 精确值和 s 大小的十进位整数,精确值p是指全部有几个数(digits)大小值,s是指小数点後有几位数。如果没有特别指定,则系统会设为 p=5; s=0 。
*/
DECIMAL,
/**
* 32位元的实数。
*/
FLOAT ,
/**
* 64位元的实数。
*/
DOUBLE,
/**
* n 长度的字串,n不能超过 254
*/
CHAR,
/**
* 长度不固定且其最大长度为 n 的字串,n不能超过 4000。
*/
VARCHAR,
/**
* 和 char(n) 一样,不过其单位是两个字元 double-bytes, n不能超过127。这个形态是为了支援两个字元长度的字体,例如中文字。
*/
GRAPHIC,
/**
* 可变长度且其最大长度为 n 的双字元字串,n不能超过 2000
*/
VARGRAPHIC,
/**
* 包含了 年份、月份、日期。
*/
DATE,
/**
* 包含了 小时、分钟、秒。
*/
TIME,
/**
* 包含了 年、月、日、时、分、秒、千分之一秒。
*/
TIMESTAMP;
}
构建数据库管理工具
利用反射+注解的机制来完成对象关系映射
//数据库名
private String dbName;
//表名
private String tableName;
//上下文的软引用
private SoftReference<Context> contextSoftReference;
//实体bean
private T t;
//实体bean的类类型的对象
private Class<? extends T> tClass;
//数据库操作者(核心)
private SQLiteDatabase database;
//得到数据库操作者的类
private DbManager manager;
构造方法,形参:上下文对象,bean,数据局库的名称
public DbHelper(Context context, T t, String dbName) {
contextSoftReference = new SoftReference<Context>(context);
this.t = t;
this.dbName = dbName;
init();
}
初始化方法,通过反射和注解拿到表名
private void init() {
try {
if (t == null) return;
tClass = (Class<? extends T>) t.getClass();
Field[] fields = tClass.getFields();
int size = fields.length;
//拿到对应的tableName的值
DbAnn dbAnnClass = tClass.getAnnotation(DbAnn.class);
if (dbAnnClass != null) {
tableName = dbAnnClass.tableName();
}
for (int i = 0; i < size; i++) {
Field f = fields[i];
DbAnn dbAnn = f.getAnnotation(DbAnn.class);
if (dbAnn == null) continue;
break;
}
//最后做一下判断
dbName = dbName == null ? "yzz" : dbName;
tableName = tableName == null ? "t_yzz" : tableName;
} catch (Exception e) {
e.printStackTrace();
}
create();
}
创建数据库
/**
* 创建数据库
*/
private void create() {
if (contextSoftReference.get() == null) return;
manager = new DbManager(contextSoftReference.get(), dbName, 1);
database = manager.getWritableDatabase();
StringBuilder sb = new StringBuilder();
sb.append("create table if not exists ")
.append(tableName)
.append(" ( ");
Field[] fields = tClass.getFields();
int size = fields.length;
for (int i = 0; i < size; i++) {
Field f = fields[i];
if (f.getAnnotation(DbAnn.class) == null) continue;
sb.append(getFieldType(f));
sb.append(" , ");
}
String sql = sb.substring(0, sb.length() - 2);
sql += " ) ";
database.execSQL(sql);
}
private String getFieldType(Field field) {
StringBuilder sb = new StringBuilder();
try {
String type = "text";
DbAnn dbAnn = field.getAnnotation(DbAnn.class);
if (dbAnn != null) {
DbType dbType = dbAnn.type();
type = dbType.name();
int len = dbAnn.length();
sb.append(field.getName());
if (len != -1) {
type += "(" + len + ") ";
}
sb.append(" ").append(type);
if (dbAnn.isKey()) {
if (dbAnn.isAutoincrement())
sb.append(" primary key autoincrement ");
else sb.append(" primary key ");
}
return sb.toString();
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
插入,总体思路就是字符串的拼接
public void insert(T t) {
try {
StringBuilder sb = new StringBuilder();
sb.append("insert into ")
.append(tableName)
.append(" ( ");
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
Field[] fields = t.getClass().getFields();
int size = fields.length;
for (int i = 0; i < size; i++) {
Field f = fields[i];
if (f.getAnnotation(DbAnn.class) == null) continue;
if (f.getAnnotation(DbAnn.class).isKey()) continue;
sb1.append(f.getName()).append(" , ");
Object oob = f.get(t);
if (oob == null) continue;
if (oob.getClass().equals(int.class)) {
sb2.append(oob);
} else {
String str = oob.toString().replaceAll("\"","");
sb2.append("\"" + str + "\"").append(" , ");
}
}
sb.append(sb1.substring(0, sb1.length() - 2));
sb.append(" ) ")
.append(" values ")
.append(" ( ")
.append(sb2.substring(0, sb2.length() - 2))
.append(" ) ");
database.execSQL(sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
查找
public Cursor select() {
StringBuilder sb = new StringBuilder();
sb.append("select * from ").append(tableName);
Cursor c = database.rawQuery(sb.toString(), null);
return c;
}
实体bean处理
/**
* Created by yzz
* 2017/4/22 0022.
*/
@DbAnn(tableName = "yzz_music")
public class Musicer implements Parcelable {
@DbAnn(isKey = true, isAutoincrement = true, type = DbType.INTEGER)
public int id;
@DbAnn(type = DbType.VARCHAR, length = 35)
public String path;
@DbAnn(type = DbType.VARCHAR, length = 20)
public String musictitle;
@DbAnn(type = DbType.VARCHAR, length = 20)
public String author = "未知";
@DbAnn(type = DbType.VARCHAR, length = 20)
public String album = "未知";
@DbAnn(type = DbType.VARCHAR, length = 20)
public String year = "未知";
@DbAnn(type = DbType.VARCHAR, length = 20)
public String memo = "未知";
@DbAnn(type = DbType.VARCHAR, length = 20)
public String retain = "未知";
@DbAnn(type = DbType.VARCHAR, length = 20)
public String track = "未知";
@DbAnn(type = DbType.VARCHAR, length = 20)
public String type = "未知";
......
}
使用
//创建
dbHelper = new DbHelper<>(this, new Musicer(), "yzz");
//插入
dbHelper.insert(musics.get(i));
//查找
dbHelper = new DbHelper<>(this, new Musicer(), "yzz");
Cursor c = dbHelper.select();
if (c == null) return;
while (c.moveToNext()) {
Musicer m = new Musicer();
m.setPath(c.getString(c.getColumnIndex("path")));
m.setMusictitle(c.getString(c.getColumnIndex("musictitle")));
m.setAuthor(c.getString(c.getColumnIndex("author")));
m.setAlbum(c.getString(c.getColumnIndex("album")));
m.setYear(c.getString(c.getColumnIndex("year")));
m.setMemo(c.getString(c.getColumnIndex("memo")));
m.setRetain(c.getString(c.getColumnIndex("retain")));
m.setTrack(c.getString(c.getColumnIndex("track")));
m.setType(c.getString(c.getColumnIndex("type")));
musics.add(m);
}
总结
**本次的ORM工具还只有创建,插入和全部查找这三个功能,后面会陆续补充,详情请查看github项目
AudioVideo
**