数据库封装

首先要感谢下面的这篇文章
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;
    }
}
Python数据封装是将数据库操作相关的代码封装成一个模块或类,使得代码结构更加清晰,易于维护和重用。常用的Python数据库封装模块有: 1. PyMySQL:一个纯Python实现的MySQL客户端库,支持Python 2和Python 3。 2. MySQLdb:Python MySQL数据库接口,是Python的一个第三方模块,用于连接MySQL数据库。 3. SQLAlchemy:一个Python SQL工具和对象关系映射器,支持多种数据库,包括MySQL、PostgreSQL、SQLite、Oracle等。 4. Django ORM:一个Python Web框架,自带ORM(对象关系映射器),支持多种数据库,包括MySQL、PostgreSQL、SQLite等。 封装后的代码示例: ``` import pymysql class DB: def __init__(self, host, user, password, database): self.conn = pymysql.connect( host=host, user=user, password=password, database=database, charset='utf8' ) def query(self, sql): cursor = self.conn.cursor() cursor.execute(sql) result = cursor.fetchall() cursor.close() return result def insert(self, table, data): cursor = self.conn.cursor() keys = ','.join(data.keys()) values = ','.join(['%s'] * len(data)) sql = 'INSERT INTO %s (%s) VALUES (%s)' % (table, keys, values) cursor.execute(sql, tuple(data.values())) self.conn.commit() cursor.close() def update(self, table, data, condition): cursor = self.conn.cursor() values = ','.join(["%s='%s'" % (k, v) for k, v in data.items()]) sql = 'UPDATE %s SET %s WHERE %s' % (table, values, condition) cursor.execute(sql) self.conn.commit() cursor.close() def delete(self, table, condition): cursor = self.conn.cursor() sql = 'DELETE FROM %s WHERE %s' % (table, condition) cursor.execute(sql) self.conn.commit() cursor.close() def close(self): self.conn.close() ``` 以上代码是一个封装了MySQL数据库操作的类,包括查询、插入、更新和删除等常用操作。使用时只需实例化DB类,并调用对应的方法即可完成数据库操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值