Android 本地数据存储四 ormlite的使用和基于反射的数据库工具封装

OrmLite实现数据库增删改查操作 OrmLite 数据库操作 立即下载

一.主要讲解内容

1.基于运行时注解的ormlite的使用

2.基于反射的数据库工具封装

3.基于编译时注解的greendao的使用

二.github 的下载地址

https://github.com/MatrixSpring/OrmLiteDemo

三.视频讲解

 

四.原理分析

1.ormlite的使用

1.导入依赖

 implementation 'com.j256.ormlite:ormlite-android:5.0'
 implementation 'com.j256.ormlite:ormlite-core:5.0'

2.使用注解建立bean类

  1. 创建表名         @DatabaseTable(tableName = "xxxx") //xxxx指用户自己定义的表名
  2. 绑定id字段      @DatabaseField(generatedId = true)   //设置表的id为主键且自动生成
  3. 绑定普通字段  @DatabaseField(columnName = "name")
  4. bean对象的例子
@DatabaseTable(tableName = "article")
public class ArticleBean {
    // article表中各个字段的名称
    public static final String COLUMNNAME_ID = "id";
    public static final String COLUMNNAME_TITLE = "title";
    public static final String COLUMNNAME_CONTENT = "content";
    public static final String COLUMNNAME_USER = "user_id";

    @DatabaseField(generatedId = true, columnName = COLUMNNAME_ID, useGetSet = true)
    private int id;
    @DatabaseField(columnName = COLUMNNAME_TITLE, useGetSet = true, canBeNull = false, unique = true)
    private String title;
    @DatabaseField(columnName = COLUMNNAME_CONTENT, useGetSet = true)
    private String content;
    @DatabaseField(columnName = COLUMNNAME_USER, foreign = true, foreignAutoRefresh = true, foreignAutoCreate = true,
            foreignColumnName = UserBean.COLUMNNAME_ID)
    private UserBean user_id;

    public ArticleBean() {
    }

    public ArticleBean(String title, String content, UserBean user) {
        this.title = title;
        this.content = content;
        this.user_id = user;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public UserBean getUser() {
        return user_id;
    }

    public void setUser(UserBean user) {
        this.user_id = user;
    }

    @Override
    public String toString() {
        return "ArticleBean{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", content='" + content + '\'' +
                ", user=" + user_id +
                '}';
    }
}

3.使用OrmLiteSqliteOpenHelper类,建立OrmLiteHelper帮助类继承自OrmLiteSqliteOpenHelper类。

1.继承后系统提示会有几个重要的方法要实现   

@Override // 创建数据库时调用的方法
public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
}

@Override // 数据库版本更新时调用的方法
public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
}

// 释放资源
@Override
public void close() {
    super.close();
}

2.对OrmLiteHelper实现单例化,采用Java中的双重检查锁(double checked locking)单例 传进来的上下文context需要使用Application的content不然会产生内存泄漏,当然里面也可以使用(软引用,弱引用)的activity。也可以使用内部静态类产生对象。

3.使用map存储APP中所有的DAO对象 private Map<String, Dao> daos = new HashMap<>();这样在使用时通过对象名获取到相应的操作表的对象。在close()方法中释放map中引用的对象

4.DatabaseHelper的实现

public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
    // 数据库名称
    public static final String DATABASE_NAME = "mydb.db";
    // 本类的单例实例
    private static DatabaseHelper instance;
    // 存储APP中所有的DAO对象的Map集合
    private Map<String, Dao> daos = new HashMap<>();

    // 获取本类单例对象的方法
    public static synchronized DatabaseHelper getInstance(Context context) {
        if (instance == null) {
            synchronized (DatabaseHelper.class) {
                if (instance == null) {
                    instance = new DatabaseHelper(context);
                }
            }
        }
        return instance;
    }

    // 私有的构造方法
    private DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, 1);
    }

    // 根据传入的DAO的路径获取到这个DAO的单例对象(要么从daos这个Map中获取,要么新创建一个并存入daos)
    public synchronized Dao getDao(Class clazz) throws SQLException {
        Dao dao = null;
        String className = clazz.getSimpleName();
        if (daos.containsKey(className)) {
            dao = daos.get(className);
        }
        if (dao == null) {
            dao = super.getDao(clazz);
            daos.put(className, dao);
        }
        return dao;
    }

    @Override // 创建数据库时调用的方法
    public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
        try {
            TableUtils.createTable(connectionSource, UserBean.class);
            TableUtils.createTable(connectionSource, ArticleBean.class);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override // 数据库版本更新时调用的方法
    public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
        try {
            TableUtils.dropTable(connectionSource, UserBean.class, true);
            TableUtils.dropTable(connectionSource, ArticleBean.class, true);
            onCreate(database, connectionSource);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // 释放资源
    @Override
    public void close() {
        super.close();
        for (String key : daos.keySet()) {
            Dao dao = daos.get(key);
            dao = null;
        }
    }
}

2.基于反射的数据库工具封装

1.思维设计

对于设计数据库封装工具。我们首先得把一些场景和条件或者说约束列出来

1.提供的一系列的数据接口,都需要提供统一的方法 增删改查批量的增加减少。于是就可以抽象出统一的接口来规范这些操作。

2.对于这个数据接口的实现类,我们想一般需要从外面传进来两个参数,一个是数据库操作的类,一个是这个数据接口封装的对象。

3.对外使用时我们需要调一个统一的入口,返回我们需要的带有上述增删改查统一接口方法的对象。这时我们想到了单例模式和工厂模式。

4.由于数据库的创建和连接销毁这个功能实现比较耗性能和消耗内存因此这个功能也需要用单例模式来实现。

5.工厂入口使用单例来实现了,里面的数据库操作的功能类也是单例实现了。那么这个工厂类需要根据传进去的类,初始化表的创建,根据传进去的类通过反射找到里面的参数。来实现接口增删改查功能。反射会有点耗性能。

6.sqlite中和Java中对于基本数据集的定义不同需要根据不同类型做转化。

7.我们可以将一个工厂实现的接口类里面定义一个缓存,将发射获取的参数加入到缓存中。下次其他方式操作这个类时就可以使用之前的缓存减少性能消耗。

8.查询支持类需要专门分装,由于查询的条件多方式多专门封装后功能清晰不凌乱。

9.在Android6.0以后在存储器上见文件需要权限,因此在数据库初始化时需要检测是否有存储器上的创建和读写的权限。

10.更高级的优化即把运行时的反射功能改成编译时自动生成代码功能。比如说greendao。

2.功能模块

1.接口定义

2.数据库操作工具单例实现

3.操作入口工厂工具类的实现 

4.转化工具类的实现

5.查询功能的封装

3.代码

1.接口定义代码

public interface IDaoSupport<T> {
    void init(SQLiteDatabase sqLiteDatabase, Class<T> tClass);
    //插入数据
    public long insert(T t);
    //批量插入数据
    public void insert(List<T> dataList);
    //获取专门的查询的支持类
    QuerySupport<T> querySupport();
    //
    int delete(String whereClause, String... whereArgs);

    int update(T obj, String whereClause, String... whereArgs);
}

2.数据库操作工具单例实现代码和工厂入口工具类的实现代码

public class DaoSupportFactory {
    // 持有外部数据库的引用
    private SQLiteDatabase mSqLiteDatabase;
    private static final String db_name = "yty";
    private static WeakReference<Context> weakReference;

    public static class DaoSupportInstance{
        public static DaoSupportFactory daoSupportFactory=new DaoSupportFactory();
    }

    public static DaoSupportFactory getInstance(Context context){
        weakReference = new WeakReference<>(context);
        return DaoSupportInstance.daoSupportFactory;
    }

    private DaoSupportFactory(){
        // 把数据库放到内存卡里面  判断是否有存储卡 6.0要动态申请权限
        File dbRoot = new File(weakReference.get().getFilesDir().getAbsolutePath() + File.separator + db_name + File.separator + "database");
        if (!dbRoot.exists()) {
            dbRoot.mkdirs();
        }
        File dbFile = new File(dbRoot, "test.db");

        // 打开或者创建一个数据库
        mSqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(dbFile, null);
    }

    public <T> IDaoSupport<T> getDao(Class<T> clazz) {
        IDaoSupport<T> daoSupport = new DaoSupport();
        daoSupport.init(mSqLiteDatabase, clazz);
        return daoSupport;
    }
}

3.数据库接口实现类

public class DaoSupport<T> implements IDaoSupport<T> {
    private String TAG = "DaoSupport";
    private SQLiteDatabase mSqLiteDatabase;
    //范型类
    private Class<T> mClass;
    private static final Object[] mPutMethodArgs = new Object[2];

    private static final Map<String, Method> mPutMethods = new ArrayMap<>();

    private QuerySupport<T> mQuerySupport;

    @Override
    public void init(SQLiteDatabase sqLiteDatabase, Class<T> tClass) {
        this.mSqLiteDatabase = sqLiteDatabase;
        this.mClass = tClass;

        //创建表
//        create table if not exists Student(
//                id integer primary key autoincrement,
//                name text,
//                age integer,
//                flag boolean
//        )

        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("create table if not exists ")
                .append(DaoUtils.getTableName(mClass))
                .append("(id integer primary key autoincrement, ");

        Field[] fields = mClass.getDeclaredFields();
        for(Field field: fields){
            field.setAccessible(true);
            String name = field.getName();
            String type = field.getType().getSimpleName();// int String boolean
            //  type需要进行转换 int --> integer, String text;
            stringBuffer.append(name).append(DaoUtils.getColumnType(type)).append(", ");
        }

        stringBuffer.replace(stringBuffer.length()-2, stringBuffer.length(),")");
        String createTableSql = stringBuffer.toString();

        // 创建表
        mSqLiteDatabase.execSQL(createTableSql);
    }

    @Override
    public long insert(T t) {
//        ContentValues values = new ContentValues();
//        values.put("name",person.getName());
//        values.put("age",person.getAge());
//        values.put("flag",person.getFlag());
//        db.insert("Person",null,values);

        // 使用的其实还是  原生的使用方式,只是我们是封装一下而已
        ContentValues values = contentValuesByObj(t);

        // null  速度比第三方的快一倍左右
        return mSqLiteDatabase.insert(DaoUtils.getTableName(mClass), null, values);
    }

    @Override
    public void insert(List<T> dataList) {
        //批量插入数据采用 采用事务 提高 性能
        mSqLiteDatabase.beginTransaction();
        for(T data: dataList){
            //采用单条插入
            insert(data);
        }
        mSqLiteDatabase.setTransactionSuccessful();
        mSqLiteDatabase.endTransaction();
    }

    @Override
    public QuerySupport<T> querySupport() {
        if (null == mQuerySupport){
            mQuerySupport = new QuerySupport<>(mSqLiteDatabase, mClass);
        }
        return mQuerySupport;
    }

    @Override
    public int delete(String whereClause, String... whereArgs) {
        return mSqLiteDatabase.delete(DaoUtils.getTableName(mClass), whereClause, whereArgs);
    }

    @Override
    public int update(T obj, String whereClause, String... whereArgs) {
        ContentValues values = contentValuesByObj(obj);
        return mSqLiteDatabase.update(DaoUtils.getTableName(mClass),values,whereClause,whereArgs);
    }

    private ContentValues contentValuesByObj(T obj){
        // 第三方的 使用比对一下 了解一下源码
        ContentValues values = new ContentValues();
        //封装values
        Field[] fields = mClass.getDeclaredFields();

        for(Field field: fields){
            try{
                //设置权限,私有和公有的都可以访问
                field.setAccessible(true);
                String key = field.getName();
                //获取value
                Object value = field.get(obj);

                //put第二个参数是类型 需要转化
                mPutMethodArgs[0] = key;
                mPutMethodArgs[1] = value;

                //方法使用反射,反射在一定程度上会影响性能
                //参考AppCompatViewInflater源码
                String filedTypeName = field.getType().getName();
                //还是使用反射  获取方法  put  缓存方法
                Method putMethod = mPutMethods.get(filedTypeName);
                if(putMethod == null){
                    putMethod = ContentValues.class.getDeclaredMethod("put", String.class, value.getClass());
                    mPutMethods.put(filedTypeName, putMethod);
                }
                //通过反射执行
                putMethod.invoke(values,mPutMethodArgs);
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                mPutMethodArgs[0] = null;
                mPutMethodArgs[1] = null;
            }
        }
        return values;
    }
}

4.转化工具类的实现代码

public class DaoUtils {
    private DaoUtils() {
        throw new UnsupportedOperationException("cannot be instantiated");
    }

    /**
     * 获得类名
     */
    public static String getTableName(Class<?> clazz) {
        return clazz.getSimpleName();
    }

    /**
     * 数据库操作的时候根据类型进行转换
     */
    public static String getColumnType(String type) {
        String value = null;
        if (type.contains("String")) {
            value = " text";
        } else if (type.contains("int")) {
            value = " integer";
        } else if (type.contains("boolean")) {
            value = " boolean";
        } else if (type.contains("float")) {
            value = " float";
        } else if (type.contains("double")) {
            value = " double";
        } else if (type.contains("char")) {
            value = " varchar";
        } else if (type.contains("long")) {
            value = " long";
        }
        return value;
    }

    /**
     * 查询数据:cursor.getInt();将int第一个字符进行转换成大写
     */
    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 : "";
    }
}

5.查询功能的封装代码

public class QuerySupport<T> {
    // 查询的列
    private String[] mQueryColumns;
    // 查询的条件
    private String mQuerySelection;
    // 查询的参数
    private String[] mQuerySelectionArgs;
    // 查询分组
    private String mQueryGroupBy;
    // 查询对结果集进行过滤
    private String mQueryHaving;
    // 查询排序
    private String mQueryOrderBy;
    // 查询可用于分页
    private String mQueryLimit;

    private Class<T> mClass;
    private SQLiteDatabase mSQLiteDatabase;

    public QuerySupport(SQLiteDatabase sqLiteDatabase, Class<T> clazz) {
        this.mClass = clazz;
        this.mSQLiteDatabase = sqLiteDatabase;
    }

    public QuerySupport columns(String... columns) {
        this.mQueryColumns = columns;
        return this;
    }

    public QuerySupport selectionArgs(String... selectionArgs) {
        this.mQuerySelectionArgs = selectionArgs;
        return this;
    }

    public QuerySupport having(String having) {
        this.mQueryHaving = having;
        return this;
    }

    public QuerySupport orderBy(String orderBy) {
        this.mQueryOrderBy = orderBy;
        return this;
    }

    public QuerySupport limit(String limit) {
        this.mQueryLimit = limit;
        return this;
    }

    public QuerySupport groupBy(String groupBy) {
        this.mQueryGroupBy = groupBy;
        return this;
    }

    public QuerySupport selection(String selection) {
        this.mQuerySelection = selection;
        return this;
    }

    public List<T> query() {
        Cursor cursor = mSQLiteDatabase.query(DaoUtils.getTableName(mClass), mQueryColumns, mQuerySelection,
                mQuerySelectionArgs, mQueryGroupBy, mQueryHaving, mQueryOrderBy, mQueryLimit);
        clearQueryParams();
        return cursorToList(cursor);
    }

    public List<T> queryAll() {
        Cursor cursor = mSQLiteDatabase.query(DaoUtils.getTableName(mClass), null, null, null, null, null, null);
        return cursorToList(cursor);
    }

    /**
     * 清空参数
     */
    private void clearQueryParams() {
        mQueryColumns = null;
        mQuerySelection = null;
        mQuerySelectionArgs = null;
        mQueryGroupBy = null;
        mQueryHaving = null;
        mQueryOrderBy = null;
        mQueryLimit = null;
    }

    /**
     * 通过Cursor封装成查找对象
     *
     * @return 对象集合列表
     */
    private List<T> cursorToList(Cursor cursor) {
        List<T> list = new ArrayList<>();
        if (cursor != null && cursor.moveToFirst()) {
            do {
                try {
                    T instance = mClass.newInstance();
                    Field[] fields = mClass.getDeclaredFields();
                    for (Field field : fields) {
                        // 遍历属性
                        field.setAccessible(true);
                        String name = field.getName();
                        //cursor.getInt(0);
                        // 获取角标
                        int index = cursor.getColumnIndex(name);
                        if (index == -1) {
                            continue;
                        }
                        // 通过反射获取 游标的方法
                        Method cursorMethod = cursorMethod(field.getType());
                        if (cursorMethod != null) {
                            Object value = cursorMethod.invoke(cursor, index);
                            if (value == null) {
                                continue;
                            }

                            // 处理一些特殊的部分
                            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);
                                }
                            }
                            field.set(instance, value);
                        }
                    }
                    // 加入集合
                    list.add(instance);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } while (cursor.moveToNext());
        }
        cursor.close();
        return list;
    }

    private Method cursorMethod(Class<?> type) throws Exception {
        String methodName = getColumnMethodName(type);
        Method method = Cursor.class.getMethod(methodName, int.class);
        return method;
    }

    private String getColumnMethodName(Class<?> fieldType) {
        String typeName;
        if (fieldType.isPrimitive()) {//是不是基本类型
            typeName = DaoUtils.capitalize(fieldType.getName());//Int
        } else {
            typeName = fieldType.getSimpleName();//Integer
        }
        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;
    }

}

6.使用 

新建的java bean对象必须有无参的构造函数

 

 

3.类似封装SQLCipher

将上面的sqlite换成sqlcipher也可以实现类似封装,源码在面链接中的libframe中,帮忙点个赞

GitHub地址:https://github.com/MatrixSpring/FrameWork

 

4.基于编译时注解的greendao的使用

 

 

Android-一个方便实用的OrmLite数据库框架支持一键集成。 一个方便实用的OrmLite数据库框架,支持一键集成。 立即下载

相关推荐

改进差分进化算法及其求解柔性作业车间调度问题(Python代码实现)

内容概要:本文系统探讨了改进差分进化算法在求解柔性作业车间调度问题中的应用,并结合Python代码实现,展示了该算法相较于传统方法在全局搜索能力和收敛速度方面的优势。研究不仅聚焦于算法本身的改进策略,如变异、交叉和选择操作的优化,还深入分析了其在复杂制造环境中应对多目标、多约束调度问题的有效性。文中通过标准测试实例验证了算法性能,并与其他智能优化算法进行了对比分析,体现了其在实际工程应用中的潜力。此外,文档还关联了多无人机路径规划、电力系统状态估计、微电网优化、图像与信号处理等多个前沿技术领域,展现了智能优化算法在跨学科工程仿真与决策支持中的广泛适用性。; 适合人群:具备一定编程基础和工程背景,从事智能制造、自动化、工业工程、电气工程、控制科学与工程、计算机科学及相关领域的科研人员、高校研究生及企业研发技术人员。; 使用场景及目标:①为科研工作者提供可复现的智能优化算法代码框架,支持柔性作业车间调度、多无人机协同路径规划、电力系统优化等复杂工程问题的建模仿真;②辅助完成学术论文复现、课程设计、毕业设计或科研项目开发;③推动智能算法在生产调度、能源管理、交通规划等实际场景中的落地应用。; 阅读建议:建议读者结合文中提供的算法原理与代码实现,动手调试并验证不同参数设置对优化结果的影响,同时可参考荔枝科研社提供的完整资源包进行扩展学习与实践,以加深对算法机制与工程应用的理解。

Ormlite 数据库的使用

首先添加依赖public class DataBaseHelper extends OrmLiteSqliteOpenHelper { private static DataBaseHelper dbHelper; Context context; public DataBaseHelper(Context context) { super(co...

zhaihoy的博客 465

龙虾 Skill 技能库|OpenClaw+Hermes 全集成 一键调用所有 AI 技能

龙虾 Skill 技能库、OpenClaw、Hermes Agent、AI 技能集成、本地 AI 自动化、办公工具、数字员工

weixin_42219287的博客 624

Android 数据库框架ormlite 使用

...

hdhhd的博客 2793

智能座舱架构与芯片- (9) 音频篇 上

从A2B收发器衍生出来的简化产品具备各种级别的功能,例如端点从节点(不支持TDM)、简化型主节点(支持较短的电缆和更少的从节点数量),以及简化型端点从节点(支持较短电缆和更少的PDM输入)。例如,AVB中的talker和listener是不同的设备,它们的参考时钟源可能并不相同。传统的车载收音机通过天线接收无线电信号,然后由调谐模块(Tuner)进行信号调谐,信道过滤,信道均衡,多路改善,信号解调等,转为数字信号后再交给DSP进行立体声解码,噪声抑制,弱信号处理,最后从车载音响系统进行播放。

joanna_xiao的博客 4904

别再瞎调参数了!用MATLAB fmincon优化傅里叶级数,为你的机器人设计“完美”激励轨迹

本文详细介绍了如何利用MATLAB的fmincon优化器设计机器人激励轨迹,通过优化傅里叶级数参数,解决传统试错法的低效问题。文章涵盖了目标函数设计、约束条件转化及优化算法选择,帮助工程师实现高精度的系统辨识和动力学参数优化。

weixin_42613501的博客 240

ormlite android jar,Android—Ormlite框架简单的操作数据库

大家在Android项目中或多或少的都会使用数据库,为了提高我们的开发效率,当然少不了数据库ORM框架了,尤其是某些数据库操作特别频繁的app;本篇博客将详细介绍ORMLite的简易用法。下面开始介绍ORMLite的入门用法~1、下载 ORMLite Jar首先去ORMLite官网下载jar包,对于Android为:ormlite-android-5.0.jar 和 ormlite-core-5....

weixin_42619742的博客 386

NY8A053E 例程 之 PWM Ouput

更多关于NY8A053E的相关例程请留言!

倪彬笑阳的博客 2924

ormlite android studio,Android数据库框架-----ORMLite 的基本用法

ORMLite 是一款非要流行的Android平台上的数据库框架,性能优秀,代码简洁;简述: 优点: 1.轻量级;2.使用简单,易上手;3.封装完善;4.文档全面。缺点:1.基于反射,效率较低(本人还没有觉得效率低);2.缺少中文翻译文档准备工作:集成方法:把jar包复制到as的libs文件夹下,并且引用jar包即可之后创建一个类User,并完成相关配置@DatabaseTable(tableNa...

weixin_29043895的博客 271

手把手教你设计MTBF加速寿命试验:从阿伦尼斯模型到卡方计算(含Excel模板)

本文详细介绍了如何设计MTBF加速寿命试验,从阿伦尼斯模型到卡方计算,帮助工程师在合理时间内获得准确的MTBF数据。通过工业电源模块的实例演示,涵盖活化能确定、温度应力设计、样本量计算及数据记录规范,并提供Excel模板实现自动化计算,显著提升测试效率。

weixin_42563415的博客 537

STM32 I²C外设深度解析:时序配置、主从模式与可靠性工程

I²C是一种广泛应用于嵌入式系统的同步串行总线协议,其核心在于精确的时序控制与可靠的电气特性匹配。理解SCL/SDA信号建立/保持时间、上升下降沿约束及硬件滤波机制,是保障通信稳定的基础;STM32通过I2C_TIMINGR寄存器实现对PRESC、SCLH、SCLL、SDADEL和SCLDEL等关键参数的精细调控,直接影响tSU:DAT、tVD:DAT等标准时序合规性;该能力支撑工业级高可靠场景下的主从双向通信、时钟拉伸管理与错误恢复;本文聚焦STM32平台,结合寄存器级配置、状态机行为与实战调试经验,系统

weixin_42146230的博客 87

Android数据库使用(ORMLite)

引言:Android主要有五种重要的存储方式,分别为:文件存储,sharePreference,contentProvider,数据库SQLite和网络存储。 对于数据库SQLite的操作是Android里面数据持久化非常一个环节,而在使用原生系统中的SQLite进行CRUD可能会有点复杂,代码量比较多。因此基于SQLite的数据库操作框架Ormlite和litePal就产生了,这两个框架减轻了开

linshijun33的专栏 896

数据结构课程设计--基于知识图谱的中医食疗数据管理与应用

【代码】数据结构课程设计--基于知识图谱的中医食疗数据管理与应用。

M_inherit的博客 565

Android数据库OrmLite、LitePal、GreenDao的区别

在以前的项目中用过数据储存第三方库,我觉得有必要记下来供大家参考学习下,有可能还有很多人在面对项目中要使用数据存储时还不知道该具体使用哪个三方库,以下介绍三种开源的Android数据库框架,当看了这篇文章后大家可以明确的使用哪个库更适合运用在项目中。 What is ORM? 对象关系映射(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一...

悟-静的博客 2467

WPF实战项目十七(客户端):数据等待加载弹框动画

1、在Common文件夹下新建文件夹Events,新建扩展类UpdateLoadingEvent。2、新建一个静态扩展类DialogExtensions来编写注册和推送等待消息弹框方法。3、在ViewModel中添加实现类NavigationViewModel。5、在View文件夹下新建用户控件ProgressView.xmal。4、在主窗体MainView.xmal中给弹窗界面命名。6、在MainView.xmal.cs中注册消息。

yigu4011的博客 2346

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Android 数据库框架ormlite 使用精要

前言 本篇博客记录一下笔者在实际开发中使用到的一个数据库框架,这个可以让我们快速实现数据库操作,避免频繁手写sql,提高我们的开发效率,减少出错的机率。 ormlite是什么? 首先可以去它的官网看看www.ormlite.com,它的英文全称是Object Relational Mapping,意思是对象关系映射;如果接触过Java EE开发的,一定知道Java Web开发就有一个类似的数

自由人生 278

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Android ORM框架之GreenDAO

为何使用GreenDAO? 存储本地数据往往想到SQLite数据库,但SQLite需要做许多额外的工作,如编写SQL语句与解析查询结果等。所以,适用于 Android 的ORM 框架也就孕育而生了,现在市面上主流的框架有 OrmLite、SugarORM、Active Android、Realm 与 GreenDAO。GreenDAO 是一个将对象映射到 SQLite 数据库中的轻量且快速的 OR

zj 的笔记本 307

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

android支持哪些数据库,Android 中的 SQLite 数据库支持

开袋即食我们大多数人都至少熟悉某些 Core Data 提供给我们的直接可用的持久化特性。然而不幸的是,它们中的很多在 Android 平台上并不是自动化的。 例如,Core Data 抽象出大部分数据库的 SQL 语法和数据库标准,这些语法和标准都是数据库工程师们每天面对的问题。 因为 Android 仅提供一个简单的 SQLite 客户端,所以你扔需要写 SQL 并且确保你的数据库表被适当的标...

weixin_26876073的博客 993

Android知识体系总结之必须掌握的轮子:数据库框架

Android知识体系总结之常用框架之数据库存储框架篇 Android数据库框架 LitePal GreenDao OrmLite DBFlow Realm 自己封装一个?   其实这些库满足我们平时的开发需求足够,但是也有这些库办不到的,因此我们需要自己进行封装,我们可以利用Java高阶知识反射,泛型,注解等等封装一个内存优化良好,使用优雅的库,这要看你的思维啦! 知道这些库的原理以及各...

编程语言是方式,而思维是创造。 1364

Android 数据库框架总结,总有一个适合你!

一:OrmLite 简述: 优点: 1.轻量级;2.使用简单,易上手;3.封装完善;4.文档全面。缺点:1.基于反射,效率较低(本人还没有觉得效率低);2.缺少中文翻译文档 ● jar包 地址:http://ormlite.com/releases/ ● 集成方法:把jar包复制到as的libs文件夹下,并且引用jar包即可 ● 用于学习的相...

weixin_34380781的博客 156

Android ORMLite 框架的入门用法

转载请标明出处:http://blog.youkuaiyun.com/lmj623565791/article/details/39121377 大家在Android项目中或多或少的都会使用数据库,为了提高我们的开发效率,当然少不了数据库ORM框架了,尤其是某些数据库操作特别频繁的app;本篇博客将详细介绍ORMLite的简易用法。 下面开始介绍ORMLite的入门用法~ 1、下载 ORMLite Jar 首...

810364804 501

Android 快速开发系列 ORMLite 框架最佳实践

转载请标明出处:http://blog.youkuaiyun.com/lmj623565791/article/details/39122981,本文出自【张鸿洋的博客】 上一篇已经对ORMLite框架做了简单的介绍:Android ORMLite 框架的入门用法~~本篇将介绍项目可能会使用到的一些用法,也为我们的使用ORMLite框架总结出一个较合理的用法。 通过上一篇的了解,我们使用ORMLite,需要自...

810364804 443

SQLite优化记录 + 资源及时释放以免OOM -- 又被Java忽悠一次

今天很恼火, 大致状况是这样的, 程序直接进入数据库写操作InsertDBActivity中,异步完成80W条数据的插入, 不会OOM; 当我在进入InsertDBActivity之前先来了个用户介绍页(滑动预览6张图片), 然后换了个高清的背景图,够炫,但是悲剧的一幕发生了   在log中可以明显的看到 数据插入到40W多的时候 OOM了! 什么原因呢? 我debug追踪了好久,代码没怎么改动呀

quanjin24k的专栏 2929

GreenDao实现原理

接下来,定义User实体类,使用 GreenDao 的注解进行标注:Java267@Entity1317 }1821 }2225 }2629 }3033 }3437 }3841 }4248 }4952 }53}

VitorLiu的博客 1255

GreenDao的使用

参考博客地址 http://www.open-open.com/lib/view/open1438065400878.htmlgreendao官网 http://greenrobot.org/greendao/1、GreenDao的原理1、DaoMaster: 持有数据库对象(SQLiteDatabase) ,并管理一些DAO类(不是对象) 能够创建和删除数据库表 它的内部类OpenHel

androidxiaogang的博客 1017

greenDao的实现原理

核心: 首先明确一点,sqlite操作都是依靠sql语句的,所以 greendao的所有api及实现都是为这个准则服务的。 变化: 3.0之前需要通过新建GreenDaoGenerator工程生成Java数据对象(实体)和DAO对象,非常的繁琐而且也加大了使用成本。 GreenDao 3.0最大的变化就是采用注解的方式通过编译方式生成Java数据对象和DAO对象。 DatabaseOpenHelper也是实现了SQLiteOpenHelper的一个帮助类,它内部可以获取到两种不同的数...

android开发入门学习 1068
上一篇: Android Studio 常用插件使用
下一篇: Java基础一 Java对象的引用
MatrixGame
博客等级 码龄9年 40粉丝 75原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MatrixGame

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值