SQLDelight从SQL生成Java模型CREATE TABLE
语句。这些模型给你一个类型安全的API来读写你的表中的行。它可以帮助你保持你的SQL语句共同组织,并容易从Java访问。
例
要使用SQLDelight,把你的SQL语句在.sq
文件,就像 在src / main / sqldelight / COM /例子/ HockeyPlayer.sq
。通常情况下,第一条语句创建一个表。
CREATE TABLE hockey_player (
_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
number INTEGER NOT NULL,
name TEXT NOT NULL
);
-进一步SQL语句由标识符进行。这将被用于命名恒定 -在生成的Java代码。
select_by_name:
SELECT *
FROM hockey_player
WHERE name = ;
从这个SQLDelight会生成一个HockeyPlayerModel
嵌套类的Java接口读取(映射器)和写作(元帅)表。
package com.example;
import android.content.ContentValues;
import android.database.Cursor;
import java.lang.String;
public interface HockeyPlayerModel {
String TABLE_NAME = "hockey_player";
String _ID = "_id";
String NUMBER = "number";
String NAME = "name";
String CREATE_TABLE = ""
+ "CREATE TABLE hockey_player (\n"
+ " _id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n"
+ " number INTEGER NOT NULL,\n"
+ " name TEXT NOT NULL\n"
+ ")";
String SELECT_BY_NAME = ""
+ "SELECT *\n"
+ "FROM hockey_player\n"
+ "WHERE name = ";
long _id();
long number();
String name();
final class Mapper<T extends HockeyPlayerModel> {
private final Creator<T> creator;
protected Mapper(Creator<T> creator) {
this.creator = creator;
}
public T map(Cursor cursor) {
return creator.create(
cursor.getLong(cursor.getColumnIndex(_ID)),
cursor.getLong(cursor.getColumnIndex(NUMBER)),
cursor.getString(cursor.getColumnIndex(NAME))
);
}
public interface Creator<R extends HockeyPlayerModel> {
R create(long _id, long number, String name);
}
}
class HockeyPlayerMarshal<T extends HockeyPlayerMarshal<T>> {
protected ContentValues contentValues = new ContentValues();
public HockeyPlayerMarshal() {
}
public final ContentValues asContentValues() {
return contentValues;
}
public T _id(long _id) {
contentValues.put(_ID, _id);
return (T) this;
}
public T number(long number) {
contentValues.put(NUMBER, number);
return (T) this;
}
public T name(String name) {
contentValues.put(NAME, name);
return (T) this;
}
}
}
AutoValue
使用谷歌的AutoValue可以最低限度地使模型/元帅/映射器的实现:
@AutoValue
public abstract class HockeyPlayer implements HockeyPlayerModel {
public static final Mapper<HockeyPlayer> MAPPER = new Mapper<>(new Mapper.Creator() {
@Override public HockeyPlayer create(long _id, long number, String name) {
return new AutoValue_HockeyPlayer(_id, age, number, gender);
}
}
public static final class Marshal extends HockeyPlayerMarshal<Marshal> { }
}
如果您还使用Retrolambda匿名类可以通过方法引用来代替:
@AutoValue
public abstract class HockeyPlayer implements HockeyPlayerModel {
public static final Mapper<HockeyPlayer> MAPPER = new Mapper<>(AutoValue_HockeyPlayer::new);
public static final class Marshal extends HockeyPlayerMarshal<Marshal> { }
}
消费代码
使用生成的常量引用表名和SQL语句。
public void insert(SqliteDatabase db, long _id, long number, String name) {
db.insert(HockeyPlayer.TABLE_NAME, null, new HockeyPlayer.Marshal()
._id(_id)
.number(number)
.name(name)
.asContentValues());
}
public List<HockeyPlayer> alecs(SQLiteDatabase db) {
List<HockeyPlayer> result = new ArrayList<>();
try (Cursor cursor = db.rawQuery(HockeyPlayer.SELECT_BY_NAME, new String[] { "Alec" })) {
while (cursor.moveToNext()) {
result.add(HockeyPlayer.MAPPER.map(cursor));
}
}
return result;
}
类型
SQLDelight列定义是相同的常规SQLite的列定义,但支持一个额外的列约束其指定生成的接口列的Java类型。SQLDelight原生支持,同样类型的 光标
和ContentValues
期望:
CREATE TABLE some_types {
some_long INTEGER, -- Stored as INTEGER in db, retrieved as Long
some_double REAL, -- Stored as REAL in db, retrieved as Double
some_string TEXT, -- Stored as TEXT in db, retrieved as String
some_blob BLOB, -- Stored as BLOB in db, retrieved as byte[]
some_int INTEGER AS Integer, -- Stored as INTEGER in db, retrieved as Integer
some_short INTEGER AS Short, -- Stored as INTEGER in db, retrieved as Short
some_float REAL AS Float -- Stored as REAL in db, retrieved as Float
}
布尔值
SQLDelight支持布尔列,将它们存储在数据库中的整数。由于它们作为整数实现时,它们可以给INT列约束:
CREATE TABLE hockey_player (
injured INTEGER AS Boolean DEFAULT 0
)
自定义类
如果您想获取自定义类型的列,您可以指定Java类型为字符串的sqlite:
CREATE TABLE hockey_player (
birth_date INTEGER AS 'java.util.Calendar' NOT NULL
)
但是,创建一个元帅或映射器将要求您提供ColumnAdapter
它知道如何将映射光标
到你的类型和元帅你的类型变成ContentValues
:
public class HockeyPlayer implements HockeyPlayerModel {
private static final ColumnAdapter<Calendar> CALENDAR_ADAPTER = new ColumnAdapter<>() {
@Override public Calendar map(Cursor cursor, int columnIndex) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(cursor.getLong(columnIndex));
return calendar;
}
@Override public void marshal(ContentValues contentValues, String key, Calendar value) {
contentValues.put(key, value.getTimeInMillis());
}
}
public static final Mapper<HockeyPlayer> MAPPER = new Mapper<>(new Mapper.Creator<>() { },
CALENDAR_ADAPTER);
public static final class Marshal extends HockeyPlayerMarshal<Marshal> {
public Marshal() {
super(CALENDAR_ADAPTER);
}
}
}
枚举
作为一种方便SQLDelight运行包括ColumnAdapter
用于存储枚举为文本。
CREATE TABLE hockey_player (
position TEXT AS 'com.example.hockey.HockeyPlayer.Position'
)
public class HockeyPlayer implements HockeyPlayerModel {
public enum Position {
CENTER, LEFT_WING, RIGHT_WING, DEFENSE, GOALIE
}
private static final ColumnAdapter<Position> POSITION_ADAPTER = EnumColumnAdapter.create(Position.class);
public static final Mapper<HockeyPlayer> MAPPER = new Mapper<>(new Mapper.Creator<>() { },
POSITION_ADAPTER);
public static final class Marshal extends HockeyPlayerMarshal<Marshal> {
public Marshal() {
super(POSITION_ADAPTER);
}
}
}
SQL语句的参数
SQL查询也可以包含参数以同样的方式SqliteDatabase
作用:
select_by_position:
SELECT *
FROM hockey_player
WHERE position = ;
Cursor centers = db.rawQuery(HockeyPlayer.SELECT_BY_POSITION, new String[] { Center.name() });
的IntelliJ插件
该插件的IntelliJ提供语言级特性为.sq
文件,包括:
- 语法高亮
- 重构/查找用法
- 代码自动完成
-
生成
模式
编辑后的文件
下载
对于摇篮插件:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.squareup.sqldelight:gradle-plugin:0.3.2'
}
}
apply plugin: 'com.squareup.sqldelight'
该插件的IntelliJ可以从Android的工作室通过导航安装
>首选项- - Android电子工作室>插件- >浏览资料库- >搜索SQLDelight
的开发版本(包括IDE插件ZIP)快照是可 Sonatype的的快照
库。