Android SQLite数据库demo。架构组件Room

 Android架构组件Room

Room主要包含三个部分:

  • Database : 持有DB和DAO
  • Entity : 定义POJO类,即数据表结构
  • DAO(Data Access Objects) : 定义访问数据(增删改查)的接口
  • @Entity(tableName = "table_name**") 注解POJO类,定义数据表名称;
  • @PrimaryKey 定义主键,如果一个Entity使用的是复合主键,可以通过@Entity注解的primaryKeys 属性定义复合主键:@Entity(primaryKeys = {"firstName", "lastName"})
  • @ColumnInfo(name = “column_name”) 定义数据表中的字段名
  • @Ignore 用于告诉Room需要忽略的字段或方法
  • 建立索引:在@Entity注解的indices属性中添加索引字段。例如:indices = {@Index(value = {"first_name", "last_name"}, unique = true), ...}, unique = true可以确保表中不会出现{"first_name", "last_name"} 相同的数据。

 

1.2 Entitiy间的关系

不同于目前存在的大多数ORM库,Room不支持Entitiy对象间的直接引用。(具体原因可以参考: Understand why Room doesn't allow object references)
但Room允许通过外键(Foreign Key)来表示Entity之间的关系。

 

@Entity(foreignKeys = @ForeignKey(entity = User.class,parentColumns = "id",childColumns = "user_id"))
class Book {@PrimaryKeypublic int bookId;public String title;@ColumnInfo(name = "user_id")public int userId;
}

如上面代码所示,Book对象与User对象是属于的关系。Book中的user_id,对应User中的id。 那么当一个User对象被删除时, 对应的Book会发生什么呢?

@ForeignKey注解中有两个属性onDeleteonUpdate, 这两个属性对应ForeignKey中的onDelete()onUpdate(), 通过这两个属性的值来设置当User对象被删除/更新时,Book对象作出的响应。这两个属性的可选值如下:

  • CASCADE:User删除时对应Book一同删除; 更新时,关联的字段一同更新
  • NO_ACTION:User删除时不做任何响应
  • RESTRICT:禁止User的删除/更新。当User删除或更新时,Sqlite会立马报错。
  • SET_NULL:当User删除时, Book中的userId会设为NULL
  • SET_DEFAULT:与SET_NULL类似,当User删除时,Book中的userId会设为默认值

2. 创建数据访问对象(DAO)

 

@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);@Insertvoid insertAll(List<User> users);@Insert(onConflict = OnConflictStrategy.REPLACE)public void insertUsers(User... users);@Deletevoid delete(User user);@Updatepublic void updateUsers(List<User> users);
}

DAO 可以是一个接口,也可以是一个抽象类, Room会在编译时创建DAO的实现。

 

2.2 查询参数传递

 

@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);

看代码应该比较好理解, 方法中传递参数arg, 在sql语句中用:arg即可。编译时R

2.3 查询表中部分字段的信息

在实际某个业务场景中, 我们可能仅关心一个表部分字段的值,这时我仅需要查询关心的列即可。

定义子集的POJO类:

 

public class NameTuple {@ColumnInfo(name="first_name")public String firstName;@ColumnInfo(name="last_name")public String lastName;
}

在DAO中添加查询方法:

 

@Query("SELECT first_name, last_name FROM user")
public List<NameTuple> loadFullName();

这里定义的POJO也支持使用@Embedded

2.4 联表查询

Room支持联表查询,接口定义上与其他查询差别不大, 主要还是sql语句的差别。

 

@Dao
public interface MyDao {@Query("SELECT * FROM book "+ "INNER JOIN loan ON loan.book_id = book.id "+ "INNER JOIN user ON user.id = loan.user_id "+ "WHERE user.name LIKE :userName")public List<Book> findBooksBorrowedByNameSync(String userName);
}

2.4 联表查询

Room支持联表查询,接口定义上与其他查询差别不大, 主要还是sql语句的差别。

 

@Dao
public interface MyDao {@Query("SELECT * FROM book "+ "INNER JOIN loan ON loan.book_id = book.id "+ "INNER JOIN user ON user.id = loan.user_id "+ "WHERE user.name LIKE :userName")public List<Book> findBooksBorrowedByNameSync(String userName);
}

Room提供了Migration类来实现数据库的升级:

 

Room.databaseBuilder(getApplicationContext(), MyDb.class, "database-name").addMigrations(MIGRATION_1_2, MIGRATION_2_3).build();static final Migration MIGRATION_1_2 = new Migration(1, 2) {@Overridepublic void migrate(SupportSQLiteDatabase database) {database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, "+ "`name` TEXT, PRIMARY KEY(`id`))");}
};static final Migration MIGRATION_2_3 = new Migration(2, 3) {@Overridepublic void migrate(SupportSQLiteDatabase database) {database.execSQL("ALTER TABLE Book "+ " ADD COLUMN pub_year INTEGER");}
};

在创建Migration类时需要指定startVersionendVersion, 代码中MIGRATION_1_2MIGRATION_2_3的startVersion和endVersion是递增的, Migration其实是支持从版本1直接升到版本3,只要其migrate()方法里执行的语句正常即可。那么Room是怎么实现数据库升级的呢?其实本质上还是调用SQLiteOpenHelper.onUpgrade,Room中自己实现了一个SQLiteOpenHelper, 在onUpgrade()方法被调用时触发Migration,当第一次访问数据库时,Room做了以下几件事:

  • 创建Room Database实例
  • SQLiteOpenHelper.onUpgrade被调用,并且触发Migration
  • 打开数据库

架构组件Room、demo了解:https://download.csdn.net/download/meixi_android/19386289

 

 

原生sqlite、demo链接:https://download.csdn.net/download/meixi_android/10710400

 

创建数据库版本v.1

/*** 作者:created by meixi* 邮箱:13164716840@163.com* 日期:2018/10/9 11*/
public class DBHelper extends SQLiteOpenHelper {private static final String DATABASE_NAME = "mall.db";private static final int DATABASE_VERSION = 1000;private static DBHelper instance = null;public DBHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION);}public synchronized static DBHelper getInstance(Context context) {if (instance == null) {instance = new DBHelper(context);}return instance;}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(SQL.CREATE_TABLE_FAVORITE);// 若不是第一个版本安装,直接执行数据库升级// 请不要修改FIRST_DATABASE_VERSION的值,其为第一个数据库版本大小final int FIRST_DATABASE_VERSION = 1000;onUpgrade(db, FIRST_DATABASE_VERSION, DATABASE_VERSION);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 使用for实现跨版本升级数据库for (int i = oldVersion; i < newVersion; i++) {switch (i) {default:break;}}}
}

 

创建数据库语句:

public class SQL {public static final String T_FAVORITE = "favorite";public static final String CREATE_TABLE_FAVORITE ="CREATE TABLE IF NOT EXISTS " + T_FAVORITE + "(" +"_id integer primary key autoincrement, " +"title VARCHAR, " +"url VARCHAR, " +"createDate VARCHAR " +")";
}

实现增删改查activity:

public class MainActivity extends AppCompatActivity {private static String CREATE_TABLE ="create table number(_id integer primary key autoincrement ,phone real)";int ab  = 0,cd;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button1=findViewById(R.id.baocunid);Button button2=findViewById(R.id.duquid);Button button3=findViewById(R.id.shanchuid);Button button4=findViewById(R.id.xiugaiid);button1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {ab++;boolean nn = baocun(MainActivity.this, new String[] { "114499title","rullll---htt;s=="+ab,"加入的xxx" });Log.i("lgq","sbbbb---"+nn);}});button2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {getBai(MainActivity.this);}});button3.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {String ss= Delete(MainActivity.this,"1");Log.i("lgq","shanchu=g==="+ss);}});button4.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {String ss = updata(MainActivity.this,"");Log.i("lgq","xiugg=g==="+ss);}});}public static boolean baocun(Context context, String[] values) {SQLiteDatabase db2=null;DBHelper2 dbHelper = null;try {dbHelper =new DBHelper2(context);db2 = dbHelper.getWritableDatabase();db2=dbHelper.getWritableDatabase();db2.beginTransaction();db2.execSQL("insert into favorite (title,url,deleted) values (?,?,?)",values);db2.setTransactionSuccessful();db2.endTransaction();return true;} catch (Exception e) {e.printStackTrace();return false;}finally{}}public  List<String> getBai(Context context){List<String> list = new ArrayList<String>();SQLiteDatabase db2=null;DBHelper2 dbHelper = null;try {dbHelper= new DBHelper2(context);db2=dbHelper.getWritableDatabase();Cursor cursor =db2.rawQuery("select _id,title,deleted from favorite", null);while(cursor.moveToNext()){cd++;
//                int dbid = cursor.getInt(cursor.getColumnIndex("_id"));int id=cursor.getInt(cursor.getColumnIndex("_id"));String haoma = cursor.getString(cursor.getColumnIndex("title"))+"";String names = cursor.getString(cursor.getColumnIndex("deleted"));list.add(haoma);System.out.println("lgqs======"+haoma+"......."+names+"     "+cd+"    id===  "+id);}db2.setTransactionSuccessful();db2.endTransaction();} catch (Exception e) {e.printStackTrace();}return list;}public static String Delete(Context context,String string){SQLiteDatabase db2=null;DBHelper2 dbHelper = null;try {dbHelper =new DBHelper2(context);db2 = dbHelper.getWritableDatabase();db2=dbHelper.getWritableDatabase();db2.beginTransaction();db2.execSQL("delete from favorite where _id=?",new String[] { string });db2.setTransactionSuccessful();db2.endTransaction();return "成功";} catch (Exception e) {e.printStackTrace();return "失败";}}public static String updata(Context context,String string){SQLiteDatabase db2=null;DBHelper2 dbHelper = null;try {dbHelper =new DBHelper2(context);db2 = dbHelper.getWritableDatabase();db2=dbHelper.getWritableDatabase();db2.beginTransaction();db2.execSQL("update favorite set title ="+"2222999"+" where url =?",new String[]{"rullll---htt;s==3"});db2.setTransactionSuccessful();db2.endTransaction();return "成功";} catch (Exception e) {e.printStackTrace();return "失败";}}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/415107.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

转录组差异表达分析工具Ballgown

Ballgown是分析转录组差异表达的R包。 软件安装&#xff1a; 运行R&#xff0c; source(“http://bioconductor.org/biocLite.R”) biocLite(“ballgown”) R会自动安装Ballgown&#xff0c;及相应的依赖包。 Ballgown的输入文件 StringTie使用-B参数直接生成Ballgown的输入文件…

docker centos ssh

1、创建一个容器 docker run -d -p 18022:22 -p 18000:8000 --privileged -v /Users/caowei/share:/share --name yf c17f22223248 /usr/sbin/init 2、进入容器 docker exec -it 39550a9d4610 /bin/bash 3、安装openssh和openssh-server yum install -y passwd openssh op…

Android自定义view详解,使用实例,自定义属性,贝塞尔曲线

//只会触发执行onDraw方法&#xff0c;只会改变绘制里面的内容,条目的绘制 invalidate(); //只会触发执行onDraw方法&#xff0c;但是可以在子线程中刷新 postInvalidate(); //view的布局参数改变之后刷新&#xff0c;比如view的宽度和高度都修改了&#xff0c;只能通过reques…

centos使用git安装nvm

1、文件拷贝 git clone https://github.com/creationix/nvm.git source nvm/nvm.sh 2、安装node nvm install 14.9.0 nvm use 14.9.0

前端学习(2679):安装mysql_front

mysql front安装与使用教程 2020-04-10 11:32 更新mysql front一种小巧的管理Mysql的应用工具&#xff0c;那么这个工具该如何安装和使用呢&#xff1f;一起来看看吧。 一&#xff0c;mysql前端下载&#xff1a; mysql front下载地址&#xff1a;点击下载 二&#xff0c;mysql前…

Android RecyclerView 向上偏移解决、添加自定义分割线,瀑布流,ScrollView嵌套RecyclerView滑动卡顿

向上偏移解决 android:focusableInTouchMode"true" android:focusable"true" android:fillViewport"true" 卡顿解决方法 recyclerViewwg.setHasFixedSize(true); recyclerViewwg.setNestedScrollingEnabled(false); 删除条目&#xff1a; l…

前端学习(2678):懂代码之表格BaseTable编辑操作

第一步:编辑操作 <template slot-scope"scope"><el-buttontype"text"icon"el-icon-edit"click"handleEdit(scope.$index, scope.row)">编辑</el-button></template> 第二步 进行编辑处理 // 编辑操作handle…

vue-cli3配置externals、jquery

在index.html引入 <script src"https://cdn.bootcdn.net/ajax/libs/jquery/1.10.0/jquery.js"></script>配置文件 vue.config.js 代码如下&#xff1a; module.exports {configureWebpack:{externals: {jquery : $,}}, };

QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开

版权声明&#xff1a;若无来源注明&#xff0c;Techie亮博客文章均为原创。 转载请以链接形式标明本文标题和地址&#xff1a;本文标题&#xff1a;QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开 本文地址&#xff1a;http://techieliang.com/2017/12/685/ 文章…

工作182:表格渲染

<el-table :data"tableData" style"width: 100%" border> <!-- <el-table-column label"id" prop"1" align"center"></el-table-column>--><!--渲染账号名称--><el-table-column l…

Android 集成支付宝支付,支付宝支付2.0

成功起调支付宝支付 下载支付sdk复制到libs文件夹下并add as library&#xff1a;https://docs.open.alipay.com/54/104509 1、首先申请支付宝 企业账户 链接&#xff1a;https://memberprod.alipay.com/account/reg/enterpriseIndex.htm 备注&#xff1a;企业账户是以邮箱申…

docker centos node nginx

1、docker pull centos:centos8 2、进入容器 docker run -it centos:centos8 /bin/bash 3、安装git yum install -y git 4、安装nvm git clone https://github.com/creationix/nvm.git source nvm/nvm.sh 5、修改环境变量 vi ~/.bash_profile 加入source nvm/nvm.sh 更新 sour…

Appium——api常用函数

appium常用函数介绍&#xff1a;获取页面信息&#xff1a;1、 def get_current_activity(cls, driver):获取当前页面的activity:param driver::return:return driver.current_activity2、 def get_current_pagesource(cls, driver):获取当前页面源码:param driver::return: 返回…

android 微信支付,body为中文字符,签名错误

微信支付订单生产方法&#xff1a; /*** 根据您的订单信息 生成 微信产品支付订单信息*/private String createWeChatOrder() {StringBuffer xml new StringBuffer();try {String nonceStr genNonceStr();xml.append("</xml>");List<KeyValue> package…

使用Dockerfile部署vue项目

项目需要部署到甲方电脑上&#xff0c;使用docker是个不错的选择。 1、创建Dockerfile文件 # 设置基础镜像 FROM nginx:latest# 将dist文件中的内容复制到 /usr/share/nginx/html/ 这个目录下面 COPY dist/ /usr/share/nginx/html/ # 用本地的 default.conf 配置来替换nginx镜…

工作183:动态渲染数据 数据在数字字典里面

1接口调用 /*调用接口*/created() {/*动态渲染content_type接口*/getAction("/dict/list",{dict_code:"content_type"}).then(res>{this.content_typeres.data})/*动态渲染*/getAction("/dict/list",{dict_code:"resource_type"})…

cesium 修改 鼠标 样式

十字&#xff1a; viewer._container.style.cursor "crosshair"; 默认: viewer._container.style.cursor "default";

Android 集成微信支付详解

打包后才能起调支付 微信支付成功起调 微信skd下载&#xff1a;https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter11_1 签名APK下载&#xff1a;https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk 1、首先到微信.…

工作184:自定义事件

1子组件 mongo.vue <template><button click"eat">按钮</button> </template><script> export default {created() {this.$on("eat", function(fruit) {console.log("子组件接收自己发射的事件");});},methods:…