您的位置:首页 > 移动开发 > Android开发

Android开源数据库框架——LitePal

2017-04-09 18:36 387 查看
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,接着编辑该文件

<?xml version="1.0" encoding="UTF-8" ?>
<litepal>
<dbname value="BookStore"></dbname>

<version value="2"></version>

<list>

</list>
</litepal>


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

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

<manifest xmlns:android="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">
<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>


接下来学习如何创建和升级数据库

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

下面我们创建一个类Book

public class Bo
114ad
ok
{
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>


这里使用
<mapping>
标签来声明我们要配置的映射模型类,注意一定要使用完整的类名。

现在我们只要进行任意一次数据库的操作,BookStore.db数据库就会自动创建出来,在这里我们为项目添加五个按钮,分别用于之后的各个操作。

<LinearLayout
xmlns:android="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">

<Button
android:id="@+id/create_database"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Create database"/>

<Button
android:id="@+id/add_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add data"/>

<Button
android:id="@+id/update_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Update data"/>

<Button
android:id="@+id/delete_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Delete data"/>

<Button
android:id="@+id/query_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Query data"/>

</LinearLayout>


现在修改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创建成功。



之后查看一下建表语句(放错图了,这里实际上是没有字段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<Book> 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<Book> 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());
}
}
});


下面是效果图



由于在之前的操作中我们删除了另一条数据的记录,因此此时数据库中只剩下一条记录了,这说明我们查询成功。

除了findAll()方法外,LitePal还提供了很多查询API,如DataSupport.findFirst()、findLast()、select()等等,具体可以在书上或者Github中的LitePal开源项目Readme文档中查看。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: