Android SqlDelight详解和Demo例子.docx

上传人:b****1 文档编号:1996567 上传时间:2023-05-02 格式:DOCX 页数:31 大小:106.53KB
下载 相关 举报
Android SqlDelight详解和Demo例子.docx_第1页
第1页 / 共31页
Android SqlDelight详解和Demo例子.docx_第2页
第2页 / 共31页
Android SqlDelight详解和Demo例子.docx_第3页
第3页 / 共31页
Android SqlDelight详解和Demo例子.docx_第4页
第4页 / 共31页
Android SqlDelight详解和Demo例子.docx_第5页
第5页 / 共31页
Android SqlDelight详解和Demo例子.docx_第6页
第6页 / 共31页
Android SqlDelight详解和Demo例子.docx_第7页
第7页 / 共31页
Android SqlDelight详解和Demo例子.docx_第8页
第8页 / 共31页
Android SqlDelight详解和Demo例子.docx_第9页
第9页 / 共31页
Android SqlDelight详解和Demo例子.docx_第10页
第10页 / 共31页
Android SqlDelight详解和Demo例子.docx_第11页
第11页 / 共31页
Android SqlDelight详解和Demo例子.docx_第12页
第12页 / 共31页
Android SqlDelight详解和Demo例子.docx_第13页
第13页 / 共31页
Android SqlDelight详解和Demo例子.docx_第14页
第14页 / 共31页
Android SqlDelight详解和Demo例子.docx_第15页
第15页 / 共31页
Android SqlDelight详解和Demo例子.docx_第16页
第16页 / 共31页
Android SqlDelight详解和Demo例子.docx_第17页
第17页 / 共31页
Android SqlDelight详解和Demo例子.docx_第18页
第18页 / 共31页
Android SqlDelight详解和Demo例子.docx_第19页
第19页 / 共31页
Android SqlDelight详解和Demo例子.docx_第20页
第20页 / 共31页
亲,该文档总共31页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

Android SqlDelight详解和Demo例子.docx

《Android SqlDelight详解和Demo例子.docx》由会员分享,可在线阅读,更多相关《Android SqlDelight详解和Demo例子.docx(31页珍藏版)》请在冰点文库上搜索。

Android SqlDelight详解和Demo例子.docx

AndroidSqlDelight详解和Demo例子

AndroidSqlDelight详解和Demo例子

一、简介

SQLDelight和SqlBrite是Square公司推出的一个Android平台数据库解决方案。

在了解这个两个东西前,必须先得有Andorid的Sqlite的知识(SqliteDatabaseandSqliteDataHelper),AutoValue

要分清他们两个的功能:

SqlDelight

是用来把Sql语句生成Java对象的

SqlBrite

才是Sqlite操作,结合Rxjava进行响应式数据库操作。

SqlBrite教程

二、SqlDelight

SqlDelight是从SQL语句来生成JAVA对象。

这样的好处是,所有SQL语句都位于同一个位置,通过查看SQL语句可以清楚的了解需要实现的功能和数据库的结构。

SqlDelight添加了对SQL语句的编译时验证、表名字和列名字的代码自动完成功能。

让编写SQL语句更加快捷。

在编译的时候,根据SQL语句生成Java模型接口和builder来把数据行和Java对象实现转换。

2.1导包

在项目build.gradle的dependencies添加:

classpath'com.squareup.sqldelight:

gradle-plugin:

0.6.0'

在module的build.gralde头部添加apply

applyplugin:

'com.squareup.sqldelight'

重新Sync即可。

2.2使用

SqlDelight可以根据建表的SQL语句自动生成Javamodelinterface,interface的每个方法就是这张表的每一列。

1.编写sq语句

在main目录创建sqldelight目录,然后按照包名创建目录,main/sqldelight/com/xxx/xxx/sq文件(一定得是正确的目录,不然构建失败)

这里编写创建表和查询的语句;

createtableuser(

_idINTEGERNOTNULLPRIMARYKEYAUTOINCREMENT,

nameTEXTNOTNULL,

ageINTEGERNOTNULL

);

--其他的语句通过标识符来引用。

在生成的Java对象中会包含

--一个该标识符的常亮引用这个语句。

--查询use表,百分号(%)代表零个、一个或多个数字或字符,||连接两个不同的字符串,得到一个新的字符串。

select_by_name:

select*fromuser;

2.生成接口Module

编写完毕sql语句之后,make一下moduel,即可在build/generated/source/sqldelight/包名/看到xxxModule接口文件(xxx就是你的sq文件的名称)。

可以看到接口大概是这样的。

publicinterfaceUserModel{

StringTABLE_NAME="user";

String_ID="_id";

StringNAME="name";

StringAGE="age";

StringCREATE_TABLE=""

+"createtableuser(\r\n"

+"_idINTEGERNOTNULLPRIMARYKEYAUTOINCREMENT,\r\n"

+"nameTEXTNOTNULL,\r\n"

+"ageINTEGERNOTNULL\r\n"

+")";

long_id();

@NonNull

Stringname();

longage();

interfaceCreator{

Tcreate(long_id,@NonNullStringname,longage);

}

finalclassMapperimplementsRowMapper{

privatefinalFactoryuserModelFactory;

publicMapper(FactoryuserModelFactory){

this.userModelFactory=userModelFactory;

}

@Override

publicTmap(@NonNullCursorcursor){

returnuserModelFactory.creator.create(

cursor.getLong(0),

cursor.getString

(1),

cursor.getLong

(2)

);

}

}

finalclassMarshal{

protectedfinalContentValuescontentValues=newContentValues();

Marshal(@NullableUserModelcopy){

if(copy!

=null){

this._id(copy._id());

this.name(copy.name());

this.age(copy.age());

}

}

publicContentValuesasContentValues(){

returncontentValues;

}

publicMarshal_id(long_id){

contentValues.put("_id",_id);

returnthis;

}

publicMarshalname(Stringname){

contentValues.put("name",name);

returnthis;

}

publicMarshalage(longage){

contentValues.put("age",age);

returnthis;

}

}

finalclassFactory{

publicfinalCreatorcreator;

publicFactory(Creatorcreator){

this.creator=creator;

}

/**

*@deprecatedUsecompiledstatements(

*/

@Deprecated

publicMarshalmarshal(){

returnnewMarshal(null);

}

/**

*@deprecatedUsecompiledstatements(

*/

@Deprecated

publicMarshalmarshal(UserModelcopy){

returnnewMarshal(copy);

}

publicSqlDelightStatementselect_by_name(){

returnnewSqlDelightStatement(""

+"select*fromuser",

newString[0],Collections.singleton("user"));

}

publicMapperselect_by_nameMapper(){

returnnewMapper(this);

}

}

}

从这个接口可以看到重要的有下面四个类和接口:

Mapper

把Cursor映射为Java对象

Marshal

把Java对象转换为ContentValues,好方便插入数据库

接口Creator

里面定义了一个方法create用来创建我们的Model类型(这里用的是泛型T)

Factory

里面包含一个实现了Creator对象的creator,如果有列值需要转换的话还要包括相应的ColumnAdapter,它的构造函数传入Creator和ColumnAdapter这些参数,marshal方法返回Mode的Marshal(通过它的asContentValues获取对应的ContentValues)

3.定义Bean类

这里利用AtuoValue重写接口,因为SqlDelight生成的接口适合AutoValue无缝接入的,AutoValue的作用的是,自动生成bean代码,AutoValue请点击我。

使用需要导包

//基础AutoValue

apt'com.google.auto.value:

auto-value:

1.4-rc3'

provided'com.google.auto.value:

auto-value:

1.4-rc3'

//AutoValue的扩展,为每个AutoValue注释对象创建一个简单的GsonTypeAdapterFactory。

//

apt'com.ryanharter.auto.value:

auto-value-gson:

0.4.6'

provided'com.ryanharter.auto.value:

auto-value-gson:

0.4.6'

//AutoValue的扩展,支持Android的Parcelable

apt'com.ryanharter.auto.value:

auto-value-parcel:

0.2.5'

//可选择TypeAdapter支持

compile'com.ryanharter.auto.value:

auto-value-parcel-adapter:

0.2.5'

这时候User的bean为

@AutoValue

publicabstractclassUserimplementsUserModel{

publicstaticfinalFactoryFACTORY=newFactory<>(newCreator(){

@Override

publicUsercreate(long_id,@NonNullStringname,longage){

//AutoValue_User需要先make一下module

returnnewAutoValue_User(_id,name,age);

}

});

publicstaticfinalRowMapperSELECT_ALL_MAPPER=FACTORY.select_by_nameMapper();

}

4.使用

然后写一个Activity来测试看看(Sqlite相关知识请XX,点我看教程):

publicclassMainActivityextendsAppCompatActivity{

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//创建获取名字为tp的数据库

SQLiteDatabasesqLiteDatabase=newStuDBHelp(this,"tp",null,1).getWritableDatabase();

//插入数据

sqLiteDatabase.insert("user",null,createContentValues(0,"天平",21));

sqLiteDatabase.insert("user",null,createContentValues(1,"逼辉",23));

Log.e("@@","数据数量:

:

"+getAllUsers(sqLiteDatabase).size());

}

publicListgetAllUsers(SQLiteDatabasedb){

Listresult=newArrayList<>();

//try-with-resources写法,括号里面的资源需要继承AutoCloseable,作用是可以自动关闭对象

try(Cursorcursor=db.rawQuery(User.FACTORY.select_by_name().statement,newString[0])){

while(cursor.moveToNext()){

result.add(User.SELECT_ALL_MAPPER.map(cursor));

}

}

returnresult;

}

publicContentValuescreateContentValues(intid,Stringname,intage){

ContentValuescontentValues=newContentValues();

contentValues.put("_id",id);

contentValues.put("name",name);

contentValues.put("age",age);

returncontentValues;

}

classStuDBHelpextendsSQLiteOpenHelper{

publicStuDBHelp(Contextcontext,Stringname,SQLiteDatabase.CursorFactoryfactory,intversion){

super(context,name,factory,version);

}

//第一次创建数据库的调用的方法

@Override

publicvoidonCreate(SQLiteDatabasedb){

//db.execSQL(User.CREATE_TABLE);

//创建表

db.execSQL(User.CREATE_TABLE);

}

@Override

publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){

}

}

}

这时候你会看到输出:

数据数量:

:

2

2.3sq语句参数

.sq文件使用与SQLite完全相同的语法,包括SQLite绑定args(官方文档点我)。

如果语句包含绑定args,将在Factory上生成类型安全方法,该方法返回包含查询字符串,查询args和要查询的表的字段的SqlDelightStatement。

上面的例子中,我把sq文件里面的查询语句添加where条件,变成:

select_by_name:

select*fromuserwherename='天平';

然后重新make一下module,然后修改查询的getAllUsers方法:

publicListgetAllUsers(SQLiteDatabasedb){

Listresult=newArrayList<>();

//创建SqlDelightStatement对象,里面有查询字符串和参数

SqlDelightStatementquery=User.FACTORY.select_by_name("天平");

//try_with_resources写法,括号里面的资源需要继承AutoCloseable,作用是可以自动关闭对象

try(Cursorcursor=db.rawQuery(User.FACTORY.select_by_name("天平").statement,query.args)){

while(cursor.moveToNext()){

result.add(User.SELECT_ALL_MAPPER.map(cursor));

}

}

returnresult;

}

此时可以看到输出:

数据数量:

:

1

如果是数组就用IN:

select_by_names:

select*fromuserwherenamein?

;

publicListgetAllUsers(SQLiteDatabasedb){

Listresult=newArrayList<>();

SqlDelightStatementquery=User.FACTORY.select_by_name(newString[]{"天平","逼辉"});

try(Cursorcursor=db.rawQuery(query.statement,query.args)){

while(cursor.moveToNext()){

result.add(User.SELECT_ALL_MAPPER.map(cursor));

}

}

returnresult;

}

还能用运算符,例如查询user表的name字段是天开头的或结尾的:

--查询use表,百分号(%)代表零个、一个或多个数字或字符,||连接两个不同的字符串,得到一个新的字符串。

?

1标识参数为同一个的意思

select_by_name:

select*fromuserwhere

namelike'%'||?

1

or

namelike?

1||'%';

SqlDelightStatementquery=User.FACTORY.select_by_name("天");

Cursorcursor=db.rawQuery(query.statement,query.args)

2.4插入、更新、删除

执行多次的插入,更新和删除都需要make一下module,SQLDelight会为为它们生成一个类型安全类。

例如在User.sq添加一句:

--更新name为参数1的年龄为参数2

update_age:

updateusersetage=?

wherename=?

;

重新make一下module会看到UserModel有一个Update_age类:

finalclassUpdate_ageextendsSqlDelightCompiledStatement.Update{

publicUpdate_age(SQLiteDatabasedatabase){

super("user",pileStatement(""

+"updateusersetage=?

wherename=?

"));

}

publicvoidbind(longage,@NonNullStringname){

program.bindLong(1,age);

program.bindString(2,name);

}

}

更新的时候(在上面的栗子的MainActivity的onCreate修改):

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//创建获取名字为tp的数据库

SQLiteDatabasesqLiteDatabase=newStuDBHelp(this,"tp",null,1).getWritableDatabase();

//插入数据

sqLiteDatabase.insert("user",null,createContentValues(0,"天平",21));

sqLiteDatabase.insert("user",null,createContentValues(1,"逼辉",23));

//创建Update_age对象

User.Update_ageupdateAge;

updateAge=newUser.Update_age(sqLiteDatabase);

//设置修改的值

updateAge.bind(66,"天平");

updateAge.bind(99,"逼辉");

//执行

updateAge.program.execute();

//执行,返回修改的行数,这个方法只修改最后一个

//updateAge.program.executeUpdateDelete();

for(Useruser:

getAllUsers(sqLiteDatabase)){

Log.e("@@","user:

"+user.toString());

}

}

这时候会看到输出:

user:

User{_id=0,name=天平,age=66}

user:

User{_id=1,name=逼辉,age=99}

ps:

注意:

如果是bind了多个,executeUpdateDelete只能修改最后那个。

如果需要同时修改需要使用execute,如上面的代码

2.5多个结果

选择返回多个结果列的话,要为查询生成的结果自定义模型、映射程序和工厂方法。

例如:

在User.sq底部添加语句:

--根据age分组,group_concat链接所有的相同age的名字(默认使用逗号链接)

names_for_age:

selectage,group_concat(name)

fromuser

groupbyage;

在Userbean里面添加一个类和静态常量:

@AutoValue

publicabstractclassUserimplementsUserModel{

//

publicstaticfinalFactoryFACTORY=newFactory<>(newCreator(){

@Override

publicUsercreate(long_id,@NonNullStringname,longage){

returnnewAutoV

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2