编写的通用数据库操作类
来源:互联网 发布:建站abc代理商 编辑:程序博客网 时间:2024/05/25 16:38
首先需要对象化要建表的对象,如News
通过一个interface,并定义增删改查方法,其传入的对象应当为泛型,只有这样才有通用性。需要一个
基础Dao类,DAO<M>,也使用了泛型,对应上面的实体类
public interface DAO<M> {//提供增删改查的接口long insert(M m);int delete(Serializable m);int update(M m);List<M> findAll();}
接着需要有抽象类实现该接口,这些接口就是具体的类的接口,即泛型实例化,如下:
public abstract class DaoSupport<M> implements DAO<M> {
// 操作省略。。。。。。。。。。。。。。。。。。。。。。
}
需要让对象(News)和表建立对应关系,如获取表名和对象的关系(News类对应news表等等),或者 类中属性 和表的列 建立对应关系。
要实现上述操作,则可以通过自定义注解的方式完成。如下:
@TableName(MyDBHelper.TABLE_NEWS)public class News {@Primarykey@Column(MyDBHelper.COLUMN_NEWS_ID)private int id;@Column(MyDBHelper.COLUMN_NEWS_TITLE)private String title;//省略下面的set和get方法}
上面这段是一个简单的数据库实体类,其中的@TableName,@Primarykey,@Column都为自定义注解,其中@TableName的自定义注解如下:
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;//表明只能在类上使用该注解,还有如ElementType.FIELD,表示可以在字段上使用,ElementType.METHOD表示可以在方法上使用@Target(ElementType.TYPE) //表明可以在运行时获取该注解及其值,此外还有RetentionPolicy.SOURCE,表示在源代码阶段可以获取注解及其值@Retention(RetentionPolicy.RUNTIME) public @interface TableName {String value();}而其他的注解,也和该注解大同小异。
问题一:如何获取表名
对数据库的操作需要表名,而传入的为泛型,这样如何获取表名呢?
其实在上面自定义的注解,已经给出了答案,
<pre name="code" class="html">@TableName(MyDBHelper.TABLE_NEWS)这个表明该Class是与数据库的表对应的,对应的表名为
MyDBHelper.TABLE_NEWS
知道了这个,就很容易了,无非是获取泛型M的实例(即实例化一个M,如何实例化,请看后面)
接着就需要对该实例的注解进行解析,解析方式如下:
/** * 获取表名 */public String getTableName() {M m = getInstance();TableName annotation = m.getClass().getAnnotation(TableName.class);if (annotation != null) {// 说明有设置表名,则获取表名return annotation.value();}return "";}
问题二:如何将实体中的数据,按照对应关系导入到数据库中
其实可以观察一下普通的insert方法,如下:
// 普通写法ContentValues values = new ContentValues();values.put(MyDBHelper.COLUMN_NEWS_ID, news.getId());values.put(MyDBHelper.COLUMN_NEWS_TITLE, news.getTitle());return db.insert(MyDBHelper.TABLE_NEWS, null, values);会发现News对象插入数据库,最重要的就是把News对象中的属性(field)给存放到ContentValues对象中。所以实现如下:
//通过自定义 fillValues方法,完成。
private void fillValues(M m, ContentValues values) {// 获取该类中添加的字段(不包括其父类的字段)Field[] declaredFields = m.getClass().getDeclaredFields();for (Field item : declaredFields) {// 有则表明为和表字段对应的属性Column annotation = item.getAnnotation(Column.class);if (annotation != null) {// 对应的表字段名// annotation.value().toString();item.setAccessible(true);// 对象的属性值// item.get(m);try {values.put(annotation.value(), item.get(m).toString());} catch (Exception e) {e.printStackTrace();}}}}
问题三: 在查询到数据库表数据后,如何取出?(查询时使用)
我们也可以观察一下,原查询语句:
@Overridepublic List<News> findAll() {List list = null;Cursor cursor = db.query(getTableName(), null, null, null, null, null,null);if (cursor != null) {list = new ArrayList<New>();while (cursor.moveToNext()) {News m = new News();m.setTitle(cursor.getString(cursor.getColumnIndex("title")));
<span style="white-space:pre"></span>list.add(m);}cursor.close();}return list;}会发现,其实最重要的就是 把Cursor中的数据给取出到实例化的对象中。
则写方法如下:
/** * 把ContentValues中的值取出到M中 */private void fillField(Cursor cursor, M m) {Field[] fields = m.getClass().getDeclaredFields();for (Field item : fields) {item.setAccessible(true);Column column = item.getAnnotation(Column.class);if (column != null) {int columnIndex = cursor.getColumnIndex(column.value());String value = cursor.getString(columnIndex);try {item.set(m, value);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}}
问题四: 如何获取主键名和主键值(在修改删除等操作中需要)
上面有@Primarykey自定义注解,该注解就是为了声明哪个为主键的,所以实现如下:
/** * 获取该对象主键和主键值,为一个数组 * * @param m * @return */private String[] getID(M m) {Field[] fields = m.getClass().getDeclaredFields();for (Field item : fields) {// 有则表明为和表字段对应的属性Primarykey annotation = item.getAnnotation(Primarykey.class);if (annotation != null) {// 对应的表字段名// annotation.value().toString();item.setAccessible(true);Column annotation2 = item.getAnnotation(Column.class);String[] results = null;if (annotation2 != null) {results = new String[2];results[0] = annotation2.value();try {results[1] = item.get(m).toString();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return results;}}}return null;}
问题五: 如何获取M泛型的实例
在上述中,获取表名,查询数据并返回等各种操作都需要使用到M泛型的实例。
那么如何获取泛型对象是哪个具体的类又如何实例化泛型对象呢?
由于是泛型无法通过如:
M m = new M();或者
M m = M.class.newInstance();的方式完成实例化,所以就需要通过特别的方式获取。如下:
/** * 获取到实体 */public M getInstance() {//返回该Object运行时类,例子如下://即如果一个类名为A继承了DaoSupport类(即本类),并泛型为News//class A extends DaoSupport<News>{////````//};//这时调用getClass()获取的为class com.luan.myNormalDB.DBTest$A//可以发现获取到的为A类本身,这样就可以通过该类获取其带参数的父类Class clazz = getClass();Log.i(TAG, clazz.getName());//获取的为class com.luan.myNormalDB.DaoSupport//clazz.getSuperclass();//获取的为com.luan.myNormalDB.DaoSupport<com.luan.myNormalDB.News>//clazz.getGenericSuperclass();Type type = clazz.getGenericSuperclass();if(type != null && type instanceof ParameterizedType){ParameterizedType pType = (ParameterizedType) type;//Returns an array of the actual type arguments for this type. //返回的结果为[class com.luan.myNormalDB.News]Type[] types = pType.getActualTypeArguments();try {return (M) ((Class) types[0]).newInstance();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}return null;}
本程序思想来自黑马视频,我只是按照思想操作~
0 0
- 编写的通用数据库操作类
- 利用Hibernate编写通用的数据库操作代码
- Hibernate编写通用数据库操作代码
- Hibernate编写通用数据库操作代码
- Hibernate编写通用数据库操作代码
- 使用Hibernate编写通用数据库操作代码
- Hibernate编写通用数据库操作代码
- Hibernate编写通用数据库操作代码
- Hibernate编写通用数据库操作代码演示
- 使用Hibernate编写通用数据库操作代码
- 通用的数据库增删改操作类
- ASP在线操作数据库的通用类
- ASP在线操作数据库的通用类
- winform中通用的数据库操作类
- 对MySql数据库操作的通用类
- 操作Access的通用数据库类
- JAVA操作数据库的一个通用类
- 通用的数据库操作类(支持多种数据库)
- UIKit类结构图
- 以太网的启示--公开课笔记--
- Java初级优化
- rqnoj PID74 24点
- live555中openRTSP用法
- 编写的通用数据库操作类
- 前台UI框架网址
- tomcat启动异常
- Java高级优化技术
- IP与点分十进制数的字符串之间的转换(c++)
- sqlcipher 加密数据库问题3
- 依赖属性
- 软件程序接口说明
- $ npm install -d 是什么意思?