实现数据库、表的创建,便于扩展。调用层直接一个对象丢过去,即可实现增删改查。
1.数据库增删改查接口
//泛型实现一个对象丢过来实现增删改查
public interface IBaseDao<T>{
Long insert(T entity);
int update(T entity,T where);
int delete(T where);
List<T> query(T where);
List<T> query(T where,String orderBy, Integer startIndex,Integer limit);
List<T> query(String sql);
}
2.注解
因为在对象丢给数据库操作具体类的时候,要找到模型对象对应属性在数据库对应的表、列名。用注解来实现
//1.数据库表名注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DbTableName{
String value();
}
//2.数据库列名注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DbColumnName{
String value();
}
3.工厂模式+单例模式给客户端调用
public class BaseDaoFactory{
//数据库存放路径
private String dataBasePath;
//操作数据库
private SQLiteDatabase sqliteDatabase;
private static BaseDaoFactory instance = new BaseDaoFactory();
private BaseDaoFactory(){
//设定数据库存储路径
dataBasePath =
Environment.getExternalStorageDirectory().getAbsolutePath()
+"/teacher.db";
//创建数据库
openDatabase();
}
public BaseDaoFactory getInstance(){
return instance;
}
//创建了数据库
private void openDatabase(){
this.sqliteDatabase =
SQLiteDatabase.openOrCreateDatabase(dataBasePath,null);
}
//暴露给客户端的方法用于获取Database
public synchronized <T extends BaseDao<M>,M>
T
getDataHelper(Class<T> clazz,Class<M> entity){
BaseDao baseDao = null;
try{
//反射new实例,每次调用都产生一个实例
//就算以前调用过得也初始化
//这里的代码不够优雅
baseDao = clazz.newInstance();
//初始化basedao
baseDao.init(entity,sqlitDatabase);
}catch(Exception e){e.printStackTrace();}
return (T)baseDao;
}
}
4.抽象的BaseDao类+模板方法具体的创建表交给子类去实现
public abstract class BaseDao<T> implements IBaseDao<T>{
//创建表交给子类去实现
public abstract String createTable();
//操作数据库的具体工具类
protected SQLiteDatabase database;
//操作的具体对象
private Class<T> entity;
//初始化标志符
private boolean isInit = false;
//表名
private String tableName;
//表列名与对象属性名映射表
prvate Map<String,String> cacheMap;
protected synchronized boolean init (Class<T> entity,
SQLiteDatabase sqliteDatabase){
if(!isInit){
this.database = sqliteDatabase;
this.entity = entity;
if(entity.getAnnotation(DbTableName.class)==null){
tableName = entity.getClass.getSimpleName;
}else{
tableName = entity.getAnnotation(DbTableName.class).value();
}
if(!sqliteDatabase.isOpen()){
return false;
}
if(!TextUtils.isEmpty(createTable())){
database.execSQL(createTable());
}
cacheMap = new HashMap<>();
initCacheMap();
isInit = true;
}
return isInit;
}
//初始化映射关系
private void initCacheMap(){
//1.查询表的各个列名
String sql = "select * from "+this.tableName+" limit 1 , 0";
Cursor cursor = null;
try{
cursor = database.rawQuery(sql,null);
//数据表的各个列数据
String[] columnNames = cursor.getColumnNames();
//2.获取操作对象的Filed数组
Field[] columnFields = entity.getFields();
for(Field field : columnFields){
//防止私有变量,所以这么操作
field.setAccessible(true);
}
//3.循环遍历获取到的表列名,查看与类对应属性的标注名是否一致
for(String columnName : columnNames){
Field mField = null;
for(Filed field : columnFields){
String fieldName = null;
if(field.getAnnotation(DbColumnName.class)!=null){
fieldName = field.getAnnotation(DbColumnName.class).value();
}else{
fieldName = field.getName();
}
if(columnName.equals(fieldName)){
mField = field;
break;//结束内循环,执行内循环外代码
}
}
if(mField!=null){
cacheMap.put(colmunName,mField);
}
}
}catch(Exception e){e.printStackTrace();}
finally{cursor.close();}
}
//增操作
@Override
public Long insert(T entity){
//1.根据entity获取 数据库列名和对应的值
Map<String,String> map = getValues(entity);
//2.得到的map转换成ContentValues
ContentValues values=getContentValues(map);
//3.进行新增操作
Long result =database.insert(tableName,null,values);
return result;
}
//根据传入的entity得到表列名与对应值的关系
private Map<String,String> getValues(T entity){
HashMap<String,String> result = new HashMap<>();
Iterator<Field> iterator = cacheMap.values().iterator();
while(iterator.hasNext()){
Field field = iterator.next();
String key = null;
String value = null;
if(field.getAnnotation(DbColumnName.class)!=null){
key = field.getAnnotation(DbColumnName.class).value();
}else{
key = field.getName();
}
try{
if(null==field.get(entity)){continue;}
value = field.get(entity).toString();
}catch(Exception e){e.printStackTrace();}
result.put(key,value);
}
return result;
}
//根据表列名与值的map得到可以插入的ContentValue
private ContentValues getContentValues(Map<String,String> map){
ContentValues contentValues = new ContentValues();
Set keys = map.keySet();
Iterator<String> iterator = key.iterator();
while (iterator.hasNext()){
String key = iterator.next();
String value = map.get(key);
if(value!=null){
contentValues.put(key,value);
}
}
return contentValues;
}
//删除操作
@Override
public int delete(T where){
Map map = getValues(where);
Condition condition = new Condition(map);
int result = database.delete(tableName,condition.getWhereClause(),
condition.getWhereArgs());
return result;
}
//Condition内部类,用户根据entity
class Condition{
private String whereClause;
private String[] whereArgs;
public Condition(Map<String ,String> where) {
ArrayList list=new ArrayList();
StringBuilder stringBuilder=new StringBuilder();
stringBuilder.append(" 1=1 ");
Set keys=where.keySet();
Iterator iterator=keys.iterator();
while (iterator.hasNext()){
String key= (String) iterator.next();
String value=where.get(key);
if (value!=null){
stringBuilder.append(" and "+key+" =?");
list.add(value);
}
}
this.whereClause=stringBuilder.toString();
this.whereArgs= (String[]) list.toArray(new String[list.size()]);
}
public String[] getWhereArgs() {
return whereArgs;
}
public String getWhereClause() {
return whereClause;
}
}
//更新操作
@Override
public int update(T entity, T where) {
int reslut=-1;
//更新列与值映射表
Map values=getValues(entity);
//原始的列与值映射表
Map whereClause=getValues(where);
Condition condition=new Condition(whereClause);
//更新后的值
ContentValues contentValues=getContentValues(values);
reslut=database.update(tableName,
contentValues,condition.getWhereClause(),
condition.getWhereArgs());
return reslut;
}
//查询操作
@Override
public List<T> query(T where){
return query(where,null,null,null);
}
@Override
public List<T> query(T where,String orderBy,
Integer startIndex,Integer limit){
Map map = getValues(where);
String limitString=null;
if(startIndex!=null&&limit!=null){
limitString=startIndex+" , "+limit;
}
Condition condition=new Condition(map);
Cursor cursor=database.query(tableName,null,
condition.getWhereClause(),
condition.getWhereArgs(),null,null,orderBy,limitString);
List<T> result=getResult(cursor,where);
cursor.close();
return result;
}
//Cursor转换成T
private List<T> getResult(Cursor cursor, T where) {
ArrayList list=new ArrayList();
Object item;
while (cursor.moveToNext()) {
try {
item=where.getClass().newInstance();
Iterator iterator=cacheMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry= (Map.Entry) iterator.next();
String colomunName= (String) entry.getKey();
Integer colmunIndex=cursor.getColumnIndex(colomunName);
Field field= (Field) entry.getValue();
Class type=field.getType();
if(colmunIndex!=-1){
if(type==String.class){
//反射方式赋值
field.set(item,cursor.getString(colmunIndex));
}else if(type==Double.class){
field.set(item,cursor.getDouble(colmunIndex));
}else if(type==Integer.class){
field.set(item,cursor.getInt(colmunIndex));
}else if(type==Long.class){
field.set(item,cursor.getLong(colmunIndex));
}else if(type==byte[].class){
field.set(item,cursor.getBlob(colmunIndex));
}else {
continue;
}
}
}
list.add(item);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return list;
}
}
5.调用层的使用
//1.实例类
@DbTableName("tb_user")
public class User{
public int user_id;
@DbColumnName("name")
public String name;
@DbColumnName("password")
public String password
}
//2.具体的DaseDao
public class UserDao extents BaseDao{
@Override
protected String createTable() {
return "create table if not exists tb_user(user_Id int,name"+
" varchar(20),password varchar(10))";
}
@Override
public List query(String sql) {
return null;
}
}
//3.具体操作 通过baseDao操作
baseDao= BaseDaoFactory.getInstance().getDataHelper(UserDao.class,
User.class);
网友评论