学习笔记-泛型的使用:通用数据库增删改查
2015-06-01 00:26
267 查看
利用泛型,得到一个通用的数据库工具类,进行增删改查
要解决的问题:
* 1.表名的获取
* 2.将实体的数据按照对应关系导入到数据库表中
* 3.将数据表中列的数据按照对应关系导入到实体中
* 4.明确实体中的主键,获取到主键中封装的值
* 5.实体的对象创建
用到的三个注解类:主键、表名和列项
举例:某新闻数据
数据库建立:
bean:
如此一来,数据库操作的实现只用:
要解决的问题:
* 1.表名的获取
* 2.将实体的数据按照对应关系导入到数据库表中
* 3.将数据表中列的数据按照对应关系导入到实体中
* 4.明确实体中的主键,获取到主键中封装的值
* 5.实体的对象创建
/** * 实体操作的通用接口 * @author lenov0 * */ public interface Dao<M> { long insert(M m); int delete(Serializable id); //可实现int long String int update(M m); List<M> findAll(); }
//实现上面的接口
public abstract class DaoSupport<M> implements Dao<M>{ <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>protected Context context; <span style="white-space:pre"> </span>protected DBHelper helper; <span style="white-space:pre"> </span>protected SQLiteDatabase db; <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>public DaoSupport(Context context) { <span style="white-space:pre"> </span>super(); <span style="white-space:pre"> </span>this.context = context; <span style="white-space:pre"> </span>helper = new DBHelper(context); <span style="white-space:pre"> </span>db = helper.getWritableDatabase(); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * 增 <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span>public long insert(M m) { <span style="white-space:pre"> </span>ContentValues values = new ContentValues(); <span style="white-space:pre"> </span>fillColumn(m, values); <span style="white-space:pre"> </span>return db.insert(getTableName(), null, values); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * 删 <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span>public int delete(Serializable id) { <span style="white-space:pre"> </span>return db.delete(getTableName(), DBHelper.TABLE_ID + "=?", new String[]{id+""}); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * 改 <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span>public int update(M m) { <span style="white-space:pre"> </span>ContentValues values = new ContentValues(); <span style="white-space:pre"> </span>fillColumn(m, values); <span style="white-space:pre"> </span>return db.update(getTableName(), values, DBHelper.TABLE_ID + "=?", new String[]{getId(m)}); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * 查 <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span>public List<M> findAll() { <span style="white-space:pre"> </span>List<M> result = null; <span style="white-space:pre"> </span>Cursor cursor = db.query(DBHelper.TABLE_NEWS_NAME, null, null, null, null, null, null); <span style="white-space:pre"> </span>if(cursor != null) { <span style="white-space:pre"> </span>result = new ArrayList<M>(); <span style="white-space:pre"> </span>while(cursor.moveToNext()){ //<span style="white-space:pre"> </span>M m = new M(); //<span style="white-space:pre"> </span>String title = cursor.getString(cursor.getColumnIndex(DBHelper.TABLE_NEWS_TITLE)); //<span style="white-space:pre"> </span>news.setTitle(title); <span style="white-space:pre"> </span>M m = getInstance(); <span style="white-space:pre"> </span>fillField(cursor, m); <span style="white-space:pre"> </span>result.add(m); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>cursor.close(); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>return result; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * 1.获取表名:利用注解Annotation <span style="white-space:pre"> </span> * @return <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span>private String getTableName() { <span style="white-space:pre"> </span>//获取实体 <span style="white-space:pre"> </span>M m = getInstance(); <span style="white-space:pre"> </span>//根据注解里value值获取表名 <span style="white-space:pre"> </span>TableName annotation = m.getClass().getAnnotation(TableName.class); <span style="white-space:pre"> </span>//如果需要在运行的时候获取注解,设置存活时间 <span style="white-space:pre"> </span>if(annotation != null){ <span style="white-space:pre"> </span>return annotation.value(); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>return ""; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * 创建实体对象 <span style="white-space:pre"> </span> * @return <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span>public M getInstance() { <span style="white-space:pre"> </span>//1哪个孩子在运行 <span style="white-space:pre"> </span>Class clazz = getClass(); //返回的是运行的class,this和super都一样 <span style="white-space:pre"> </span>//2获取该孩子的父类-“支持泛型”的父类 <span style="white-space:pre"> </span>//clazz.getSuperclass();这个方法没有泛型,用下面这个方法 <span style="white-space:pre"> </span>Type superClass = clazz.getGenericSuperclass(); <span style="white-space:pre"> </span>//泛型实现接口(参数化类型),规定了泛型的通用操作 <span style="white-space:pre"> </span>if(superClass != null && superClass instanceof ParameterizedType) { <span style="white-space:pre"> </span>//3获取到泛型中的参数 <span style="white-space:pre"> </span>Type[] arguments = ((ParameterizedType)superClass).getActualTypeArguments(); <span style="white-space:pre"> </span>try { <span style="white-space:pre"> </span>return (M) ((Class)arguments[0]).newInstance(); <span style="white-space:pre"> </span>} catch (InstantiationException e) { <span style="white-space:pre"> </span>e.printStackTrace(); <span style="white-space:pre"> </span>} catch (IllegalAccessException e) { <span style="white-space:pre"> </span>e.printStackTrace(); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>return null; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * 实体数据填充到数据库列 <span style="white-space:pre"> </span> * @param m 数据源 <span style="white-space:pre"> </span> * @param values 导入的目标 <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span>private void fillColumn(M m, ContentValues values) { <span style="white-space:pre"> </span>//m.getClass().getFields(); <span style="white-space:pre"> </span>Field[] fields = m.getClass().getDeclaredFields(); //获取字段 <span style="white-space:pre"> </span>for (Field field : fields) { <span style="white-space:pre"> </span>field.setAccessible(true); <span style="white-space:pre"> </span>Column column = field.getAnnotation(Column.class); <span style="white-space:pre"> </span>if(column != null) { <span style="white-space:pre"> </span>String key = column.value(); //得到列名 <span style="white-space:pre"> </span>try { <span style="white-space:pre"> </span>//得到实体的值 <span style="white-space:pre"> </span>String value = field.get(m).toString();//Returns the value of the field in the specified object. <span style="white-space:pre"> </span>//注意是不是主键,且主键是否自增 <span style="white-space:pre"> </span>ID id = field.getAnnotation(ID.class); <span style="white-space:pre"> </span>if(id != null && id.autoincrement()) { <span style="white-space:pre"> </span>//就不给主键赋值,不然主键都是0了 <span style="white-space:pre"> </span>} else { <span style="white-space:pre"> </span>values.put(key, value); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>} catch (IllegalAccessException e) { <span style="white-space:pre"> </span>e.printStackTrace(); <span style="white-space:pre"> </span>} catch (IllegalArgumentException e) { <span style="white-space:pre"> </span>e.printStackTrace(); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * 数据库数据填充到实体 <span style="white-space:pre"> </span> * @param cursor 数据库数据 <span style="white-space:pre"> </span> * @param m 待填充实体 <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span>private void fillField(Cursor cursor, M m) { <span style="white-space:pre"> </span>Field[] fields = m.getClass().getDeclaredFields(); <span style="white-space:pre"> </span>for (Field field : fields) { <span style="white-space:pre"> </span>field.setAccessible(true); <span style="white-space:pre"> </span>//拿到field的注解 <span style="white-space:pre"> </span>Column column = field.getAnnotation(Column.class); <span style="white-space:pre"> </span>if(column != null) { <span style="white-space:pre"> </span>//拿到数据库列的数据 <span style="white-space:pre"> </span>String value = cursor.getString(cursor.getColumnIndex(column.value())); <span style="white-space:pre"> </span>try { <span style="white-space:pre"> </span>//若返回的是int类型 <span style="white-space:pre"> </span>if(field.getType() == int.class) { <span style="white-space:pre"> </span>field.set(m, Integer.valueOf(value)); <span style="white-space:pre"> </span>} else { <span style="white-space:pre"> </span>field.set(m, value); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>} catch (IllegalAccessException e) { <span style="white-space:pre"> </span>e.printStackTrace(); <span style="white-space:pre"> </span>} catch (IllegalArgumentException e) { <span style="white-space:pre"> </span>e.printStackTrace(); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * 获取主键 <span style="white-space:pre"> </span> * @return <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span>private String getId(M m) { <span style="white-space:pre"> </span>Field[] fields = m.getClass().getDeclaredFields(); <span style="white-space:pre"> </span>for (Field field : fields) { <span style="white-space:pre"> </span>field.setAccessible(true); <span style="white-space:pre"> </span>ID id = field.getAnnotation(ID.class); <span style="white-space:pre"> </span>if(id != null) { <span style="white-space:pre"> </span>try { <span style="white-space:pre"> </span>return field.get(m).toString(); <span style="white-space:pre"> </span>} catch (IllegalAccessException e) { <span style="white-space:pre"> </span>e.printStackTrace(); <span style="white-space:pre"> </span>} catch (IllegalArgumentException e) { <span style="white-space:pre"> </span>e.printStackTrace(); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>return null; <span style="white-space:pre"> </span>} }
用到的三个注解类:主键、表名和列项
/** * 指定实体Field与数据库中列的对应关系 * @author lenov0 * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Column { /** * 列名 * @return */ String value(); }
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ID { boolean autoincrement(); }
/** * 指定实体与数据库中表的对应关系 * @author lenov0 * */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface TableName { /** * 表名 * @return */ String value(); }
举例:某新闻数据
数据库建立:
public class DBHelper extends SQLiteOpenHelper { public static int VERSION = 1; public static final String NAME = "itgn.db"; 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 TABLE_NEWS_SUMMARY = "summary"; //新闻表:主键+标题+摘要 public DBHelper(Context context) { super(context, NAME, null, VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table " + TABLE_NEWS_NAME + " (" + TABLE_ID + " integer primary key autoincrement, " + TABLE_NEWS_TITLE + " varchar(50), " + TABLE_NEWS_SUMMARY + " varchar(200))"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } }
bean:
/** * 新闻实体 * @author lenov0 * */ @TableName(DBHelper.TABLE_NEWS_NAME) public class News { @ID(autoincrement=true) @Column(DBHelper.TABLE_ID) private int id; @Column(DBHelper.TABLE_NEWS_TITLE) private String title; @Column(DBHelper.TABLE_NEWS_SUMMARY) private String summary; public int getId() { return id; } public String getTitle() { return title; } public String getSummary() { return summary; } public void setId(int id) { this.id = id; } public void setTitle(String title) { this.title = title; } public void setSummary(String summary) { this.summary = summary; } }
如此一来,数据库操作的实现只用:
/** * 依靠建立通用DAO,增删改查都在DaoSupport中实现,不用写了 * * @author lenov0 * */ public class NewsDaoImpl extends DaoSupport<News> implements NewsDao { public NewsDaoImpl(Context context) { super(context); } }不用再重新写增删改查了。
相关文章推荐
- 数据库设计(3)_逻辑结构设计_常用模块
- 从百万级别数据的分析角度,Mysql,Mongodb,Hbase如何选择?
- SQL Server 开发指南---存储过程
- MySQL索引
- SQL Server 开发指南---索引和视图
- ORA-00205: ?????????????????????解决方案
- oracle存储过程及Java调用
- SQLite笔记
- mongodb安装-配置文件
- mongodb常用命令
- Oracle SQL Developer如何配置TNS
- SQL Server 开发指南---Transact-SQL 编程
- 使用Redis实现高并发分布式序列号生成服务
- 有了SQLService的基础,轻松学习Oracle
- 数据库设计(2)_逻辑结构设计
- oracl sql 笔记【未整理】
- 数据库设计(1)_概念结构设计
- SQL Server 开发指南---T-SQL高级查询
- 【Oracle连接字符串】【Oracle Net Manager 服务命名配置】【PL/SQL 登陆数据库】
- SQL Server 2014 SP1 通过补丁KB3058865提供更新,SP1一文便知