听说GreenDao数据库效率高,那么现在开始使用它。
第一步
配置项目build.gradle,
在对应位置添加:
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.1'
mavenCentral()
修改后的文件:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0-beta4'
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
mavenCentral()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
第二步:
修改module目录下的build.gradle文件:
对应位置添加:
apply plugin: 'org.greenrobot.greendao'
compile 'org.greenrobot:greendao:3.2.0'
修改后的文件:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "xyz.reginer.greendao"
minSdkVersion 18
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.1'
testCompile 'junit:junit:4.12'
compile 'org.greenrobot:greendao:3.2.0'
}
第三步 :
添加greendao的数据库版本号:
生成的操作类可以不指定路径。
greendao {
schemaVersion 1
}
修改后的文件:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "xyz.reginer.greendao"
minSdkVersion 18
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
greendao {
schemaVersion 1
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.1'
testCompile 'junit:junit:4.12'
compile 'org.greenrobot:greendao:3.2.0'
}
第四步:
创建实体类(数据库表,字段)
这里做下注解说明:
@Entity:告诉GreenDao该对象为实体,只有被@Entity注释的Bean类才能被dao类操作
@Id:对象的Id,使用Long类型作为EntityId,否则报错。(autoincrement = true)表示主键会自增,false使用旧值
@Unique:该属性值必须在数据库中是唯一值
@Property:可以自定义字段名,外键不能使用该属性
@NotNull:属性不能为空
@Transient:使用该注释的属性不会被存入数据库的字段中
@Generated:编译后自动生成的构造函数、方法等的注释,提示构造函数、方法等不能被修改
@Entity
public class User {
//不能用int
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "name")
private String name;
@Unique
private String QQ;
private int age;
private String address;
}
build之后:
package xyz.reginer.greendao;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Property;
import org.greenrobot.greendao.annotation.Unique;
import org.greenrobot.greendao.annotation.Generated;
/**
* ----------Dragon be here!----------/
* ┏┓ ┏┓
* ┏┛┻━━━┛┻┓
* ┃ ┃
* ┃ ━ ┃
* ┃ ┳┛ ┗┳ ┃
* ┃ ┃
* ┃ ┻ ┃
* ┃ ┃
* ┗━┓ ┏━┛
* ┃ ┃神兽保佑
* ┃ ┃代码无BUG!
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
* ━━━━━━神兽出没━━━━━━
* 创 建:Reginer in 2017/2/15 11:18.
* 联系方式:QQ:282921012
* 功能描述:bean对象
*/
@Entity
public class User {
//不能用int
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "name")
private String name;
@Unique
private int QQ;
private int age;
private String address;
/**
* 这部分是我创建的
*
* @param name 昵称
* @param QQ QQ
* @param age 年龄
* @param address 住址
*/
public User(String name, int QQ, int age, String address) {
this.name = name;
this.QQ = QQ;
this.age = age;
this.address = address;
}
@Generated(hash = 964878038)
public User(Long id, String name, int QQ, int age, String address) {
this.id = id;
this.name = name;
this.QQ = QQ;
this.age = age;
this.address = address;
}
@Generated(hash = 586692638)
public User() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getQQ() {
return this.QQ;
}
public void setQQ(int QQ) {
this.QQ = QQ;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
}
第五步:
创建数据库帮助类:
public class DbHelper extends DaoMaster.OpenHelper {
public DbHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
super.onUpgrade(db, oldVersion, newVersion);
}
}
第六步:
创建Application类:
public class App extends Application {
private DaoSession daoSession;
@Override
public void onCreate() {
super.onCreate();
DbHelper helper = new DbHelper(this, "user.db", null);
Database db = helper.getWritableDb();
daoSession = new DaoMaster(db).newSession();
}
public DaoSession getDaoSession() {
return daoSession;
}
}
第七步:
正式操作:
增:
private void add() {
//____________________保存一个————————
User user = new User("那时年少", 282921012, 25, "大连");
mUserDao.insert(user);
//____________________保存list————————
List<User> mUsers = new ArrayList<>();
for (int i = 0; i < 50; i++) {
mUsers.add(new User("那时年少" + i, i, 25, "大连"));
}
mUserDao.insertInTx(mUsers);
}
删:
private void del() {
mUserDao.deleteByKey((long) 1);
// 删除单个数据
// mUserDao().delete(user);
// 删除多个数据
// mUserDao().deleteInTx(userList);
}
改:
private void up() {
User user = new User((long) 3, "那时年少", 282921012, 25, "伊拉克");
mUserDao.update(user);
}
查:
private void query() {
//--------------------------查询全部---------
List<User> mUsers = mUserDao.loadAll();
// List< User> mUsers = mUserDao.queryBuilder().list();
//--------------------------条件查询---------
List<User> users = mUserDao.queryBuilder().where(UserDao.Properties.QQ.le(20)).list();
Log.d(TAG, "mUsers.size is:: " + mUsers.size() + "--- users.size is::" + users.size());
}
八:数据库升级:
借用网上一个工具类MigrationHelper:
public class MigrationHelper {
/**
* 调用升级方法
*
* @param db db
* @param daoClasses dao.class
*/
@SafeVarargs
public static void migrate(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
//1 新建临时表
generateTempTables(db, daoClasses);
//2 创建新表
createAllTables(db, false, daoClasses);
//3 临时表数据写入新表,删除临时表
restoreData(db, daoClasses);
}
/**
* 生成临时表,存储旧的表数据
*
* @param db db
* @param daoClasses daoClasses
*/
@SafeVarargs
private static void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
for (Class<? extends AbstractDao<?, ?>> daoClass : daoClasses) {
DaoConfig daoConfig = new DaoConfig(db, daoClass);
String tableName = daoConfig.tablename;
if (!checkTable(db, tableName))
continue;
String tempTableName = daoConfig.tablename.concat("_TEMP");
String insertTableStringBuilder = "alter table " +
tableName +
" rename to " +
tempTableName +
";";
db.execSQL(insertTableStringBuilder);
}
}
/**
* 检测table是否存在
*
* @param db db
* @param tableName tableName
*/
private static Boolean checkTable(Database db, String tableName) {
Cursor c = db.rawQuery("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='" + tableName + "'", null);
if (c.moveToNext()) {
int count = c.getInt(0);
return count > 0;
}
return false;
}
/**
* 创建新的表结构
*
* @param db db
* @param ifNotExists ifNotExists
* @param daoClasses daoClasses
*/
@SafeVarargs
private static void createAllTables(Database db, boolean ifNotExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) {
reflectMethod(db, "createTable", ifNotExists, daoClasses);
}
/**
* 创建根删除都在NoteDao声明了,可以直接拿过来用
* dao class already define the sql exec method, so just invoke it
*/
@SuppressWarnings("unchecked")
private static void reflectMethod(Database db, String methodName, boolean isExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) {
if (daoClasses.length < 1) {
return;
}
try {
for (Class cls : daoClasses) {
//根据方法名,找到声明的方法
Method method = cls.getDeclaredMethod(methodName, Database.class, boolean.class);
method.invoke(null, db, isExists);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 临时表的数据写入新表
*
* @param db db
* @param daoClasses daoClasses
*/
@SafeVarargs
private static void restoreData(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
for (Class<? extends AbstractDao<?, ?>> daoClass : daoClasses) {
DaoConfig daoConfig = new DaoConfig(db, daoClass);
String tableName = daoConfig.tablename;
String tempTableName = daoConfig.tablename.concat("_TEMP");
if (!checkTable(db, tempTableName))
continue;
// get all columns from tempTable, take careful to use the columns list
List<String> columns = getColumns(db, tempTableName);
//新表,临时表都包含的字段
ArrayList<String> properties = new ArrayList<>(columns.size());
for (int j = 0; j < daoConfig.properties.length; j++) {
String columnName = daoConfig.properties[j].columnName;
if (columns.contains(columnName)) {
properties.add(columnName);
}
}
if (properties.size() > 0) {
final String columnSQL = TextUtils.join(",", properties);
String insertTableStringBuilder = "INSERT INTO " + tableName + " (" +
columnSQL +
") SELECT " +
columnSQL +
" FROM " + tempTableName + ";";
db.execSQL(insertTableStringBuilder);
}
db.execSQL("DROP TABLE " + tempTableName);
}
}
private static List<String> getColumns(Database db, String tableName) {
List<String> columns = null;
Cursor cursor = null;
try {
cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 0", null);
if (null != cursor && cursor.getColumnCount() > 0) {
columns = Arrays.asList(cursor.getColumnNames());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null)
cursor.close();
if (null == columns)
columns = new ArrayList<>();
}
return columns;
}
}
在User中添加一个字段girlFriend;
重写升级方法:
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
super.onUpgrade(db, oldVersion, newVersion);
MigrationHelper.migrate(db, UserDao.class);
}
修改数据库版本号 +1:
schemaVersion 2
九:执行数据库语句:
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "user.db", null);
SQLiteDatabase db = helper.getWritableDatabase();
String sql = "这里是语句";
db.execSQL(sql);