Android开源数据库框架——LitePal

LitePal是一款开源的Android数据库框架,它采用了对象关系映射(ORM)的模式,并且封装了我们常用的数据库功能,使得我们不用编写SQL语句就可以完成各种建表和增删改查的操作。但其中最强大的功能是ORM——对象关系映射,这个映射关系使得Java中的类和数据库中的表一一对应,让Java开发者能够更简单的操作数据库。

以前如果要使用一个开源库,我们需要下载这个库的jar包然后再集成到我们的项目当中;但是现在不需要这么麻烦了,如今大多数的开源项目都会将版本提交到jcenter上,因此我们只需要在app/build.gradle文件中声明该开源库的引用即可,AndroidStudio会自动从jcenter下载这个开源库的jar包并自动集成到项目中。

下面我们学习如何使用LitePal,首先新建一个项目LitePalTest。

使用LitePal的第一步,就是编辑app/build.gradle文件,在dependencies闭包中添加如下内容,其中LitePal的最新版本号可以去https://github.com/LitePalFramework/LitePal查看。

compile 'org.litepal.android:core:1.5.1'

这样我们就把LitePal成功导入到当前项目中了,接下来需要配置litepal.xml文件,在main目录下创建一个新的文件夹并命名为assets,在该文件夹下创建一个File(注意不是Android Resource File)并命名为litepal.xml,接着编辑该文件


<litepal>
    <dbname value="BookStore">dbname>

    <version value="2">version>

    <list>

    list>
litepal>

其中标签指定数据库名称,标签指定数据库版本号,标签指定所有的映射模型。

最后还需要修改Manifest文件,配置LitePalApplication,这里我们将项目的application配置为org.litepal.LitePalApplication,这样才能让LitePal所有功能都可以正常工作。

"http://schemas.android.com/apk/res/android"
          package="com.studio.litepaltest">

    <application
        android:name="org.litepal.LitePalApplication"--添加这行代码-->
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        name=".MainActivity">
            
                name="android.intent.action.MAIN"/>

                name="android.intent.category.LAUNCHER"/>
            
        
    application>

接下来学习如何创建和升级数据库
首先说说什么是对象关系映射(ORM)。简单点说,我们使用的Java语言是面向对象的语言,而使用的数据库SQLite是关系型数据库,那么将面向对象的语言和面向关系的数据库之间建立一种映射关系,这就是对象关系映射。例如Java中的一个类Book,映射在SQLite中就是一个数据表Book,类Book中的数据成员就是数据表Book中对应的字段。

下面我们创建一个类Book

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

    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;
    }

}

要想成功在数据库中映射出数据表Book,我们还需要将Book类添加到映射模型列表中,修改litepal.xml中的代码

    <list>
        <mapping class="com.studio.litepaltest.Book">mapping>
    list>

这里使用标签来声明我们要配置的映射模型类,注意一定要使用完整的类名。
现在我们只要进行任意一次数据库的操作,BookStore.db数据库就会自动创建出来,在这里我们为项目添加五个按钮,分别用于之后的各个操作。

"http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.studio.litepaltest.MainActivity">

    

现在修改MainActivity代码

public class MainActivity extends AppCompatActivity
{

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button createDatabase = (Button) findViewById(R.id.create_database);
        createDatabase.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                LitePal.getDatabase();
            }
        });
    }
}

其中,调用LitePal.getDatabase()方法就是一次最简单的数据库操作,只要点击一下按钮Create database,数据库就会创建完成。
执行程序,在adb shell中查看效果,发现数据库BookStore.db创建成功。
Android开源数据库框架——LitePal_第1张图片
之后查看一下建表语句(放错图了,这里实际上是没有字段press和表category的,就假装是对的吧)
这里写图片描述
发现Book类中对应的数据成员都成功映射成了Book表中的字段,需要注意的是Book类中的成员id自动被映射成了Book表的主键。

接着学习如何升级数据库
在之前学习SQLiteOpenHelper的时候我们发现,要升级数据库我们需要把之前的数据表drop掉,然后在onUpgrade()中重新创建,这是一个非常严重的问题,这会导致数据丢失,虽然我们可以通过一些复杂的逻辑解决这个问题,但是这样维护成本非常高。
但是在LitePal中就不存在这个问题,我们可以直接更新,不用担心之前的数据丢失。
比如我们想向表Book中添加一个press列,那么我们直接修改Book中的代码,添加一个press字段并完成getter/setter方法

public class Book extends DataSupport
{
    private int id;
    private String author;
    private double price;
    private int pages;
    private String name;
    private String 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;
    }

    public String getPress()
    {
        return press;
    }

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

此外,我们还想再添加一张Category表,那么我们再新建一个Category类

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文件中将版本号加1就可以了,当然这里我们还添加了一个Category类,因此也需要将它添加到映射模型列表中

<litepal>
    <dbname value="BookStore">dbname>

    <version value="2">version>

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

现在重新运行程序,点击Create database按钮,再查看一下最新的建表语句,结果如图
这里写图片描述
发现更新成功,字段press和表category都已经添加到了数据库中,并且之前的数据依然保留。

下面学习如何利用LitePal添加数据库
使用LitePal添加数据,我们只需要创建出模型类的实例,将所有要存放的数据设置好,最后调用一下save()方法就可以了。但是需要注意的是,LitePal在进行表管理操作时不需要模型类有任何的继承结构,但是进行CRUD操作时就不可以了,必须要让模型类继承DataSupport类才行,因此我们首先需要让Book类继承DataSupport类。

完成继承后,修改MainActivity代码,在原有代码后添加如下代码

        /*添加数据*/
        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("The Da Vinci Code");
                book.setAuthor("Dan Brown");
                book.setPages(454);
                book.setPrice(16.99);
                book.setPress("Unknown");
                //保存数据
                book.save();
            }
        });

这样一个数据就成功存储了,查看效果
这里写图片描述

下面学习如何使用LitePal更新数据
首先,最简单的一种更新方式就是就是对已经存储的对象重新设值,再调用save()方法即可。

        /*更新数据*/
        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("The Lost Symbol");
                book.setAuthor("Dan Brown");
                book.setPages(510);
                book.setPrice(19.95);
                book.setPress("Unknown");
                book.save();
                book.setPrice(10.99);
                book.save();
            }
        });

效果图,这里我们发现价格是10.99而不是19.95,原因就是第二次save()使得原有数据发生了更新。
这里写图片描述

这种最简单的更新方式只能对已存储的对象进行操作,限制性比较大,接下来我们学习另外一种比较灵活的更新方式,修改上述代码

//更新数据
        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(14.95);
                book.setPress("Anchor");
                book.updateAll("name = ? and author = ?","The Lost Symbol","Dan Brown");
            }
        });

这里我们首先创建一个新的Book实例,然后设置要更新的值,最后调用updateAll()方法执行更新操作。updateAll方法中可以指定一个条件约束,如果不指定条件语句的话,就表示更新所有数据,这里我们指定所有书名是The Lost Symbol并且作者是Dan Brown的书介个更新为14.95,出版社更新为Anchor。
效果图,更新成功!
这里写图片描述
不过在使用updateAll()方法时,有一个非常重要的知识点,就是当我们想把一个字段的值更新为默认值时,不能通过set来设置数据,只能通过setToDefault()方法,传入相应的列名即可。

Book book=new Book();
book.setToDefault("pages");
book.updateAll();

这样就表示将所有书的页数都更新为0(int的默认值为0),而如果我们使用

book.setPages(0);

就会报错。

下面学习如何删除数据
删除数据的方式依然有两种,第一种很简单,就是直接调用实例对象的delete()方法即可,如book.delete(),这里就不进行演示了。

下面直接来看第二种

        //删除数据
        Button deleteData= (Button) findViewById(R.id.delete_data);
        deleteData.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                DataSupport.deleteAll(Book.class,"price < ?","15");
            }
        });

这里调用了 DataSupport.deleteAll()方法来删除数据,第一个参数指定删除哪张表中的数据,后面的参数指定约束条件,不指定条件约束则默认删除所有数据,这里的意思是删除Book表中价格小于15的书的数据。
效果如下,删除成功!
这里写图片描述

最后是查询数据
如果我们想查询一个表中的所有数据,使用的代码非常简单

List books=DataSupport.findAll(Book.class);

findAll()方法返回的就是参数指定的类的一个List集合。
下面实践一下看看效果

        /*查询数据*/
        Button queryData= (Button) findViewById(R.id.query_data);
        queryData.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                List books=DataSupport.findAll(Book.class);
                for (Book book:books)
                {
                    Log.d("MainActivity","book name is "+book.getName());
                    Log.d("MainActivity","book author is "+book.getAuthor());
                    Log.d("MainActivity","book pages is "+book.getPages());
                    Log.d("MainActivity","book price is "+book.getPrice());
                    Log.d("MainActivity","book press is "+book.getPress());
                }
            }
        });

下面是效果图
Android开源数据库框架——LitePal_第2张图片
由于在之前的操作中我们删除了另一条数据的记录,因此此时数据库中只剩下一条记录了,这说明我们查询成功。
除了findAll()方法外,LitePal还提供了很多查询API,如DataSupport.findFirst()、findLast()、select()等等,具体可以在书上或者Github中的LitePal开源项目Readme文档中查看。

你可能感兴趣的:(Android)