场景
Room
Room是Google官方提供的数据库ORM框架,使用起来非常方便。Room在SQLite上提供了一个抽象层,以便在利用SQLite的全部功能的同时能更加流畅的访问数据库。
Room中三个主要组件:
Database:该组件用来创建一个database holder。注解定义实体的列表,类的内容定义从数据库中获取数据的对象(DAO)。它也是底层连接的主要入口。这个被注解的类是一个继承RoomDatabase的抽象类。在运行时,可以通过调用Room.databaseBuilder() 或者 Room.inMemoryDatabaseBuilder()来得到它的实例。
Entity:该组件的一个示例表示数据库的一行数据,对于每个Entity类来说,都会有对应的table被创建。想要这些Entity被创建,就需要卸载上面的Database的注解参属entities列表中,默认Entity中的所有字段都会来创建表,除非该字段上加上@Ignore注解。
Dao:该组件用来表述具有Data Access Object(DAO)功能的类或者接口,DAO类时Room的重要组件,负责定义查询(添加或者删除等)数据库的方法。使用@Database注解的类中必须定义一个不带参数的抽象方法,这个方法返回使用@Dao注解的类,返回类型为@Dao注解过的类的抽象方法Room会在编译时生成这个类的实现。
Room 不同组件之间的关系
官方Room教程
https://developer.android.google.cn/training/data-storage/room
注:
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
打开Android Studio 新建一个项目,勾选上下面的User legacy android support libraries
然后点击Finish,然后打开build.grdle,添加项目依赖
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
添加位置
下面开始按照官方文档构建三个组件。
首先是数据库组件,按照其文档说明
以及官方推荐的使用单例设计模式
在包下新建继承自RoomDatabase的类,这里叫AppDatebase
package com.badao.roomstudy.room;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import com.badao.roomstudy.MyApplication;
@Database(entities = {User.class}, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE;
public static AppDatabase getInstance() {
if (INSTANCE == null) {
synchronized (AppDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(MyApplication.context, AppDatabase.class, "badao.db")
.allowMainThreadQueries()
.build();
}
}
}
return INSTANCE;
}
public abstract UserDao userDao();
}
因为此类作为工具类的方式存在,在进行构建数据库时需要获取Context对象。
所以另外再新建一个继承自Application的类MyApplication
package com.badao.roomstudy;
import android.app.Application;
import android.content.Context;
public class MyApplication extends Application {
public static Context context;
@Override
public void onCreate() {
super.onCreate();
context = this;
}
}
然后在AndroidMainifest.xml中添加
<application
android:name=".MyApplication"
在上面的AppDarabase中用到了User这个类,就是Entity组件
新建User.java
package com.badao.roomstudy.room;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity
public class User {
@PrimaryKey
public int uid;
@ColumnInfo(name = "first_name")
public String firstName;
@ColumnInfo(name = "last_name")
public String lastName;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
有三个属性:uid使用PrimaryKey注解作为主键,后面是姓和名两个属性,使用@ColumnInfo(name = "first_name")映射数据库中的列。
然后再新建Dao层组件UserDao接口
package com.badao.roomstudy.room;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import java.util.List;
@Dao
public interface UserDao {
@Query("SELECT * FROM user")
List<User> getAll();
@Query("SELECT * FROM user WHERE uid IN (:userIds)")
List<User> loadAllByIds(int[] userIds);
@Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
"last_name LIKE :last LIMIT 1")
User findByName(String first, String last);
@Query("SELECT * FROM user WHERE last_name LIKE :last LIMIT 1")
User findByLastName(String last);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAll(User... users);
@Delete
void delete(User user);
}
并且创建了几个方法。
然后在布局文件中添加几个按钮
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加数据"
android:onClick="insertData"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询所有数据"
android:onClick="getAll"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="根据名字模糊查询"
android:onClick="findByLastName"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="删除"
android:onClick="delete"
/>
</LinearLayout>
然后在对应的Activity中
package com.badao.roomstudy;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.badao.roomstudy.room.AppDatabase;
import com.badao.roomstudy.room.User;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 添加数据
* @param view
*/
public void insertData(View view)
{
User user = new User();
user.setUid((int) System.currentTimeMillis());
user.setFirstName("公众号"+Math.random());
user.setLastName("霸道的程序猿");
AppDatabase.getInstance().userDao().insertAll(user);
Toast.makeText(this,"插入成功",Toast.LENGTH_SHORT).show();
}
/**
* 查询所有数据
* @param view
*/
public void getAll(View view)
{
StringBuilder stringBuilder = new StringBuilder();
List<User> userList = AppDatabase.getInstance().userDao().getAll();
for (User user:userList) {
stringBuilder.append(","+user.getLastName());
}
Toast.makeText(this,"查询到所有的名字为:"+stringBuilder,Toast.LENGTH_SHORT).show();
}
/**
* 条件查询
* @param view
*/
public void findByLastName(View view) {
User user = AppDatabase.getInstance().userDao().findByLastName("霸道%");
if (user == null) {
Toast.makeText(this, "没有查到" , Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "查询到的名字为:" + user.getFirstName() + user.getLastName(), Toast.LENGTH_SHORT).show();
}
}
/**
* 删除
* @param view
*/
public void delete(View view) {
User user = new User();
user.setUid(0);
AppDatabase.getInstance().userDao().delete(user);
Toast.makeText(this, "删除成功" , Toast.LENGTH_SHORT).show();
}
}
即可实现对数据库的增删改查。
对应的数据库文件的位置在data/data/你的包名/database下