2022-11-4学习内容
1.Jetpack Room、Room增删改查
1.1build.gradle
plugins { id 'com.android.application' } android { compileSdk 33 defaultConfig { applicationId "com.example.chapter06" minSdk 28 targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" javaCompileOptions { annotationProcessorOptions { arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]//指定数据库schema导出的位置 } } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { implementation 'androidx.appcompat:appcompat:1.3.0' implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' implementation 'androidx.room:room-runtime:2.2.5' annotationProcessor 'androidx.room:room-compiler:2.2.5' }
其中新增内容为:
defaultConfig { javaCompileOptions { annotationProcessorOptions { arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]//指定数据库schema导出的位置 } } }
dependencies { implementation 'androidx.room:room-runtime:2.2.5' annotationProcessor 'androidx.room:room-compiler:2.2.5' }
1.2BookInfo.java
package com.example.chapter06.entity; import androidx.room.Entity; import androidx.room.PrimaryKey; @Entity public class BookInfo { @PrimaryKey(autoGenerate = true) private int id; private String name; private String author; private String press; private Double price; 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 String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getPress() { return press; } public void setPress(String press) { this.press = press; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } @Override public String toString() { return "BookInfo{" + "id=" + id + ", name='" + name + '\'' + ", author='" + author + '\'' + ", press='" + press + '\'' + ", price=" + price + '}'; } }
1.3BookDao.java
package com.example.chapter06.dao; import androidx.room.Dao; import androidx.room.Delete; import androidx.room.Insert; import androidx.room.Query; import androidx.room.Update; import com.example.chapter06.entity.BookInfo; import java.util.List; @Dao public interface BookDao { // 可变参数 @Insert void insert(BookInfo... book); @Delete void delete(BookInfo... book); @Query("DELETE FROM BookInfo") void deleteAll(); @Update int update(BookInfo... book); // 加载所有书籍信息 @Query("SELECT * FROM BookInfo") List<BookInfo> queryAll(); @Query("SELECT * FROM BookInfo WHERE name = :name ORDER BY id DESC LIMIT 1") BookInfo queryByName(String name); }
1.4BookDatabase.java
package com.example.chapter06.database; import androidx.room.Database; import androidx.room.RoomDatabase; import com.example.chapter06.dao.BookDao; import com.example.chapter06.entity.BookInfo; // entities表示该数据库有哪些表,version表示数据库的版本号 // exportShema表示是否导出数据库信息的JSON串,建议设为false,若设为true还需指定json文件的保存路径。 @Database(entities = {BookInfo.class}, version=1, exportSchema = true) public abstract class BookDatabase extends RoomDatabase { // 获取该数据库中某张表的持久化对象 public abstract BookDao bookDao(); }
1.5MyApplication.java
package com.example.chapter06; import android.app.Application; import android.content.res.Configuration; import android.util.Log; import androidx.annotation.NonNull; import androidx.room.Room; import com.example.chapter06.database.BookDatabase; import java.util.HashMap; public class MyApplication extends Application { private static MyApplication myApp; // 声明一个公共的信息映射对象,可当做全局变量使用 public HashMap<String, String> infoMap = new HashMap<>(); // 声明一个书籍数据库对象 private BookDatabase bookDatabase; public static MyApplication getInstance() { return myApp; } // 在APP启动时调用 @Override public void onCreate() { super.onCreate(); myApp = this; Log.d("ning", "MyApplication onCreate"); // 构建书籍数据库的实例 bookDatabase = Room.databaseBuilder(this, BookDatabase.class, "book") // 允许迁移数据库(发生数据库变更时,Room默认删除原数据库再创建新数据库,如此一来原来的记录会丢失,故而要改为迁移方式以便保存原有记录 .addMigrations() // 允许在主线程中操作数据库(Room默认不能在主线程中操作数据库) .allowMainThreadQueries() .build(); } // 在APP终止时调用 @Override public void onTerminate() { super.onTerminate(); Log.d("ning", "onTerminate"); } // 在配置改变时调用,例如从竖屏变为横屏 @Override public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); Log.d("ning", "onConfigurationChanged"); } // 获取书籍数据库的实例 public BookDatabase getBookDB() { return bookDatabase; } }
1.6RoomWriteActivity.java
package com.example.chapter06; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.EditText; import com.example.chapter06.dao.BookDao; import com.example.chapter06.entity.BookInfo; import com.example.chapter06.util.ToastUtil; import java.util.List; public class RoomWriteActivity extends AppCompatActivity implements View.OnClickListener{ private EditText et_name; private EditText et_author; private EditText et_press; private EditText et_price; private BookDao bookDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_room_write); et_name = findViewById(R.id.et_name); et_author = findViewById(R.id.et_author); et_press = findViewById(R.id.et_press); et_price = findViewById(R.id.et_price); findViewById(R.id.btn_save).setOnClickListener(this); findViewById(R.id.btn_delete).setOnClickListener(this); findViewById(R.id.btn_update).setOnClickListener(this); findViewById(R.id.btn_query).setOnClickListener(this); // 从App实例中获取唯一的书籍持久化对象 bookDao = MyApplication.getInstance().getBookDB().bookDao(); } @Override public void onClick(View v) { String name = et_name.getText().toString(); String author = et_author.getText().toString(); String press = et_press.getText().toString(); String price = et_price.getText().toString(); switch (v.getId()) { case R.id.btn_save: // 以下声明一个书籍信息对象,并填写它的各字段值 BookInfo b1 = new BookInfo(); b1.setName(name); b1.setAuthor(author); b1.setPress(press); b1.setPrice(Double.parseDouble(price)); bookDao.insert(b1); ToastUtil.show(this, "保存成功"); break; case R.id.btn_delete: BookInfo b2 = new BookInfo(); b2.setId(1); bookDao.delete(b2); break; case R.id.btn_update: BookInfo b3 = new BookInfo(); // 根据名字查询到数据库中已有的记录 BookInfo b4 = bookDao.queryByName(name); b3.setId(b4.getId()); b3.setName(name); b3.setAuthor(author); b3.setPress(press); b3.setPrice(Double.parseDouble(price)); bookDao.update(b3); break; case R.id.btn_query: List<BookInfo> list = bookDao.queryAll(); for (BookInfo b : list) { Log.d("ning", b.toString()); } break; } } }
1.7activity_room_write.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal"> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text=" 书名:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_name" android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginTop="3dp" android:layout_marginBottom="3dp" android:layout_weight="1" android:background="@drawable/editext_selector" android:hint="请输入书籍名称" android:inputType="text" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal"> <TextView android:id="@+id/tv_author" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text=" 作者:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_author" android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginTop="3dp" android:layout_marginBottom="3dp" android:layout_weight="1" android:background="@drawable/editext_selector" android:hint="请输入作者姓名" android:inputType="text" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal"> <TextView android:id="@+id/tv_press" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text=" 出版社:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_press" android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginTop="3dp" android:layout_marginBottom="3dp" android:layout_weight="1" android:background="@drawable/editext_selector" android:hint="请输入出版社名称" android:inputType="text" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal"> <TextView android:id="@+id/tv_price" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text=" 价格:" android:textColor="@color/black" android:textSize="17sp" /> <EditText android:id="@+id/et_price" android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginTop="3dp" android:layout_marginBottom="3dp" android:layout_weight="1" android:background="@drawable/editext_selector" android:hint="请输入书籍价格" android:inputType="text" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> <Button android:id="@+id/btn_save" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="添加" android:textColor="@color/black" android:textSize="17sp" /> <Button android:id="@+id/btn_delete" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="删除" android:textColor="@color/black" android:textSize="17sp" /> <Button android:id="@+id/btn_update" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="修改" android:textColor="@color/black" android:textSize="17sp" /> <Button android:id="@+id/btn_query" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="查询" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout>
1.8效果:
1.8.1schema:
1.json
{ "formatVersion": 1, "database": { "version": 1, "identityHash": "b72d0053ebd9b4bd9d877174fb85477e", "entities": [ { "tableName": "BookInfo", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `author` TEXT, `press` TEXT, `price` REAL)", "fields": [ { "fieldPath": "id", "columnName": "id", "affinity": "INTEGER", "notNull": true }, { "fieldPath": "name", "columnName": "name", "affinity": "TEXT", "notNull": false }, { "fieldPath": "author", "columnName": "author", "affinity": "TEXT", "notNull": false }, { "fieldPath": "press", "columnName": "press", "affinity": "TEXT", "notNull": false }, { "fieldPath": "price", "columnName": "price", "affinity": "REAL", "notNull": false } ], "primaryKey": { "columnNames": [ "id" ], "autoGenerate": true }, "indices": [], "foreignKeys": [] } ], "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'b72d0053ebd9b4bd9d877174fb85477e')" ] } }
1.8.2增:
点击“查询”控制台输出:
2022-11-04 21:01:52.857 5045-5045/com.example.chapter06 D/ning: BookInfo{id=1, name='bookName1', author='author1', press='press1', price=19.0} 2022-11-04 21:01:52.858 5045-5045/com.example.chapter06 D/ning: BookInfo{id=2, name='bookName1', author='author1', press='press1', price=19.0}
1.8.3删除:
根据id=1删除:点击“查询”控制台输出:
2022-11-04 21:03:06.541 5045-5045/com.example.chapter06 D/ning: BookInfo{id=2, name='bookName1', author='author1', press='press1', price=19.0}
发现id=1的已成功删除。
1.8.4修改:
按下图输入,点“修改”,
点击“查询”控制台输出:
2022-11-04 21:05:01.265 5045-5045/com.example.chapter06 D/ning: BookInfo{id=2, name='bookName1', author='author2', press='press2', price=222.0}
发现name为bookName1的对象的各字段已成功修改。