您的位置:首页 > 数据库

数据库封装

2016-04-18 19:02 411 查看
首先要感谢下面的这篇文章

http://blog.csdn.net/feiduclear_up/article/details/50557590

接下来贴上自己写好的代码

1.MyApplication.java

public class MyApplication extends Application {
private DBOperator mDBOperator;
private static MyApplication mApp;
@Override
public void onCreate() {
super.onCreate();
mApp = this;
}
/**
* 获取Application实例
* @return
*/
public static MyApplication getSelf(){
return mApp;
}
/**
* 创建线程安全的数据库实例
* @return
*/
public synchronized DBOperator getDBOperator(){
if(mDBOperator == null){
mDBOperator = DBOperator.getInstance(this);
}
return mDBOperator;
}
}


两个实体类如下

public class Student {
private String name;
private String sex;
private int age;

public Student(){

}
public Student(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}

public String getName() {
return name;
}
//注意:set和get方法必须提供,因为DBOperator的方法里面会通过反射获取
public void setName(String name) {
this.name = name;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}


public class Teacher {
private String name;
private int age;

public Teacher(){

}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//注意:set和get方法必须提供,因为DBOperator的方法里面会通过反射获取
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}


DBUtil .java 数据库工具类

public class DBUtil {
/**
* 获得表名
* @param clazz 实体类
* @return 表名
*/
public static String getTableName(Class<?> clazz){
return clazz.getSimpleName().toLowerCase();
}

/**
* 获取表字段类型
* @param fileType 字段类型
* @return 数据库表字段类型
*/
public static String getColumnType(String fileType){
String value = null;
if (fileType.contains("String")) {
value = " text";//注意:前面有个空格,目的是为了拼接
} else if (fileType.contains("int")) {
value = " integer";
} else if (fileType.contains("boolean")) {
value = " boolean ";
} else if (fileType.contains("float")) {
value = " float";
} else if (fileType.contains("double")) {
value = " double";
} else if (fileType.contains("char")) {
value = " varchar";
} else if (fileType.contains("long")) {
value = " long";
}
return value;
}

/**
* 首字母大写
* @param string
* @return
*/
public static String capitalize(String string) {
if (!TextUtils.isEmpty(string)) {
return string.substring(0, 1).toUpperCase(Locale.US) + string.substring(1);
}
return string == null ? null : "";
}
}


DBHelper .java 创建数据库表

public class DBHelper extends SQLiteOpenHelper {
private static final String TAG = "DBHelper";
private static final String DB_NAME = "person.db";//数据库名称
private static final int DB_VERSION = 1;//数据库版本,从1开始
public DBHelper(Context context) {
super(context,DB_NAME,null,DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {//数据库第一次创建执行,只执行一次,以后不再执行
Log.d(TAG, "onCreate: ");
db.execSQL(getCreateTableSql(Student.class));
db.execSQL(getCreateTableSql(Teacher.class));
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {//只有当数据库版本号发生变化的时候才会执行
}

/**
* 获取创建表的语句
* @param clazz
* @return
*/
private String getCreateTableSql(Class<?> clazz){
StringBuilder sb = new StringBuilder();
String tableName = DBUtil.getTableName(clazz);
sb.append("create table "+tableName+" (ID INTEGER PRIMARY KEY AUTOINCREMENT,");
Field[] fields = clazz.getDeclaredFields();//通过反射获取所有字段
for (Field fd:fields){
String fieldName = fd.getName();//字段名
String fieldType = fd.getType().getName();//字段类型名
//不需要字段中的id,因为数据库表有自增id
if(fieldName.equalsIgnoreCase("id")||fieldName.equalsIgnoreCase("_id")){
continue;
}else{//拼接字段名和类型,例如 age int,name text,
sb.append(fieldName).append(DBUtil.getColumnType(fieldType)).append(",");
}
}
int length = sb.length();
sb.replace(length-1,length,")");//删除最后一个,age int,name text
Log.d(TAG, "getCreateTableSql: "+sb.toString());
return sb.toString();
}
}


DBOperator .java 对数据库进行各种操作

public class DBOperator {

private static final String TAG = "DBOperator";
private static Context mContext;
private  SQLiteDatabase mDatabase;

private DBOperator() {
DBHelper dbHelper = new DBHelper(mContext);
mDatabase = dbHelper.getReadableDatabase();//获取数据库对象
}
//静态内部类实现单例
public static DBOperator getInstance(Context context) {
mContext = context;
return DBOperatorHolder.mOperator;
}
//静态内部类,创建单例对象
public static class DBOperatorHolder {
private static final DBOperator mOperator = new DBOperator();
}

/**
* 关闭数据库
*/
public void closeDatabase(){
mDatabase.close();
mDatabase = null;
}

/**
* 删除数据库
* @param dataBaseName 数据库名称
*/
public void deleteDatabase(String dataBaseName){
mContext.deleteDatabase(dataBaseName);
}

/**
* 删除表
* @param clazz 表对应的实体类
*/
public void deleteTable(Class<?> clazz){
mDatabase.execSQL("DROP TABLE IF EXISTS "+ clazz.getSimpleName());
}

/**
* 向指定的表中插入数据
* @param object 实体
* @param tableName 表名
* @return 插入行所在的id,如果返回-1,说明发生了错误
*/
public long insert(Object object, String tableName) {
ContentValues values = new ContentValues();
Cursor cursor = mDatabase.rawQuery("SELECT * FROM " + tableName, null);
for (int i = 0; i < cursor.getColumnCount(); i++) {
String name = cursor.getColumnName(i);//表中字段的名称
try {
//去除从表中获取的id字段,因为实体类中没有此字段
if (!"id".equalsIgnoreCase(name) && !"_id".equalsIgnoreCase(name)) {
Field field = object.getClass().getDeclaredField(name);//根据字段名称获取代表的Field对象
field.setAccessible(true);//让私有变量也可以访问
//当所有字段为String类型时可以用下面两行代码这种方式插入
//                    String value = (String) field.get(object);
//                    values.put(name,value);
putValues(values, field, object);//插入数据
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 第一个参数 表名
* 第二个参数 nullColumnHack (作用)当values参数为空或者里面没有内容的时候,insert是会失败的(底层数据库不允许插入一个空行),
* 为了防止这种情况,要在这里指定一个列名,到时候如果发现将要插入的行为空行时,
* 就会将你指定的这个列名的值设为null,然后再向数据库中插入。
* 源码如下
*   int size = (initialValues != null && initialValues.size() > 0)
? initialValues.size() : 0;
if (size > 0) {
bindArgs = new Object[size];
int i = 0;
for (String colName : initialValues.keySet()) {
sql.append((i > 0) ? "," : "");
sql.append(colName);
bindArgs[i++] = initialValues.get(colName);
}
sql.append(')');
sql.append(" VALUES (");
for (i = 0; i < size; i++) {
sql.append((i > 0) ? ",?" : "?");
}
} else {
sql.append(nullColumnHack + ") VALUES (NULL");
}
*/
return mDatabase.insert(tableName, null, values);
}

/**
* 插入数据
* @param values 内容
* @param fd 字段对象
* @param obj 实体类
*/
private void putValues(ContentValues values, Field fd, Object obj) {
Class<?> clazz = values.getClass();
try {
Object[] parameters = new Object[]{fd.getName(), fd.get(obj)};//创建包含字段名称和值的数组
Class<?>[] parameterTypes = getParameterTypes(fd, fd.get(obj), parameters);
//根据方法名称和方法参数类型获得方法
Method method = clazz.getDeclaredMethod("put", parameterTypes);
method.setAccessible(true);
//调用方法,values调用方法的对象,parameters方法的参数
method.invoke(values, parameters);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}

/**
* 获取参数类型
* @param field 字段
* @param fieldValue 字段值,
* @param parameters 保存字段名和字段值的数组
* @return 参数类型
*/
private Class<?>[] getParameterTypes(Field field, Object fieldValue, Object[] parameters) {
Class<?>[] parameterTypes;
if (isCharType(field)) {//如果是字符类型,第二个参数当String处理
parameters[1] = String.valueOf(fieldValue);
parameterTypes = new Class[]{String.class, String.class};
} else {
//如果字段是基本数据类型,比如int,long,float,第二个参数为对应的class对象
if (field.getType().isPrimitive()) {
parameterTypes = new Class[]{String.class, getObjectType(field.getType())};
//如果是Date类型,第二个参数为long类型
} else if ("java.util.Date".equals(field.getType().getName())) {
parameterTypes = new Class[]{String.class, Long.class};
} else {
parameterTypes = new Class[]{String.class, field.getType()};
}
}
return parameterTypes;
}

/**
* 判断字段类型是否是字符
* @param field 字段
* @return true 是字符
*/
private boolean isCharType(Field field) {
//获得字段类型名称
String type = field.getType().getName();
return type.equals("char") || type.endsWith("Character");
}

/**
* 根据字段类型获取对象
* @param primitiveType
* @return
*/
private Class<?> getObjectType(Class<?> primitiveType) {
if (primitiveType != null) {
if (primitiveType.isPrimitive()) {
String basicTypeName = primitiveType.getName();
if ("int".equals(basicTypeName)) {
return Integer.class;
} else if ("short".equals(basicTypeName)) {
return Short.class;
} else if ("long".equals(basicTypeName)) {
return Long.class;
} else if ("float".equals(basicTypeName)) {
return Float.class;
} else if ("double".equals(basicTypeName)) {
return Double.class;
} else if ("boolean".equals(basicTypeName)) {
return Boolean.class;
} else if ("char".equals(basicTypeName)) {
return Character.class;
}
}
}
return null;
}

/**
* 查询所有数据
* @param clazz 实体类对象
* @param <T> 实体类
* @return 数据集合
*/
public <T> List<T> findAll(Class<T> clazz) {
//参数:表名,
//columns,需要查询那些列,传入null会查询所有列的数据
//select 条件语句
//selectionargs 条件参数
//groupby 分组
//having
//orderby
Cursor cursor = mDatabase.query(clazz.getSimpleName(), null, null, null, null, null, null);
return getEntity(cursor, clazz);
}

/**
* 根据参数获取结果
* @param clazz 实体类对象
* @param select 条件语句 id = ?
* @param selectArgs 条件参数 new String[]{"1"}
* @param <T> 实体类
* @return
*/
public <T> List<T> findByArgs(Class<T> clazz,String select,String[] selectArgs){
Cursor cursor = mDatabase.query(clazz.getSimpleName(), null, select, selectArgs, null, null, null);
return getEntity(cursor,clazz);
}

public <T> T findById(Class<T> clazz,int id){
Cursor cursor = mDatabase.query(clazz.getSimpleName(), null, "id=" + id, null, null, null, null);
List<T> list = getEntity(cursor, clazz);
android.util.Log.d(TAG, "findById: "+list);
return list.get(0);
}

public int deleteById(Class<?> clazz,int id){
return mDatabase.delete(clazz.getSimpleName(),"id="+id,null);
}
public int deleteByArgs(Class<?> clazz,String select,String[] args){
return mDatabase.delete(clazz.getSimpleName(),select,args);
}

public int deleteAll(Class<?> clazz){
return mDatabase.delete(clazz.getSimpleName(),null,null);
}
public void updateById(Class<?> clazz,ContentValues values,int id){
mDatabase.update(clazz.getSimpleName(),values,"id="+id,null);
}
public <T> List<T> getEntity(Cursor cursor, Class<T> clazz) {
List<T> list = new ArrayList<>();
try {
if (cursor != null && cursor.moveToFirst()) {
do {
Field[] fields = clazz.getDeclaredFields();
T moduleClass = clazz.newInstance();
for (Field field : fields) {
Class<?> cursorClass = cursor.getClass();
String columnMethodName = getColumnMethodName(field.getType());
Method cursorClassMethod = cursorClass.getMethod(columnMethodName, int.class);
Object value = cursorClassMethod.invoke(cursor, cursor.getColumnIndex(field.getName()));
if (field.getType() == boolean.class || field.getType() == Boolean.class) {
if ("0".equals(String.valueOf(value))) {
value = false;
} else if ("1".equals(String.valueOf(value))) {
value = true;
}
} else if (field.getType() == char.class || field.getType() == Character.class) {
value = ((String) value).charAt(0);
} else if (field.getType() == Date.class) {
long date = (Long) value;
if (date <= 0) {
value = null;
} else {
value = new Date(date);
}
}
String methodName = makeSetterMethodName(field);
Method method = clazz.getDeclaredMethod(methodName, field.getType());
method.invoke(moduleClass, value);
}
list.add(moduleClass);
} while (cursor.moveToNext());

}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
return list;
}

private String getColumnMethodName(Class<?> fieldType) {
String typeName;
if (fieldType.isPrimitive()) {//如果此类代表的是基本数据类型
typeName = DBUtil.capitalize(fieldType.getName());
} else {
typeName = fieldType.getSimpleName();
}
String methodName = "get" + typeName;
if ("getBoolean".equals(methodName)) {
methodName = "getInt";
} else if ("getChar".equals(methodName) || "getCharacter".equals(methodName)) {
methodName = "getString";
} else if ("getDate".equals(methodName)) {
methodName = "getLong";
} else if ("getInteger".equals(methodName)) {
methodName = "getInt";
}
return methodName;
}

private String makeSetterMethodName(Field field) {
String setterMethodName;
String setterMethodPrefix = "set";
if (isPrimitiveBooleanType(field) && field.getName().matches("^is[A-Z]{1}.*$")) {
setterMethodName = setterMethodPrefix + field.getName().substring(2);
} else if (field.getName().matches("^[a-z]{1}[A-Z]{1}.*")) {
setterMethodName = setterMethodPrefix + field.getName();
} else {
setterMethodName = setterMethodPrefix + DBUtil.capitalize(field.getName());
}
return setterMethodName;
}

private boolean isPrimitiveBooleanType(Field field) {
Class<?> fieldType = field.getType();
if ("boolean".equals(fieldType.getName())) {
return true;
}
return false;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: