面向对象式数据库框架

Posted 天耀106

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象式数据库框架相关的知识,希望对你有一定的参考价值。

1、使用到的注解

表注解:

package com.winfo.gdmsaec.app.databasepro.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DbTable 

    String value();

字段注解:

package com.winfo.gdmsaec.app.databasepro.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DbField 

    String value();

2、最底层接口:

package com.winfo.gdmsaec.app.databasepro.sqlite;

public interface IBaseDao<T> 

    /**
     * 插入操作
     * @param entity
     * @return
     */

    long insert(T entity);

3、接口的实现类:

package com.winfo.gdmsaec.app.databasepro.sqlite;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.winfo.gdmsaec.app.databasepro.annotations.DbField;
import com.winfo.gdmsaec.app.databasepro.annotations.DbTable;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class BaseDao<T> implements IBaseDao<T> 

    //持有一个数据库操作的引用
    private SQLiteDatabase sqLiteDatabase;
    //持有操作数据库所对应的java类型
    private Class<?> entityClass;
    //表名
    private String tableName;

    private boolean isInit = false;
    private Map<String, Field> cacheMap = new HashMap<>();

    public boolean init(SQLiteDatabase sqLiteDatabase, Class<?> entityClass) 
        this.sqLiteDatabase = sqLiteDatabase;
        this.entityClass = entityClass;

        if (isInit == false) 
            //开始完成自动创建表
            //1.得到一个表名
            tableName = entityClass.getAnnotation(DbTable.class).value();
            if (!sqLiteDatabase.isOpen()) 
                return false;
            

            //开始建表
            String sql = getCreateTableSql();
            sqLiteDatabase.execSQL(sql);

            initCacheMap();

            isInit = true;
        
        return isInit;
    

    private void initCacheMap() 
        //1.如何得到数据库表的所有字段名(查一次空表)
        String sql = "select * from " + tableName + " limit 1,0";
        Cursor cursor = sqLiteDatabase.rawQuery(sql, null);
        String[] columnNames = cursor.getColumnNames();
        //2.取到所有的成员变量
        Field[] columnFields = entityClass.getDeclaredFields();
        Field resultField = null;
        for (String columnName : columnNames) 
            for (Field field : columnFields) 
                String fieldAnnotationName = field.getAnnotation(DbField.class).value();
                if (columnName.equals(fieldAnnotationName)) 
                    resultField = field;
                    break;
                
            
            if (resultField != null) 
                cacheMap.put(columnName, resultField);
            
        
    

    private String getCreateTableSql() 
        StringBuffer sb = new StringBuffer();
        sb.append("create table if not exists ");
        sb.append(tableName + "(");
        //取到调用层传入的对象的所有变量成员
        Field[] fields = entityClass.getDeclaredFields();
        for (Field field : fields) 
            Class type = field.getType();
            if (type == String.class) 
                sb.append(field.getAnnotation(DbField.class).value() + " TEXT,");
             else if (type == Integer.class) 
                sb.append(field.getAnnotation(DbField.class).value() + " INTEGER,");
             else if (type == Long.class) 
                sb.append(field.getAnnotation(DbField.class).value() + " LONG,");
             else if (type == Double.class) 
                sb.append(field.getAnnotation(DbField.class).value() + " DOUBLE,");
             else if (type == byte[].class) 
                sb.append(field.getAnnotation(DbField.class).value() + " BLOB,");
             else 
                //不支持的类型
                continue;
            
        
        if (sb.charAt(sb.length() - 1) == ',') 
            sb.deleteCharAt(sb.length() - 1);
        
        sb.append(")");

        return sb.toString();
    

    @Override
    public long insert(T entity) 
        Map<String, String> map = getValue(entity);
        //把map中的内容存入到contentValues中
        ContentValues contentValues = getContentValues(map);
        long result = sqLiteDatabase.insert(tableName, null, contentValues);
        return result;
    

    private Map<String, String> getValue(T entity) 
        HashMap<String, String> map = new HashMap<>();
        Iterator<Field> iterator = cacheMap.values().iterator();
        while (iterator.hasNext()) 
            Field field = iterator.next();
            field.setAccessible(true);
            //获取成员变量的值
            try 
                Object obj = field.get(entity);
                String key = field.getAnnotation(DbField.class).value();
                map.put(key, String.valueOf(obj));
             catch (IllegalAccessException e) 
                e.printStackTrace();
            
        
        return map;
    

    private ContentValues getContentValues(Map<String, String> map) 
        ContentValues contentValues = new ContentValues();
        Set<String> keys = map.keySet();
        Iterator<String> iterator = keys.iterator();
        while (iterator.hasNext()) 
            String key = iterator.next();
            String value = map.get(key);
            if (value != null) 
                contentValues.put(key, value);
            
        
        return contentValues;
    

4、提供一个对外调用的接口工厂:

package com.winfo.gdmsaec.app.databasepro.sqlite;

import android.database.sqlite.SQLiteDatabase;

public class BaseDaoFactory 

    private static final BaseDaoFactory ourInstance = new BaseDaoFactory();

    public static BaseDaoFactory getInstance() 
        return ourInstance;
    

    private SQLiteDatabase sqLiteDatabase;
    private String path;

    private BaseDaoFactory() 
        path = "data/data/com.winfo.gdmsaec.app.databasepro/xiaolu.db";
        sqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(path, null);
    

    public <T> BaseDao<T> getBaseDao(Class<T> entityClass) 
        BaseDao baseDao = null;
        try 
            baseDao = BaseDao.class.newInstance();
            baseDao.init(sqLiteDatabase, entityClass);
         catch (Exception e) 
            e.printStackTrace();
        
        return baseDao;
    

5、使用到的实体类:

package com.winfo.gdmsaec.app.databasepro.bean;

import com.winfo.gdmsaec.app.databasepro.annotations.DbField;
import com.winfo.gdmsaec.app.databasepro.annotations.DbTable;

@DbTable("tb_user")
public class User 

    @DbField("_id")
    private Integer id;

    @DbField("name")
    private String name;

    @DbField("pwd")
    private String password;

    public User(Integer id, String name, String password) 
        this.id = id;
        this.name = name;
        this.password = password;
    

6、主界面调用

package com.winfo.gdmsaec.app.databasepro;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import com.winfo.gdmsaec.app.databasepro.bean.User;
import com.winfo.gdmsaec.app.databasepro.sqlite.BaseDao;
import com.winfo.gdmsaec.app.databasepro.sqlite.BaseDaoFactory;

public class MainActivity extends AppCompatActivity 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    

    public void click(View view) 
        BaseDao<User> baseDao = BaseDaoFactory.getInstance().getBaseDao(User.class);
        baseDao.insert(new User(1,"xiaolu","123456"));
        Toast.makeText(MainActivity.this, "执行成功.", Toast.LENGTH_SHORT).show();
    

下载地址:https://github.com/tianyao106/DataBasePro

以上是关于面向对象式数据库框架的主要内容,如果未能解决你的问题,请参考以下文章

面向对象式设计和面向函数式设计

九函数与函数式编程

js面向对象

全面理解js面向对象

沉浸式过Python基础(6-面向对象编程)

Spring