zoukankan      html  css  js  c++  java
  • Litepal【开源数据库ORM框架】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处!

    前言

    好用的数据库框架。

    效果图

     

    代码分析

    本篇主要是整理Litepal的引入和增删改查的简单操作,具体使用请阅读参考资料。

    使用步骤

    一、项目组织结构图

    注意事项:

    1、  导入类文件后需要change包名以及重新import R文件路径

    2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

    二、导入步骤

    (1)引入Litepal框架(在APP的bundle.gradle文件中添加标记的代码)

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 25
        buildToolsVersion "25.0.3"
        defaultConfig {
            applicationId "com.why.project.litepaldemo"
            minSdkVersion 15
            targetSdkVersion 22
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
            exclude group: 'com.android.support', module: 'support-annotations'
        })
        compile 'com.android.support:appcompat-v7:25.3.1'
        testCompile 'junit:junit:4.12'
    
        //Litepal数据库
        compile 'org.litepal.android:core:1.6.1'
    }

    (2)配置litepal.xml(在项目的assets目录中创建litepal.xml文件,并添加以下代码(或者复制Demo中的litepal.xml文件到项目中))

    <?xml version="1.0" encoding="utf-8"?>
    <litepal>
        
        <!-- <dbname>用于设定数据库的名字 -->
        <dbname value="why" ></dbname>
    
        <!-- <version>用于设定数据库的版本号 -->
        <version value="1" ></version>
    
        <!-- <list>用于设定所有的映射模型 -->
        <list>
            <!-- model类,例子如下: -->
            <!-- <mapping class="com.why.model.ClassName"></mapping> -->
        </list>
        
        <!-- 在开发阶段调试的时候,将数据库文件存放在SD卡/sdcard/Android/data/<package name>/files/databases目录下 -->
        <!-- 注意,此功能尽量只在调试的时候使用,把数据库文件存放在SD卡真的很不安全。 -->
        <!-- 在litepal-1.3.2上支持,需要添加权限【实现将数据库保存到默认位置】 -->
        <storage value="external"></storage>
        <!-- 在litepal-1.6.0上支持,需要添加权限、申请运行时权限【实现将数据库保存到SD卡指定位置】 -->
        <!--<storage value="guolin/database" />-->
        
    </litepal>

    备注:多数据库功能请阅读参考资料。

    (3)配置LitePalApplication

    一般项目中都会自定义一个MyApplication,只需要在原来的基础上添加标记的代码即可。

    package com.why.project.litepaldemo;
    
    import android.app.Application;
    import android.database.sqlite.SQLiteDatabase;
    
    import org.litepal.LitePal;
    
    /**
     * Created by HaiyuKing
     * Used
     */
    
    public class MyApplication extends Application{
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            /*=================litepal数据库=====================*/
            LitePal.initialize(this);
            //获取到SQLiteDatabase的实例,创建数据库表
            SQLiteDatabase db = LitePal.getDatabase();
        }
    }

    在AndroidManifest.xml文件中声明权限以及MyApplication【如果想要实现将数据库保存到SD卡指定位置,那么需要申请这些权限,否则不需要申请权限,一般情况下不需要

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.why.project.litepaldemo">
    
        <!-- =================Litepal用到的权限========================== -->
        <!-- 允许程序读取外部存储文件 -->
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
        <!-- 允许程序写入外部存储,如SD卡上写文件 -->
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
        <!-- 在SD卡中创建与删除文件权限 -->
        <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    
        <application
            android:name=".MyApplication"
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
    
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
        </application>
    
    </manifest>

    (4)添加运行时权限的处理(本demo中采用的是修改targetSDKVersion=22)【如果想要实现将数据库保存到SD卡指定位置,那么需要申请这些权限,否则不需要申请权限,一般情况下不需要】

    三、使用方法

    (1)创建表

    • 新建model类并继承DataSupport(拥有了进行CRUD操作的能力)
    package com.why.project.litepaldemo.model;
    
    import org.litepal.annotation.Column;
    import org.litepal.crud.DataSupport;
    
    /**
     * Created by HaiyuKing
     * Used 登录账号数据库表
     */
    
    public class LoginUserModel extends DataSupport{
    
        @Column(nullable = false)
        private String userName;//不能为空
    
        @Column(nullable = false)
        private String passWord;
    
        @Column(unique = true)
        private String userId;//不可重复
    
        private String tel;
    
        public String getPassWord() {
            return passWord;
        }
    
        public void setPassWord(String passWord) {
            this.passWord = passWord;
        }
    
        public String getTel() {
            return tel;
        }
    
        public void setTel(String tel) {
            this.tel = tel;
        }
    
        public String getUserId() {
            return userId;
        }
    
        public void setUserId(String userId) {
            this.userId = userId;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    }

    备注:

    一、字段命名应避免数据库关键字:比如id、index、text等

    二、

    @Column(nullable = false) :不能为空

    @Column(unique = true) : 不可重复

    @Column(ignore = true) : 不映射到数据库表中

    三、主键ID自动生成;

    四、支持存储的数据类型有:int、long、short、float、double、boolean、char、String、Date九种,1.3.1版本中引入了第十种数据类型:byte[]。

    五、从1.4.0版本开始支持集数数据的存储了。除了支持List<String>集合之外,还有List<Integer>、List<Boolean>、List<Long>、List<Float>、List<Double>、List<Character>这几种类型的集合也是支持的。

    六、不论字段名大小写,数据库表中的字段均为小写。

    • 将该model类配置到映射列表(litepal.xml)当中
    <?xml version="1.0" encoding="utf-8"?>
    <litepal>
        
        <!-- <dbname>用于设定数据库的名字 -->
        <dbname value="why" ></dbname>
    
        <!-- <version>用于设定数据库的版本号 -->
        <version value="1" ></version>
    
        <!-- <list>用于设定所有的映射模型 -->
        <list>
            <!-- model类,例子如下: -->
            <!-- <mapping class="com.why.model.ClassName"></mapping> -->
            <mapping class="com.why.project.litepaldemo.model.LoginUserModel"></mapping>
        </list>
        
        <!-- 在开发阶段调试的时候,将数据库文件存放在SD卡/sdcard/Android/data/<package name>/files/databases目录下 -->
        <!-- 注意,此功能尽量只在调试的时候使用,把数据库文件存放在SD卡真的很不安全。 -->
        <!-- 在litepal-1.3.2上支持,需要添加权限【实现将数据库保存到默认位置】 -->
        <storage value="external"></storage>
        <!-- 在litepal-1.6.0上支持,需要添加权限、申请运行时权限【实现将数据库保存到SD卡指定位置】 -->
        <!--<storage value="guolin/database" />-->
        
    </litepal>
    • 执行SQLiteDatabase db = Connector.getDatabase();(只要你对数据库有任何的操作,news表就会被自动创建出来)

    因为写在MyApplication中了,也就是说APP启动的时候就执行创建表的操作了。当然了,可以根据实际需求写在任何一个位置。

     数据库表在SD卡中

    (2)查看数据库表

    使用sqlitebrowser软件查看数据库表

    下载地址:链接:http://pan.baidu.com/s/1dER1Kat 密码:64ww

    使用方法:

    (3)升级表

    如果已有的表model类中新增、减少、修改字段或者新建表的model类,都需要升级表。

    • 新建model类并继承DataSupport

      如果升级的是已有表,则添加、删除、修改已有表的字段。

    • 在映射列表中新增model类,并将版本号+1【如果升级的是已有表,则只将版本号+1】
    <version value="2" ></version>
    • 执行SQLiteDatabase db = Connector.getDatabase();

    (4)建立表关联

    http://blog.csdn.net/guolin_blog/article/details/39207945

    (5)存储数据

    • save()
                    LoginUserModel model = new LoginUserModel();
                    model.setUserId("00001");
                    model.setUserName("用户名1");
                    model.setPassWord("密码1");
                    model.setTel("18600001");
    
                    model.save();

    • saveAsync()

    异步保存。

                    LoginUserModel model = new LoginUserModel();
                    model.setUserId("00001");
                    model.setUserName("用户名1");
                    model.setPassWord("密码1");
                    model.setTel("18600001");
                    
                    model.saveAsync().listen(new SaveCallback() {
                        @Override
                        public void onFinish(boolean success) {
    
                        }
                    });
    • saveThrows()

    如果希望存储失败的话就抛出异常,而不是返回一个false,那就可以使用saveThrows()方法来代替。使用saveThrows()方法来存储数据,一旦存储失败就会抛出一个DataSupportException异常,我们可以通过对这个异常进行捕获来处理存储失败的情况。

                    LoginUserModel model = new LoginUserModel();
                    model.setUserId("00001");
                    model.setUserName("用户名1");
                    model.setPassWord("密码1");
                    model.setTel("18600001");
    
                    model.saveThrows();
    • saveOrUpdate

    处理不存在就存储,已存在就更新的需求

                    LoginUserModel model = new LoginUserModel();
                    model.setUserId("00001");
                    model.setUserName("用户名1_");
                    model.setPassWord("密码1_");
                    model.setTel("18600001");
    
                    model.saveOrUpdate("userid=?",model.getUserId());

    • saveOrUpdateAsync

    异步处理不存在就存储,已存在就更新的需求

                    LoginUserModel model = new LoginUserModel();
                    model.setUserId("00001");
                    model.setUserName("用户名1_");
                    model.setPassWord("密码1_");
                    model.setTel("18600001");
    
                    model.saveOrUpdateAsync("userid=?",model.getUserId())
                            .listen(new SaveCallback() {
                                @Override
                                public void onFinish(boolean success) {
    
                                }
                            });
    •  saveAll

    专门用于存储集合数据的。

                    LoginUserModel model2 = new LoginUserModel();
                    model2.setUserId("00002");
                    model2.setUserName("用户名2");
                    model2.setPassWord("密码2");
                    model2.setTel("18600002");
    
                    LoginUserModel model3 = new LoginUserModel();
                    model3.setUserId("00003");
                    model3.setUserName("用户名3");
                    model3.setPassWord("密码3");
                    model3.setTel("18600003");
    
                    List<LoginUserModel> loginList = new ArrayList<LoginUserModel>();
                    loginList.add(model2);
                    loginList.add(model3);
    
                    DataSupport.saveAll(loginList);

     

    • saveAllAsync

     专门用于异步存储集合数据的。

                    LoginUserModel model2 = new LoginUserModel();
                    model2.setUserId("00002");
                    model2.setUserName("用户名2");
                    model2.setPassWord("密码2");
                    model2.setTel("18600002");
    
                    LoginUserModel model3 = new LoginUserModel();
                    model3.setUserId("00003");
                    model3.setUserName("用户名3");
                    model3.setPassWord("密码3");
                    model3.setTel("18600003");
    
                    List<LoginUserModel> loginList = new ArrayList<LoginUserModel>();
                    loginList.add(model2);
                    loginList.add(model3);
    
                    DataSupport.saveAllAsync(loginList).listen(new SaveCallback() {
                        @Override
                        public void onFinish(boolean success) {
                            
                        }
                    });

    (6)修改数据

    • update()

    根据主键id值(litepal数据库自动生成的ID值,从1开始)修改数据。

                    ContentValues values = new ContentValues();
                    values.put("username","用户名2_");
                    int updateNum = DataSupport.update(LoginUserModel.class,values,2);//修改id值等于2的那一行数据
                    Log.w(TAG,"{btn_update}updateNum="+updateNum);
    • updateAll()

    根据某个查询条件进行修改数据。

                    ContentValues values = new ContentValues();
                    values.put("username","用户名3_");
                    int updateAllNum = DataSupport.updateAll(LoginUserModel.class,values,"userid=?","00003");//修改userid=00003的那一行数据
                    Log.w(TAG,"{btn_update}updateAllNum="+updateAllNum);

    (7)查询数据

    普通查询
    • findFirst()

    取出表中的第一条数据。

                    LoginUserModel firstModel = DataSupport.findFirst(LoginUserModel.class);
                    Log.w(TAG,"userId = " + firstModel.getUserId());
    • findLast()

    取出表中的最后一条数据。

                    LoginUserModel lastModel = DataSupport.findLast(LoginUserModel.class);
                    Log.w(TAG,"userId = " + lastModel.getUserId());
    • findAll()

    查询所有数据。

                    List<LoginUserModel> findAllList = DataSupport.findAll(LoginUserModel.class);
                    if(findAllList.size() > 0){
                        for(LoginUserModel model : findAllList){
                            Log.w(TAG,"model.getUserId()" + model.getUserId());
                        }
                    }
    连缀查询
    • where()
                    List<LoginUserModel> findWhereList = DataSupport.where("userid=?","00003").find(LoginUserModel.class);
                    if(findWhereList.size() > 0){
                        for(LoginUserModel model : findWhereList){
                            Log.w(TAG,"model.getUserId()" + model.getUserId());
                        }
                    }
    • select()
                    List<LoginUserModel> findSelectList = DataSupport.select("userid","username").where("userid=?","00003").find(LoginUserModel.class);
                    if(findSelectList.size() > 0){
                        for(LoginUserModel model : findSelectList){
                            Log.w(TAG,"model.getUserId()" + model.getUserId());
                        }
                    }
    • order()

    order()方法中接收一个字符串参数,用于指定查询出的结果按照哪一列进行排序,asc表示正序排序,desc表示倒序排序。

                    List<LoginUserModel> findOrderList = DataSupport.select("userid","username")
                            .where("userid=?","00003")
                            .order("userid desc")
                            .find(LoginUserModel.class);
                    if(findOrderList.size() > 0){
                        for(LoginUserModel model : findOrderList){
                            Log.w(TAG,"model.getUserId()" + model.getUserId());
                        }
                    }
    • limit()

    这个方法接收一个整型参数,用于指定查询前几条数据。

                    List<LoginUserModel> findlimitList = DataSupport.select("userid","username")
                            .where("userid=?","00003")
                            .limit(10)
                            .find(LoginUserModel.class);
                    if(findlimitList.size() > 0){
                        for(LoginUserModel model : findlimitList){
                            Log.w(TAG,"model.getUserId()" + model.getUserId());
                        }
                    }
    • offset()

    用于指定查询结果的偏移量。

                    List<LoginUserModel> findoffsetList = DataSupport.select("userid","username")
                            .where("userid=?","00003")
                            .limit(10)
                            .offset(10)
                            .find(LoginUserModel.class);
                    if(findoffsetList.size() > 0){
                        for(LoginUserModel model : findoffsetList){
                            Log.w(TAG,"model.getUserId()" + model.getUserId());
                        }
                    }
    • findFirst()【连缀查询中查询结果的第一行数据】
                    LoginUserModel findWhereFisrt = DataSupport.where("userid=?","00003").findFirst(LoginUserModel.class);
                    Log.w(TAG,"findWhereFisrt.getUserId()" + findWhereFisrt.getUserId());
    • findLast()【连缀查询中查询结果的最后一行数据】
                    LoginUserModel findWhereLast = DataSupport.where("userid=?","00003").findLast(LoginUserModel.class);
                    Log.w(TAG,"findWhereFisrt.getUserId()" + findWhereLast.getUserId());
    • isExist()
                    boolean isExist = DataSupport.isExist(LoginUserModel.class,"userid=?","00003");
                    Log.w(TAG,"isExist=" + isExist);
    激进查询

    http://blog.csdn.net/guolin_blog/article/details/40153833

    原生查询

    http://blog.csdn.net/guolin_blog/article/details/40153833

    (8)删除数据

    • delete()

    需要注意的是,这不仅仅会将news表中的记录删除,同时还会将其它表中以这条记录作为外键的数据一起删除掉,因为外键既然不存在了,那么这么数据也就没有保留的意义了。

                    int DelNum = DataSupport.delete(LoginUserModel.class,1);//删除ID值等于1的那一行数据
                    Log.w(TAG,"DelNum=" + DelNum);
    • deleteAll()
                    int delAllNum = DataSupport.deleteAll(LoginUserModel.class,"userid=?","00002");
                    Log.w(TAG,"delAllNum=" + delAllNum);

    在不指定约束条件的情况下,deleteAll()方法就会删除表中所有的数据了。

                    int delAllNum = DataSupport.deleteAll(LoginUserModel.class);
                    Log.w(TAG,"delAllNum=" + delAllNum);

    (9)聚合函数

    http://blog.csdn.net/guolin_blog/article/details/40614197

    (10)加密功能

    https://mp.weixin.qq.com/s/TSp36cnKLxUmAHjT86UCrQ

    混淆配置

    #=====================litpal框架混淆=====================
    -dontwarn org.litepal.*
    -keep class org.litepal.**{*;}
    -keep enum org.litepal.**
    -keep interface org.litepal.**{*;}
    -keep public class * extends org.litepal.**
    -keepattributes *Annotation*
    -keepclassmembers enum * {
        public static **[] values();
        public static ** valueOf(java.lang.String);
    }
    -keepclassmembers class * extends org.litepal.crud.DataSupport{*;}

    参考资料

    Android数据库高手秘籍(二)——创建表和LitePal的基本用法

    gitHub地址

    我为什么能将效率提升了800%

    喜大普奔,LitePal 1.3.0 版本发布!

    LitePal 1.3.1发布了,从此支持图片存储!

    你们要的多数据库功能终于来了

    LitePal 1.5.0版本发布,你想要的都在这里

    LitePal 1.6.0版本来袭,数据加解密功能保障你的应用数据安全

    项目demo下载地址

     https://github.com/haiyuKing/LitepalDemo

  • 相关阅读:
    Servlet_note
    J2SE学习历程
    ASP.NET Core搭建多层网站架构【0-前言】
    使用oh-my-posh美化powershell
    Linux使用整理
    Ubuntu18.04国内源安装MySQL8.0
    Visual Studio Code 个人配置备份
    ASP.NET Core搭建多层网站架构【15-扩展之使用Obfuscar混淆加密保护代码】
    ASP.NET Core搭建多层网站架构【14-扩展之部署到IIS】
    ASP.NET Core搭建多层网站架构【13-扩展之支持全球化和本地化多语言】
  • 原文地址:https://www.cnblogs.com/whycxb/p/7637402.html
Copyright © 2011-2022 走看看