android 数据库操作 常见的数据库管理系统

n droid数据库室的开发和使用的详细说明一.导言:房间SQLite提供了一个抽象层,可以充分利用SQLite的强大功能,同时还可以流畅的访问数据库。房间由3个主要部分组成:数据库:它包

本文最后更新时间:  2023-04-11 09:59:02

n droid数据库室的开发和使用的详细说明

一.导言:

房间SQLite提供了一个抽象层,可以充分利用SQLite的强大功能,同时还可以流畅的访问数据库。

房间由3个主要部分组成:

数据库:它包含数据库容器,并作为应用保留的持久关系数据的底层连接的主要访问点。

@数据库评论

1.它是一个抽象类,扩展了RoomDatabase。

2.在注释中添加与数据库相关联的实体表。

3.包含0个参数并返回用@Dao注释的类的抽象方法。

在运行时,可以通过调用Room.databaseBuilder()或Room.inMemoryDatabaseBuilder()来获取数据库的实例。

@Entity:表示数据库中的一个表。

@Dao:包含访问数据库的方法。

第二,依托房间数据库

1.在bulid中添加项目的依赖关系。应用程序模块下的Gradle。

//添加Room依赖implementation 'androidx.room:room-runtime:2.2.5'annotationProcessor 'androidx.room:room-compiler:2.2.5'

第三,创建一个实体类实体

@Entitypublic class User { @PrimaryKey(autoGenerate = true)//主键是否自动增长,默认为false private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}

1.主键:每个实体必须至少定义一个字段作为其主键。

1.可以在实体中@PrimaryKey(autoGenerate = true)注解,同时你也可以使用autoGenerate属性,可以通过Room来自动分配ID 2.也可以通过@Entity@Entity(primaryKeys = {"id","name"})如果有组合主键

2.通常Room会使用类名作为数据库的表名。如果您希望自定义表名位于@ Entity(tableName = “我的用户”),注意:在SQLite中,表名是不区分大小写的。

3.Room使用变量名作为数据库表的字段名。如果希望字段名不同于变量名,请将其添加到变量中。

public class User { @ColumnInfo(name = "first_name") private String name; }

4.索引和唯一性

根据操作数据的方式,您可能需要提高通过索引查询数据库的速度。通过@Entity添加indexes属性,部分字段设置为唯一。可以通过@Index注释将unique设置为true。

@Entity(indices = {@Index(value = "name",unique = true)})public class User {private String name;}

5.定义对象之间的关系。

由于SQLite是一个关系数据库,您可以在对象之前指定关系。Room明确禁止直接使用关系,但是Room仍然允许您定义实体之间的外键。

例如,如果有另一个名为Book的实体,可以在用户实体下使用@ForeignKey注释来定义它们之间的关系。

@Entity( foreignKeys = @ForeignKey(entity = User.class, parentColumns = "id", childColumns = "user_id")//定义外键)public class Book { @PrimaryKey//定义主键 public int bookId; public String title; @ColumnInfo(name = "user_id")//定义数据库表中的字段名 public int userId; public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public int getBookId() { return bookId; } public void setBookId(int bookId) { this.bookId = bookId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; }}

6.创建嵌套对象。

您可以使用@Embedded注释来指示要在表中分解为子字段的对象。

例如,我们的用户类可以包含Address类型的字段,它表示名为street、city、state和postCode的字段的组合。要在表中单独存储组合列,请在用户类中包含带有@Embedded注释的地址字段。

public class Address { public String street; public String state; public String city; @ColumnInfo(name = "post_code") public int postCode;}@Entitypublic class User { @PrimaryKey public int id; public String firstName; @Embedded public Address address;}

因此,这个表示用户对象的表包含具有以下名称的列:id、名字、街道、州、城市和post_code。

@Embedded(前缀= “地址_ ”如果一个实体有多个相同类型的嵌入字段,可以通过设置prefix属性将address_嵌入到列名的开头,使每一列都是唯一的。

7.忽略成员变量

如果不想保留某些成员变量,可以使用@Ignore注释。

@Ignore//指示Room需要忽略的字段private int age;

四:创建一个Dao接口

Dao包含访问数据库的方法,并创建一个用@Dao注释的操作实体类。

@Insert insert语句注释

@Delete删除语句注释

@Update()更新语句注释

@查询(“SELECT * FROM user其中名字=:name ”)查询语句

@Daopublic interface UserDao { /*插入数据User*/ @Insert void insert(User user); @Query("SELECT * FROM user")//从user表中查询所有,user是User实体类默认在Room中创建的表,也可以通过@Entity(tableName = "my_user"),指定表名,故这个表名就变成my_user List<User> getAllUsers(); @Query("SELECT * FROM user WHERE first_name=:name")//设置筛选条件name,来查询这个first_name是表名first_name字段,通过@ColumnInfo(name = "first_name")来设置表字段名 List<User> getUsersByName(String name);}

五:创建数据库holder类。

@Database(entities = {User.class},version = 6,exportSchema = false)public abstract class UserDatabase extends RoomDatabase { private static final String DB_NAME="UserDatabase.db"; private static volatile UserDatabase instance;//创建单例 public static synchronized UserDatabase getInstance(Context context){ if (instance==null){ instance=create(context); } return instance; } /** * 创建数据库*/ private static UserDatabase create(Context context) { return Room.databaseBuilder(context,UserDatabase.class,DB_NAME) .allowMainThreadQueries()//允许在主线程操作数据库,一般不推荐;设置这个后主线程调用增删改查不会报错,否则会报错 .fallbackToDestructiveMigration()//该方法能在升级异常重新创建数据库,但所有的数据都会丢失 .addMigrations(new Migration(1,4) { @Override public void migrate(@NonNull SupportSQLiteDatabase database) { database.execSQL("alter table user add price TEXT");//添加一个字段 price升级数据库版本到4 }}) .build(); } public abstract UserDao getUserDao();//这个是必要的,创建DAO的抽象类}

注意:

1.将在编译时检查SQL语句的正确性。

2.不要在主线程中执行数据库操作。

3.RoomDatabase最好使用singleton模式。

如果数据库没有设置为在主线程中运行,将会报告一个错误,错误提示是

因此,最好在新线程()中使用数据库。start()子线程,或者Handler或AsyncTask或RXJava可以异步实现。

房间数据库升级

//第一步修改版本号为2,要升级的版本@Database(entities = {User.class},version = 2,exportSchema = false)//第二步,添加addMigrations()添加数据库升级 Room.databaseBuilder(context,UserDatabase.class,DB_NAME) .addMigrations(new Migration(1,2) { @Override public void migrate(@NonNull SupportSQLiteDatabase database) { database.execSQL("alter table user add go TEXT");//在user 表中添加一个字段go 类型为TEXT Log.d("aa",database.getVersion()+""); } }) .build();//第三步在Entity实体类User中添加属性private String go;public String getGo() { return go;}public void setGo(String go) { this.go = go;}//这样数据库版本就升级到了2,就可以使用了

六:房间数据库的使用

通过打开一个子线程来插入一段数据,或者可以将RXJava与Handler和AsyncTask等异步实现结合起来。

User user=new User();user.setAge(2223);user.setName("eees");user.setGo("wogo");new Thread(new Runnable() { @Override public void run() { UserDatabase.getInstance(NineActivity.this).getUserDao().insert(user); Log.d("TAG","插入一条数据"); }}).start();

温馨提示:内容均由网友自行发布提供,仅用于学习交流,如有版权问题,请联系我们。