通用数据库

来源:互联网 发布:淘宝买家4钻很厉害吗 编辑:程序博客网 时间:2024/05/19 13:27

数据库的使用流程:

①在dao包中建立数据库的帮助类,在帮助类中建表

public class DBHelper extends SQLiteOpenHelper {private static final String NAME = "uc.db";private static final int START_VERSION = 1;private static final int HISTORY_VERSION = 2;private static final int CURRENT_VERSION = 3;// 新闻表:主键 + 标题 + 摘要public static final String TABLE_ID = "_id";public static final String TABLE_NEWS_NAME = "news";// 新闻表名public static final String TABLE_NEWS_TITLE = "title";// 新闻标题public static final String TABLES_NEWS_SUMMARY = "summary";// 新闻摘要public DBHelper(Context context) {super(context, NAME, null, CURRENT_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) {// 建表String sql = "create table" + TABLE_NEWS_NAME + "(" + TABLE_ID+ "integer primary key autoincrement," + TABLE_NEWS_TITLE+ "varchar(50)," + TABLES_NEWS_SUMMARY + "varchar(200))";db.execSQL(sql);onUpgrade(db, START_VERSION, CURRENT_VERSION);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 更新// 数据库版本管理switch (oldVersion) {case START_VERSION:// 从1.0版本升级到3.0版本String sql = "create table" + "book" + "(" + TABLE_ID+ "integer primary key autoincrement," + TABLE_NEWS_TITLE+ "varchar(50)," + TABLES_NEWS_SUMMARY + "varchar(200))";db.execSQL(sql);case HISTORY_VERSION:// 从2.0版本升级到3.0版本sql = "create table" + "class" + "(" + TABLE_ID+ "integer primary key autoincrement," + TABLE_NEWS_TITLE+ "varchar(50)," + TABLES_NEWS_SUMMARY + "varchar(200))";db.execSQL(sql);case CURRENT_VERSION:// 更新表、删除表等case 4:// 更新表、删除表等case 5:// 更新表、删除表等break;}}}

②在domain包中建数据库保存信息的业务bean(实体)

改进:在②的基础上,在dao.annotation包中增加注解,以便在程序运行时获得表名,主键和字段。

/** * 指定了实体与数据库中表的对应关系 * @author HP1 * */@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface TableName {/** * 数据库中表名 * @return */String value();}

/** * 标识主键 * @author HP1 * */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface ID {/** * 主键是否自增 * @return */boolean autoincrment();}

/** * 指定了实体的字段与数据库中表中列的对应关系 * @author HP1 * */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface Column {/** * 数据库中列名 * @return */String value();}

/** * 新闻的业务bean * @author HP1 * */@TableName(DBHelper.TABLE_NEWS_NAME)public class News {@ID(autoincrment=true)@Column(DBHelper.TABLE_ID)private int id;@Column(DBHelper.TABLE_NEWS_TITLE)private String title;@Column(DBHelper.TABLES_NEWS_SUMMARY)private String summary;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getSummary() {return summary;}public void setSummary(String summary) {this.summary = summary;}}
③在dao包中建操作表中信息的接口,在接口中添加需要实现的方法

改进:把增删改查方法提取到dao.base包中的DAO接口中,③所建的接口继承自DAO接口。

/** * 实体操作的通用接口 * @author HP1 * */public interface DAO<M> {/** * 增加 * @param m * @return */long insert(M m);/** * 删除 * @param id * @return */int delete(Serializable id);// int long String/** * 修改 * @param m * @return */int update(M m);/** * 查询 * @return */List<M> findAll();}

/** * 新闻表操作的接口 * @author HP1 * */public interface NewsDao extends DAO<News> {/*long insert(News news);int delete(int id);int update(News news);List<News> findAll();*/// 特有信息}
④在dao.impl包中建表中信息的实现类,该类实现了③中所建的接口

改进:把公共部分提取到dao.base包中的DAOSupport类中,该类实现了DAO接口,④中的类继承DAOSupport类。

public abstract class DAOSupport<M> implements DAO<M>{protected Context context;protected DBHelper helper;protected SQLiteDatabase db;public DAOSupport(Context context) {super();this.context = context;helper = new DBHelper(context);db = helper.getWritableDatabase();}@Overridepublic long insert(M m) {ContentValues values = new ContentValues();fillColumn(m,values);return db.insert(getTableName(), null, values );}@Overridepublic int delete(Serializable id) {return db.delete(getTableName(), DBHelper.TABLE_ID+" = ?", new String[]{id.toString()});}@Overridepublic int update(M m) {ContentValues values = new ContentValues();fillColumn(m, values);return db.update(getTableName(), values, DBHelper.TABLE_ID+" = ?", new String[]{getID(m)});}/** * 条件查询 * @param columns * @param selection * @param selectionArgs * @param groupBy * @param having * @param orderBy * @return */public List<M> findByCondition( String[] columns, String selection,            String[] selectionArgs, String groupBy, String having,            String orderBy){List<M> result = null;Cursor cursor = db.query(getTableName(), columns, selection, selectionArgs, groupBy, having, orderBy);if(cursor != null){result = new ArrayList<M>();while(cursor.moveToNext()){M m = getInstance();fillField(cursor,m);result.add(m);}cursor.close();}return result;}@Overridepublic List<M> findAll() {List<M> result = null;Cursor cursor = db.query(getTableName(), null, null, null, null, null, null);if(cursor != null){result = new ArrayList<M>();while(cursor.moveToNext()){M m = getInstance();fillField(cursor,m);result.add(m);}cursor.close();}return result;}/** * 问题一:表名的获取 * @return */private String getTableName(){// 每个表对应一个具体实体// 方案一:如果能够获取到实体,获取到实体的简单名称,首字母小写// 方案二:利用注解,实体和数据库表的名称脱离关系// 获取到实体--问题五M m = getInstance();// 获取实体的注解,依据value里设置的值确定操作的数据库表// 如果需要在运行的时候获取到注解的信息,需要在注解的头上设置存活时间TableName tableName = m.getClass().getAnnotation(TableName.class);// annotationType:注解的类型if(tableName != null){return tableName.value();}return "";}/** * 问题二:如何将实体中的数据,按照对应关系导入到数据库表中 * @param m 数据源 * @param values 导入目标 */private void fillColumn(M m, ContentValues values) {/*values.put(DBHelper.TABLE_NEWS_TITLE, news.getTitle());// 此处省略n行代码。。。 *  */Field[] fields = m.getClass().getDeclaredFields();for(Field item:fields){item.setAccessible(true);Column column = item.getClass().getAnnotation(Column.class);if(column != null){String key = column.value();try {String value = item.get(m).toString();// 如果该field是主键,并且是自增的,不能添加到集合ID id = item.getAnnotation(ID.class);if(id != null && id.autoincrment()){// 不添加}else{values.put(key, value);}} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}}/** * 问题三:如何将数据库表中列的数据,按照对应关系导入到实体中 * @param cursor 数据源 * @param m 导入目标 */private void fillField(Cursor cursor, M m) {/* * int columnIndex = cursor.getColumnIndex(DBHelper.TABLE_NEWS_TITLE);String title = cursor.getString(columnIndex);m.setTitle(title);// 此处省略n行代码 *  */Field[] fields = m.getClass().getDeclaredFields();for(Field item:fields){item.setAccessible(true);Column column = item.getClass().getAnnotation(Column.class);if(column != null){int columnIndex = cursor.getColumnIndex(column.value());String value = cursor.getString(columnIndex);try {if(item.getType() == int.class){item.set(m, Integer.parseInt(value));}else if(item.getType() == Data.class){// 把字符串转成时间再设置}else{item.set(m, value);}} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}}/** * 问题四:明确实体中主键,获取到主键中封装的值 * @param m * @return */private String getID(M m) {Field[] fields = m.getClass().getDeclaredFields();for(Field item:fields){item.setAccessible(true);ID id = item.getClass().getAnnotation(ID.class);if(id != null){try {return item.get(m).toString();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}return null;}/** * 问题五:实体的对象创建 * @return */private M getInstance(){// 实体是何时确定的// NewsDaoImpl extends DAOSupport<News>// ①哪个孩子调用的该方法----哪个孩子在运行// 返回此 Object 的运行时类Class clazz = getClass();// ②获取该孩子的父类(支持泛型的父类)Type superclass = clazz.getGenericSuperclass();// ③获取到泛型中的参数// 所有的泛型都实现了(参数化的类型)接口,规定了泛型的通用操作if(superclass != null && superclass instanceof ParameterizedType){Type[] arguments = ((ParameterizedType)superclass).getActualTypeArguments();try {return (M) ((Class)arguments[0]).newInstance();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}return null;}}

public class NewsDaoImpl extends DAOSupport<News> implements NewsDao {public NewsDaoImpl(Context context) {super(context);}}

通用数据库需要解决的问题:

问题一:表名的获取(insert,delete,update,find)

方案一:如果能够获取到实体,获取到实体的简单名称,首字母小写

方案二:利用注解,实体和数据库表的名称脱离关系。


问题二:如何将实体中的数据,按照对应关系导入到数据库表中(insert,update)


问题三:如何将数据库表中列的数据,按照对应关系导入到实体中(find)


问题四:明确实体中主键,获取到主键中封装的值(update)


问题五:实体的对象创建(find)

0 0
原创粉丝点击