【Android】18.0 SQLite数据库——LitePal的使用及SQLite数据库怎么查看

1.0 随着android编程的版本和工具的不断更新,一些学习内容出现失效、弃用现象。写这个同时也是给自己做笔记。
2.0 Android系统内置数据库,SQLite轻量级的关系型数据库,当然,使用起来其实很麻烦,还需要熟练使用SQL语句。
3.0 开源让Android开发者收益良多,导致GitHub上有成百上千的优秀Android开源项目,当我们使用开源库LitePal时,将会特别感受到SQLite数据库使用的容易性。
4.0 LitePal项目主页当然有详细的使用文档,地址是:GitHub - LitePalFramework/LitePal: 一个Android库,使开发人员非常容易使用sqlite数据库
5.0 配置LitePal。

编辑app/build.gradle文件,在dependencies闭包中添加如下内容:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    implementation 'org.litepal.android:java:3.0.0'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

添加这行代码中,“org.litepal.android:java:”是固定的,后面的版本号可以去 LitePal项目主页上查看。

6.0 新建一个项目,我的目录结构如下:
2019-02-18_212302.png

当然这里也不要忘了,更新下编程环境,点这个:


2019-02-18_212628.png
7.0 litepal.xml内容如下:
<?xml version="1.0" encoding="utf-8"?>
<litepal>
    <dbname value="BookStore"></dbname>
    <version value="2"></version>

    <list>
        <mapping class="com.example.litepaltest.Book"></mapping>
        <mapping class="com.example.litepaltest.Category"></mapping>
    </list>
</litepal>

dbname 标签用于指定数据库名
version 标签用于指定数据库版本号,这里我因为已经玩了几轮了,已经更新到2。
mapping 标签里面都是全路径名称下的具体的表。

8.0 最后还需要配置下LitePalApplication,修改AndroidManifest.xml中的代码,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.litepaltest">

    <application
        android:name="org.litepal.LitePalApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        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>

主要是application标签下增加android:name="org.litepal.LitePalApplication",其他都是自动生成的。
这样LitePal的所有功能都能正常工作了,LitePal配置工作完全结束。

9.0 LitePal最大的好处,就在于她是相当于面向对象的,严谨地说,叫做采用的是对象关系映射(ORM)的模式。

这样可以用面向对象的思维来操作数据库,而不用再和SQL语句打交道,并且可以直接指定好了数据的数据类型。

例如在这个项目中,再定义一个Book类,代码如下:

package com.example.litepaltest;


import org.litepal.crud.LitePalSupport;

public class Book extends LitePalSupport {
    private int id;
    private String author;
    private double price;
    private int pages;
    private String name;


    private String press;

    public String getPress() {
        return press;
    }

    public void setPress(String press) {
        this.press = press;
    }

    public int getId() {
        return id;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

    public String getName() {
        return name;
    }

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


}

可见这是一个典型的Java bean。相当于对应数据库中的Book表。

10.0 由于前面已经描述了litepal.xml中的代码,事实上,坐好Book类,还需要在这个文件中用mapping标签来声明要配置的映射模型类。这里就不再贴代码了。
11.0修改MainActivity.java中的代码,创建数据库:
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button createDatebase = (Button) findViewById(R.id.create_database);
        createDatebase.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LitePal.getDatabase();
            }
        });

这里用了LitePal.getDatabase();创建数据库,运行,可以点击那个Button控件(最后一次性贴activity_main.xml的代码,里面到时候会配置4个按钮控件),数据库创建成功。

12.0 怎么可以查看数据库是否真的创建好了,在我的参考书里面是通过adb.exe,在命令窗口,通过命令行查看,但是Android6.0以后的版本的模拟器,这个方法根本进不去数据库。

所以我用的第二种方法。
12.1 首先你得装一个Navicat Premium,数据库可视化软件。
我的是Navicat Premium 12。

12.2 然后运行项目后,点击按钮,创建数据库。然后打开Android studio,在右下角可以看到Device File Explorer,接下来的操作如图所示:


2019-02-19_152423.png
2019-02-19_152804.png
2019-02-19_153356.png

当然,如果你找不到Device File Explorer,可以到View→Tool Windows→Device File Explorer:


2019-02-19_153021.png

如果这样都没有的话,那就凉凉了……

12.3 接下来打开Navicat Premium ,点击SQLite,操作如图:


2019-02-19_153637.png

选择数据库文件,


2019-02-19_153711.png

找到保存的目录,选择目录文件,打开
2019-02-19_153844.png
2019-02-19_154119.png

这样,就可以查看到相关的内容了(我的因为多写了别的代码,导致里面有数据)


2019-02-19_154310.png
13.0 常说的增删查改。首先是想添加一个出版社,直接修改Book代码,添加一个press字段即可,上面的代码,已经是添加完毕的。
14.0 如果还想再添加一张Category表,那么只需要添加一个Category类即可:

Category.java

package com.example.litepaltest;

public class Category {
    private int id;
    private String categoryName;
    private int categoryCode;

    public int getId() {
        return id;
    }

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

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public int getCategoryCode() {
        return categoryCode;
    }

    public void setCategoryCode(int categoryCode) {
        this.categoryCode = categoryCode;
    }
}

但别忘了在litepal.xml中增加一个mapping(在上面贴的完整代码中已添加好):

<mapping class="com.example.litepaltest.Category"></mapping>
15.0 添加数据,LitePal进行表管理操作时不需要模型类有任何的继承结构,但是进行CRUD操作时就不行,必须继承LitePalSupport类才行(之前是继承DataSupport类,现在已经被弃用)

上面可以看到我们的Book类已经被我加上了继承结构,但在创建表时,可以不用该继承。

添加数据,将数据设置好,调用下save()方法即可,只需要修改下MainActivity.java中的代码(当然,这里又增加了一个Button按钮):

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...
       Button addData = (Button) findViewById(R.id.add_data);
              addData.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      Book book = new Book();
                      book.setName("中国古代历史");
                      book.setAuthor("睡醒著");
                      book.setPages(454);
                      book.setPrice(16.96);
                      book.setPress("Unknow");
                     book.save();
                  }
              });
      }
}
16.0更新数据,如下:

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...
      Button updateData = (Button) findViewById(R.id.update_data);
        updateData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    Book book = new Book();
                    book.setName("大亨小传");
                    book.setAuthor("java著");
                    book.setPages(329);
                    book.setPrice(21.96);
                    book.setPress("Unknow");
                    book.save();
                    book.setPrice(51.96);
                    book.save();
                  }
              });
      }
}

当然,还可以更加灵巧的更新数据:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...
      Button updateData = (Button) findViewById(R.id.update_data);
        updateData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Book book = new Book();
                book.setPrice(33.96);
                book.setPress("Anchor");
                book.updateAll("name= ? and author = ?","中国古代历史","睡醒著");
                  }
              });
      }
}

上面updateAll()方法的意思是匹配Book表中,所有名字叫“中国古代历史“”,而且作者是“睡醒著”的所有数据,将他们的价格和出版社给改了。

还可以将某个数据恢复成系统默认值:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...
      Button updateData = (Button) findViewById(R.id.update_data);
        updateData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //                下面三句代码的意思是:把所有书的页数设置为默认值0
                Book book = new Book();
                book.setToDefault("pages");
                book.updateAll();
                  }
              });
      }
}
17.0 删除数据,如下:

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...
      Button deleteData = (Button) findViewById(R.id.delete_data);
        deleteData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                这里之前的DataSupport被弃用,取而代之的是LitePal
                LitePal.deleteAll(Book.class,"price < ?","23");
            }
        });
      }
}

上句话的意思是,删除Book表中所有价格小于23的书的数据。

18.0 查询数据,很简单:

在Button控件监控的基础上,直接增加如下代码:
18.1 查询Book表中的所有数据:

List<Book> book = LitePal.findAll(Book.class);

18.2 查询Book表中的第一条数据:

Book firstBook = LitePal.findFirst(Book.class);

18.3 查询Book表中的最后一条数据:

Book lastBook = LitePal.findLast(Book.class);

18.4 只查询Book表中的name和author这两列数据(对应SQL中的select关键字):

List<Book> book = LitePal.select("name","author").find(Book.class);

18.5 只查询Book表中的页数大于400的数据(对应SQL中的where关键字):

List<Book> book = LitePal.where("pages > ?","400").find(Book.class);

18.6 查询Book表,将查询结果按照书价从高到低排序(对应SQL中的order by关键字):

List<Book> book = LitePal.order("price desc ").find(Book.class);

其中“desc”表示降序排序,不写或者"asc"表示升序排序

18.7 查询Book表中的前3条数据:

List<Book> book = LitePal.limit(3).find(Book.class);

18.8 查询Book表中的第2条、第3条、第4条数据:

List<Book> book = LitePal.limit(3).offset(1).find(Book.class);

limit(3)查询的是前3条数据(第1、2、3条),再加一个offset(1)进行位置的偏移,意味着查询第2、3、4条数据了,这两个方法相结合对应SQL语句中的limit关键字。

18.9 划重点的来了,可以把select()、where()、order()、limit()、offset()五个方法任意组合,以完成一个复杂的查询操作,比如查询Book表中第11-20条满足页数大于400这个条件的name、author和pages这3列数据,并将查询结果按照页数的升序排列:

List<Book> book = LitePal.selcect("name","author","pages")
                                           .where("pages > ?","400")
                                           .order(pages)
                                           .limit(10)
                                           .offset(10)
                                           .find(Book.class);

18.10 最后,如果LitePal这都满足不了你穷凶极恶的需求,那么它仍然支持使用原生的SQL来查询:

Cursor c = LitePal.findBySQL("select * from Book where pages > ? and price < ?","400","20");

当然,这样数据需要取出来的话,就得通过Cursor的各种get方法了。

END

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容