七、数据库的升级
GreenDao的OpenHelper下有个onUpgrade(Database db, int oldVersion, int newVersion)方法,当设置的数据库版本改变时,在数据库初始化的时候就会回调到这个方法,我们可以通过继承OpenHelper重写onUpgrade方法来实现数据库更新操作。
数据库的升级思路:
- 创建临时表TMP_,复制原来的数据库到临时表中。
- 删除之前的原表。
- 创建新表。
- 将临时表中的数据复制到新表中,最后将TMP_表删除掉。
//build.gradle(module)
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin
android {
compileSdkVersion 29
buildToolsVersion "29.0.0"
defaultConfig {
applicationId "com.example.sourcecodetest"
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'org.greenrobot:greendao:3.2.2' // add library
}
greendao {
schemaVersion 5 //数据库版本号,原本为3改为5,用于测试数据库升级
daoPackage 'com.example.sourcecodetest.database'
//设置DaoMaster、DaoSession、Dao包名
targetGenDir 'src/main/java' //设置DaoMaster、DaoSession、Dao目录,请注意,这里路径用 / 不要用 .
generateTests false //设置为true以自动生成单元测试
targetGenDirTests 'src/main/java' //应存储生成的单元测试的基本目录。默认为src/androidTest/java
}
//MyApplication
public class MyApplication extends Application {
private static final String TAG = "MyApplication";
private DaoSession daoSession;
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "zwm, onCreate");
initGreenDao();
}
/**
* 初始化GreenDao,直接在Application中进行初始化操作
*/
private void initGreenDao() {
Log.d(TAG, "zwm, initGreenDao");
//DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "tomorrow.db");
MyDaoMaster helper = new MyDaoMaster(this, "tomorrow.db"); //自定义DaoMaster.OpenHelper,用于处理数据库升级
SQLiteDatabase db = helper.getWritableDatabase();
DaoMaster daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession();
}
public DaoSession getDaoSession() {
return daoSession;
}
}
//MyDaoMaster
public class MyDaoMaster extends DaoMaster.OpenHelper {
private static final String TAG = "MyDaoMaster";
public MyDaoMaster(Context context, String name) {
super(context, name);
}
public MyDaoMaster(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
super.onUpgrade(db, oldVersion, newVersion);
Log.d(TAG, "zwm, onUpgrade oldVersion: " + oldVersion + " newVersion: " + newVersion);
MigrationHelper.migrate(db, new MigrationHelper.ReCreateAllTableListener() {
@Override
public void onCreateAllTables(Database db, boolean ifNotExists) {
Log.d(TAG, "zwm, onCreateAllTables, ifNotExists: " + ifNotExists);
DaoMaster.createAllTables(db, ifNotExists);
}
@Override
public void onDropAllTables(Database db, boolean ifExists) {
Log.d(TAG, "zwm, onDropAllTables, ifExists: " + ifExists);
DaoMaster.dropAllTables(db, ifExists);
}
}, StudentDao.class, TeacherDao.class, StudentAndTeacherBeanDao.class);
}
}
//MigrationHelper
public final class MigrationHelper {
public static boolean DEBUG = true;
private static String TAG = "MigrationHelper";
private static final String SQLITE_MASTER = "sqlite_master";
private static final String SQLITE_TEMP_MASTER = "sqlite_temp_master";
private static WeakReference<ReCreateAllTableListener> weakListener;
public interface ReCreateAllTableListener{
void onCreateAllTables(Database db, boolean ifNotExists);
void onDropAllTables(Database db, boolean ifExists);
}
public static void migrate(SQLiteDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
printLog("【The Old Database Version】" + db.getVersion());
Database database = new StandardDatabase(db);
migrate(database, daoClasses);
}
public static void migrate(SQLiteDatabase db, ReCreateAllTableListener listener, Class<? extends AbstractDao<?, ?>>... daoClasses) {
weakListener = new WeakReference<>(listener);
migrate(db, daoClasses);
}
public static void migrate(Database database, ReCreateAllTableListener listener, Class<? extends AbstractDao<?, ?>>... daoClasses) {
weakListener = new WeakReference<>(listener);
migrate(database, daoClasses);
}
public static void migrate(Database database, Class<? extends AbstractDao<?, ?>>... daoClasses) {
printLog("【Generate temp table】start");
generateTempTables(database, daoClasses);
printLog("【Generate temp table】complete");
ReCreateAllTableListener listener = null;
if (weakListener != null) {
listener = weakListener.get();
}
if (listener != null) {
listener.onDropAllTables(database, true);
printLog("【Drop all table by listener】");
listener.onCreateAllTables(database, false);
printLog("【Create all table by listener】");
} else {
dropAllTables(database, true, daoClasses);
createAllTables(database, false, daoClasses);
}
printLog("【Restore data】start");
restoreData(database, daoClasses);
printLog("【Restore data】complete");
}
private static void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
for (int i = 0; i < daoClasses.length; i++) {
String tempTableName = null;
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
String tableName = daoConfig.tablename;
if (!isTableExists(db, false, tableName)) {
printLog("【New Table】" + tableName);
continue;
}
try {
tempTableName = daoConfig.tablename.concat("_TEMP");
StringBuilder dropTableStringBuilder = new StringBuilder();
dropTableStringBuilder.append("DROP TABLE IF EXISTS ").append(tempTableName).append(";");
db.execSQL(dropTableStringBuilder.toString());
StringBuilder insertTableStringBuilder = new StringBuilder();
insertTableStringBuilder.append("CREATE TEMPORARY TABLE ").append(tempTableName);
insertTableStringBuilder.append(" AS SELECT * FROM ").append(tableName).append(";");
db.execSQL(insertTableStringBuilder.toString());
printLog("【Table】" + tableName +"\n ---Columns-->"+getColumnsStr(daoConfig));
printLog("【Generate temp table】" + tempTableName);
} catch (SQLException e) {
Log.e(TAG, "【Failed to generate temp table】" + tempTableName, e);
}
}
}
private static boolean isTableExists(Database db, boolean isTemp, String tableName) {
if (db == null || TextUtils.isEmpty(tableName)) {
return false;
}
String dbName = isTemp ? SQLITE_TEMP_MASTER : SQLITE_MASTER;
String sql = "SELECT COUNT(*) FROM " + dbName + " WHERE type = ? AND name = ?";
Cursor cursor=null;
int count = 0;
try {
cursor = db.rawQuery(sql, new String[]{"table", tableName});
if (cursor == null || !cursor.moveToFirst()) {
return false;
}
count = cursor.getInt(0);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null)
cursor.close();
}
return count > 0;
}
private static String getColumnsStr(DaoConfig daoConfig) {
if (daoConfig == null) {
return "no columns";
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < daoConfig.allColumns.length; i++) {
builder.append(daoConfig.allColumns[i]);
builder.append(",");
}
if (builder.length() > 0) {
builder.deleteCharAt(builder.length() - 1);
}
return builder.toString();
}
private static void dropAllTables(Database db, boolean ifExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) {
reflectMethod(db, "dropTable", ifExists, daoClasses);
printLog("【Drop all table by reflect】");
}
private static void createAllTables(Database db, boolean ifNotExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) {
reflectMethod(db, "createTable", ifNotExists, daoClasses);
printLog("【Create all table by reflect】");
}
/**
* dao class already define the sql exec method, so just invoke it
*/
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 (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
private static void restoreData(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
for (int i = 0; i < daoClasses.length; i++) {
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
String tableName = daoConfig.tablename;
String tempTableName = daoConfig.tablename.concat("_TEMP");
if (!isTableExists(db, true, tempTableName)) {
continue;
}
try {
// get all columns from tempTable, take careful to use the columns list
List<TableInfo> newTableInfos = TableInfo.getTableInfo(db, tableName);
List<TableInfo> tempTableInfos = TableInfo.getTableInfo(db, tempTableName);
ArrayList<String> selectColumns = new ArrayList<>(newTableInfos.size());
ArrayList<String> intoColumns = new ArrayList<>(newTableInfos.size());
for (TableInfo tableInfo : tempTableInfos) {
if (newTableInfos.contains(tableInfo)) {
String column = '`' + tableInfo.name + '`';
intoColumns.add(column);
selectColumns.add(column);
}
}
// NOT NULL columns list
for (TableInfo tableInfo : newTableInfos) {
if (tableInfo.notnull && !tempTableInfos.contains(tableInfo)) {
String column = '`' + tableInfo.name + '`';
intoColumns.add(column);
String value;
if (tableInfo.dfltValue != null) {
value = "'" + tableInfo.dfltValue + "' AS ";
} else {
value = "'' AS ";
}
selectColumns.add(value + column);
}
}
if (intoColumns.size() != 0) {
StringBuilder insertTableStringBuilder = new StringBuilder();
insertTableStringBuilder.append("REPLACE INTO ").append(tableName).append(" (");
insertTableStringBuilder.append(TextUtils.join(",", intoColumns));
insertTableStringBuilder.append(") SELECT ");
insertTableStringBuilder.append(TextUtils.join(",", selectColumns));
insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");
db.execSQL(insertTableStringBuilder.toString());
printLog("【Restore data】 to " + tableName);
}
StringBuilder dropTableStringBuilder = new StringBuilder();
dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);
db.execSQL(dropTableStringBuilder.toString());
printLog("【Drop temp table】" + tempTableName);
} catch (SQLException e) {
Log.e(TAG, "【Failed to restore data from temp table 】" + tempTableName, e);
}
}
}
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;
}
private static void printLog(String info){
if(DEBUG){
Log.d(TAG, "zwm, " + info);
}
}
private static class TableInfo {
int cid;
String name;
String type;
boolean notnull;
String dfltValue;
boolean pk;
@Override
public boolean equals(Object o) {
return this == o
|| o != null
&& getClass() == o.getClass()
&& name.equals(((TableInfo) o).name);
}
@Override
public String toString() {
return "TableInfo{" +
"cid=" + cid +
", name='" + name + '\'' +
", type='" + type + '\'' +
", notnull=" + notnull +
", dfltValue='" + dfltValue + '\'' +
", pk=" + pk +
'}';
}
private static List<TableInfo> getTableInfo(Database db, String tableName) {
String sql = "PRAGMA table_info(" + tableName + ")";
printLog(sql);
Cursor cursor = db.rawQuery(sql, null);
if (cursor == null)
return new ArrayList<>();
TableInfo tableInfo;
List<TableInfo> tableInfos = new ArrayList<>();
while (cursor.moveToNext()) {
tableInfo = new TableInfo();
tableInfo.cid = cursor.getInt(0);
tableInfo.name = cursor.getString(1);
tableInfo.type = cursor.getString(2);
tableInfo.notnull = cursor.getInt(3) == 1;
tableInfo.dfltValue = cursor.getString(4);
tableInfo.pk = cursor.getInt(5) == 1;
tableInfos.add(tableInfo);
// printLog(tableName + ":" + tableInfo);
}
cursor.close();
return tableInfos;
}
}
}
//Student
@Entity
public class Student {
@Id(autoincrement = true)
private Long id;
@Unique
private long studentNo; //学号
private int age; //年龄
private String telPhone; //手机号
private String sex; //性别
private String name; //姓名
private String address; //家庭住址
private String schoolName; //学校名字
private String grade; //几年级
private boolean addNewField; //增加的新列,用于测试数据库升级
@ToMany
@JoinEntity(entity = StudentAndTeacherBean.class,sourceProperty = "studentId",targetProperty = "teacherId")
List<Teacher> teacherList;
}
//MainActivity
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
//insert(); //插入数据后注释掉,用于测试数据库升级
List<Student> list = loadStudents();
for(Student student : list) {
Log.d(TAG, "zwm, student NO." + student.getStudentNo() + ", _id: " + student.getId() + ", age: " + student.getAge() + ", name: " + student.getName());
Log.d(TAG, "zwm, student newField: " + student.getAddNewField());
List<Teacher> teacherList = student.getTeacherList();
Log.d(TAG, "zwm, teacherList.size: " + teacherList.size());
if(teacherList != null && teacherList.size() > 0) {
for(Teacher teacher : teacherList) {
Log.d(TAG, "zwm, teacher NO." + teacher.getTeacherNo() + ", _id: " + teacher.getId() + ", age: " + teacher.getAge() + ", name: " + teacher.getName());
}
}
}
List<Teacher> list2 = loadTeachers();
for(Teacher teacher : list2) {
Log.d(TAG, "zwm, teacher NO." + teacher.getTeacherNo() + ", _id: " + teacher.getId() + ", age: " + teacher.getAge() + ", name: " + teacher.getName());
List<Student> studentList = teacher.getStudentList();
Log.d(TAG, "zwm, studentList.size: " + studentList.size());
if(studentList != null && studentList.size() > 0) {
for(Student student : studentList) {
Log.d(TAG, "zwm, student NO." + student.getStudentNo() + ", _id: " + student.getId() + ", age: " + student.getAge() + ", name: " + student.getName());
}
}
}
}
public void insert() {
Log.d(TAG, "zwm, insert");
DaoSession daoSession = ((MyApplication) getApplication()).getDaoSession();
Student student = new Student();
student.setStudentNo(5551);
student.setAge(18);
student.setTelPhone("5524307");
student.setName("学生1");
student.setSex("男");
student.setAddress("广州");
student.setGrade("一");
student.setSchoolName("大学");
daoSession.insert(student);
Student student2 = new Student();
student2.setStudentNo(5552);
student2.setAge(19);
student2.setTelPhone("5524308");
student2.setName("学生2");
student2.setSex("男");
student2.setAddress("深圳");
student2.setGrade("二");
student2.setSchoolName("大学");
daoSession.insert(student2);
Student student3 = new Student();
student3.setStudentNo(5553);
student3.setAge(20);
student3.setTelPhone("5524309");
student3.setName("学生3");
student3.setSex("男");
student3.setAddress("北京");
student3.setGrade("三");
student3.setSchoolName("大学");
daoSession.insert(student3);
Teacher teacher1 = new Teacher();
teacher1.setTeacherNo(9991);
teacher1.setAge(28);
teacher1.setTelPhone("9924307");
teacher1.setName("教师1");
teacher1.setSex("男");
teacher1.setSubject("语文");
teacher1.setSchoolName("大学");
daoSession.insert(teacher1);
Teacher teacher2 = new Teacher();
teacher2.setTeacherNo(9992);
teacher2.setAge(29);
teacher2.setTelPhone("9924308");
teacher2.setName("教师2");
teacher2.setSex("男");
teacher2.setSubject("数学");
teacher2.setSchoolName("大学");
daoSession.insert(teacher2);
Teacher teacher3 = new Teacher();
teacher3.setTeacherNo(9993);
teacher3.setAge(30);
teacher3.setTelPhone("9924309");
teacher3.setName("教师3");
teacher3.setSex("男");
teacher3.setSubject("英语");
teacher3.setSchoolName("大学");
daoSession.insert(teacher3);
StudentAndTeacherBean studentAndTeacher = new StudentAndTeacherBean();
studentAndTeacher.setStudentId(Long.valueOf(1));
studentAndTeacher.setTeacherId(Long.valueOf(1));
daoSession.insert(studentAndTeacher);
StudentAndTeacherBean studentAndTeacher2 = new StudentAndTeacherBean();
studentAndTeacher2.setStudentId(Long.valueOf(1));
studentAndTeacher2.setTeacherId(Long.valueOf(2));
daoSession.insert(studentAndTeacher2);
StudentAndTeacherBean studentAndTeacher3 = new StudentAndTeacherBean();
studentAndTeacher3.setStudentId(Long.valueOf(2));
studentAndTeacher3.setTeacherId(Long.valueOf(1));
daoSession.insert(studentAndTeacher3);
StudentAndTeacherBean studentAndTeacher4 = new StudentAndTeacherBean();
studentAndTeacher4.setStudentId(Long.valueOf(2));
studentAndTeacher4.setTeacherId(Long.valueOf(3));
daoSession.insert(studentAndTeacher4);
StudentAndTeacherBean studentAndTeacher5 = new StudentAndTeacherBean();
studentAndTeacher5.setStudentId(Long.valueOf(3));
studentAndTeacher5.setTeacherId(Long.valueOf(1));
daoSession.insert(studentAndTeacher5);
StudentAndTeacherBean studentAndTeacher6 = new StudentAndTeacherBean();
studentAndTeacher6.setStudentId(Long.valueOf(3));
studentAndTeacher6.setTeacherId(Long.valueOf(2));
daoSession.insert(studentAndTeacher6);
StudentAndTeacherBean studentAndTeacher7 = new StudentAndTeacherBean();
studentAndTeacher7.setStudentId(Long.valueOf(3));
studentAndTeacher7.setTeacherId(Long.valueOf(3));
daoSession.insert(studentAndTeacher7);
}
public List<Student> loadStudents(){
Log.d(TAG, "zwm, loadStudents");
DaoSession daoSession = ((MyApplication) getApplication()).getDaoSession();
List<Student> students = daoSession.loadAll(Student.class);
return students;
}
public List<Teacher> loadTeachers(){
Log.d(TAG, "zwm, loadTeachers");
DaoSession daoSession = ((MyApplication) getApplication()).getDaoSession();
List<Teacher> teachers = daoSession.loadAll(Teacher.class);
return teachers;
}
}
//输出log
2020-01-08 19:45:42.461 29277-29277/com.example.sourcecodetest D/MyApplication: zwm, onCreate
2020-01-08 19:45:42.461 29277-29277/com.example.sourcecodetest D/MyApplication: zwm, initGreenDao
2020-01-08 19:45:42.889 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, onCreate
2020-01-08 19:45:42.889 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, insert
2020-01-08 19:45:43.046 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, loadStudents
2020-01-08 19:45:43.051 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, student NO.5551, _id: 1, age: 18, name: 学生1
2020-01-08 19:45:43.051 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, student newField: false
2020-01-08 19:45:43.061 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, teacherList.size: 2
2020-01-08 19:45:43.061 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9991, _id: 1, age: 28, name: 教师1
2020-01-08 19:45:43.062 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9992, _id: 2, age: 29, name: 教师2
2020-01-08 19:45:43.062 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, student NO.5552, _id: 2, age: 19, name: 学生2
2020-01-08 19:45:43.062 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, student newField: false
2020-01-08 19:45:43.067 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, teacherList.size: 2
2020-01-08 19:45:43.068 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9991, _id: 1, age: 28, name: 教师1
2020-01-08 19:45:43.068 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9993, _id: 3, age: 30, name: 教师3
2020-01-08 19:45:43.068 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, student NO.5553, _id: 3, age: 20, name: 学生3
2020-01-08 19:45:43.069 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, student newField: false
2020-01-08 19:45:43.072 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, teacherList.size: 3
2020-01-08 19:45:43.072 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9991, _id: 1, age: 28, name: 教师1
2020-01-08 19:45:43.072 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9992, _id: 2, age: 29, name: 教师2
2020-01-08 19:45:43.072 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9993, _id: 3, age: 30, name: 教师3
2020-01-08 19:45:43.072 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, loadTeachers
2020-01-08 19:45:43.076 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9991, _id: 1, age: 28, name: 教师1
2020-01-08 19:45:43.080 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, studentList.size: 3
2020-01-08 19:45:43.080 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, student NO.5551, _id: 1, age: 18, name: 学生1
2020-01-08 19:45:43.080 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, student NO.5552, _id: 2, age: 19, name: 学生2
2020-01-08 19:45:43.080 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, student NO.5553, _id: 3, age: 20, name: 学生3
2020-01-08 19:45:43.080 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9992, _id: 2, age: 29, name: 教师2
2020-01-08 19:45:43.084 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, studentList.size: 2
2020-01-08 19:45:43.085 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, student NO.5551, _id: 1, age: 18, name: 学生1
2020-01-08 19:45:43.085 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, student NO.5553, _id: 3, age: 20, name: 学生3
2020-01-08 19:45:43.085 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9993, _id: 3, age: 30, name: 教师3
2020-01-08 19:45:43.088 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, studentList.size: 2
2020-01-08 19:45:43.088 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, student NO.5552, _id: 2, age: 19, name: 学生2
2020-01-08 19:45:43.088 29277-29277/com.example.sourcecodetest D/MainActivity: zwm, student NO.5553, _id: 3, age: 20, name: 学生3
2020-01-08 19:49:37.030 30214-30214/com.example.sourcecodetest D/MyApplication: zwm, onCreate
2020-01-08 19:49:37.030 30214-30214/com.example.sourcecodetest D/MyApplication: zwm, initGreenDao
2020-01-08 19:49:37.153 30214-30214/com.example.sourcecodetest D/MyDaoMaster: zwm, onUpgrade oldVersion: 3 newVersion: 5
2020-01-08 19:49:37.154 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Generate temp table】start
2020-01-08 19:49:37.167 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Table】STUDENT
---Columns-->_id,STUDENT_NO,AGE,TEL_PHONE,SEX,NAME,ADDRESS,SCHOOL_NAME,GRADE,ADD_NEW_FIELD
2020-01-08 19:49:37.167 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Generate temp table】STUDENT_TEMP
2020-01-08 19:49:37.173 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Table】TEACHER
---Columns-->_id,TEACHER_NO,AGE,SEX,TEL_PHONE,NAME,SCHOOL_NAME,SUBJECT
2020-01-08 19:49:37.174 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Generate temp table】TEACHER_TEMP
2020-01-08 19:49:37.186 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Table】STUDENT_AND_TEACHER_BEAN
---Columns-->_id,STUDENT_ID,TEACHER_ID
2020-01-08 19:49:37.186 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Generate temp table】STUDENT_AND_TEACHER_BEAN_TEMP
2020-01-08 19:49:37.186 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Generate temp table】complete
2020-01-08 19:49:37.186 30214-30214/com.example.sourcecodetest D/MyDaoMaster: zwm, onDropAllTables, ifExists: true
2020-01-08 19:49:37.195 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Drop all table by listener】
2020-01-08 19:49:37.196 30214-30214/com.example.sourcecodetest D/MyDaoMaster: zwm, onCreateAllTables, ifNotExists: false
2020-01-08 19:49:37.202 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Create all table by listener】
2020-01-08 19:49:37.202 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Restore data】start
2020-01-08 19:49:37.205 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, PRAGMA table_info(STUDENT)
2020-01-08 19:49:37.208 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, PRAGMA table_info(STUDENT_TEMP)
2020-01-08 19:49:37.212 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Restore data】 to STUDENT
2020-01-08 19:49:37.213 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Drop temp table】STUDENT_TEMP
2020-01-08 19:49:37.216 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, PRAGMA table_info(TEACHER)
2020-01-08 19:49:37.220 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, PRAGMA table_info(TEACHER_TEMP)
2020-01-08 19:49:37.228 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Restore data】 to TEACHER
2020-01-08 19:49:37.230 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Drop temp table】TEACHER_TEMP
2020-01-08 19:49:37.233 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, PRAGMA table_info(STUDENT_AND_TEACHER_BEAN)
2020-01-08 19:49:37.237 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, PRAGMA table_info(STUDENT_AND_TEACHER_BEAN_TEMP)
2020-01-08 19:49:37.241 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Restore data】 to STUDENT_AND_TEACHER_BEAN
2020-01-08 19:49:37.242 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Drop temp table】STUDENT_AND_TEACHER_BEAN_TEMP
2020-01-08 19:49:37.242 30214-30214/com.example.sourcecodetest D/MigrationHelper: zwm, 【Restore data】complete
2020-01-08 19:49:37.591 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, onCreate
2020-01-08 19:49:37.592 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, loadStudents
2020-01-08 19:49:37.598 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, student NO.5551, _id: 1, age: 18, name: 学生1
2020-01-08 19:49:37.598 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, student newField: false
2020-01-08 19:49:37.608 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, teacherList.size: 2
2020-01-08 19:49:37.608 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9991, _id: 1, age: 28, name: 教师1
2020-01-08 19:49:37.608 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9992, _id: 2, age: 29, name: 教师2
2020-01-08 19:49:37.608 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, student NO.5552, _id: 2, age: 19, name: 学生2
2020-01-08 19:49:37.608 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, student newField: false
2020-01-08 19:49:37.612 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, teacherList.size: 2
2020-01-08 19:49:37.612 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9991, _id: 1, age: 28, name: 教师1
2020-01-08 19:49:37.612 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9993, _id: 3, age: 30, name: 教师3
2020-01-08 19:49:37.612 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, student NO.5553, _id: 3, age: 20, name: 学生3
2020-01-08 19:49:37.612 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, student newField: false
2020-01-08 19:49:37.616 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, teacherList.size: 3
2020-01-08 19:49:37.617 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9991, _id: 1, age: 28, name: 教师1
2020-01-08 19:49:37.617 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9992, _id: 2, age: 29, name: 教师2
2020-01-08 19:49:37.617 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9993, _id: 3, age: 30, name: 教师3
2020-01-08 19:49:37.618 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, loadTeachers
2020-01-08 19:49:37.623 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9991, _id: 1, age: 28, name: 教师1
2020-01-08 19:49:37.628 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, studentList.size: 3
2020-01-08 19:49:37.632 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, student NO.5551, _id: 1, age: 18, name: 学生1
2020-01-08 19:49:37.632 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, student NO.5552, _id: 2, age: 19, name: 学生2
2020-01-08 19:49:37.633 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, student NO.5553, _id: 3, age: 20, name: 学生3
2020-01-08 19:49:37.633 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9992, _id: 2, age: 29, name: 教师2
2020-01-08 19:49:37.637 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, studentList.size: 2
2020-01-08 19:49:37.637 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, student NO.5551, _id: 1, age: 18, name: 学生1
2020-01-08 19:49:37.637 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, student NO.5553, _id: 3, age: 20, name: 学生3
2020-01-08 19:49:37.637 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9993, _id: 3, age: 30, name: 教师3
2020-01-08 19:49:37.641 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, studentList.size: 2
2020-01-08 19:49:37.641 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, student NO.5552, _id: 2, age: 19, name: 学生2
2020-01-08 19:49:37.641 30214-30214/com.example.sourcecodetest D/MainActivity: zwm, student NO.5553, _id: 3, age: 20, name: 学生3
自定义SQLiteOpenHelper处理数据库升级(用于参考)
//MusicDBHelper
final class MusicDBHelper extends SQLiteOpenHelper {
private static final String TAG = MusicProvider.class.getSimpleName();
final Context mContext;
/*
* naming style 50 001 OS version local version.
*/
public static final int DATABASE_VERSION = 20091;
private static volatile MusicDBHelper sInstance;
public static synchronized MusicDBHelper getInstance(Context context) {
if (sInstance == null) {
synchronized (MusicDBHelper.class) {
if (sInstance == null) {
sInstance = new MusicDBHelper(context);
}
}
}
return sInstance;
}
private MusicDBHelper(Context context) {
super(context, MusicDBInfo.PRIMARY_DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
iLog.d("MusicDBHelper", "()");
}
@Override
public void onCreate(final SQLiteDatabase db) {
iLog.d("MusicDBHelper", "onCreate");
updateDatabase(mContext, db, 0, DATABASE_VERSION);
}
@Override
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
iLog.d("MusicDBHelper",
"onUpgrade : oldVersion = " + oldVersion + ", newVersion = " + newVersion);
updateDatabase(mContext, db, oldVersion, newVersion);
}
/**
* This method takes care of updating all the tables in the database to the
* current version, creating them if necessary.
*
* @param db Database
*/
private static void updateDatabase(Context context, SQLiteDatabase db, int fromVersion,
int toVersion) {
iLog.d(TAG, String.format(Locale.US, "updateDatabase fromVersion[%d], toVersion[%d])",
fromVersion, toVersion));
if (fromVersion > toVersion) {
iLog.e(TAG, "Illegal update request: can't downgrade from " + fromVersion + " to " +
toVersion + ". Did you forget to wipe data?");
throw new IllegalArgumentException();
}
if (fromVersion < 1) {
// create audio_meta table
// createAudioTable(db);
createDLNATable(db);
}
if (fromVersion < 10001) {
// Drop audio View for Store. From this verion, only use audio_meta
// table.
db.execSQL("DROP VIEW IF EXISTS audio");
db.execSQL("DROP TABLE IF EXISTS album_art");
db.execSQL("DROP VIEW IF EXISTS audio_with_albumart");
db.execSQL("DROP VIEW IF EXISTS album_info");
db.execSQL("DROP VIEW IF EXISTS artist_info");
db.execSQL("DROP VIEW IF EXISTS music_folders_view");
db.execSQL("DROP VIEW IF EXISTS searchhelpertitle");
db.execSQL("DROP TABLE IF EXISTS audio_playlists");
db.execSQL("DROP TABLE IF EXISTS audio_playlists_map");
db.execSQL("DROP TABLE IF EXISTS audio_playlists_map_cache");
db.execSQL("DROP TABLE IF EXISTS download_queue");
db.execSQL("DROP TABLE IF EXISTS dlna_dms_contents_table");
db.execSQL("DROP TABLE IF EXISTS inventory");
db.execSQL("DROP TABLE IF EXISTS remote_songs");
db.execSQL("DROP VIEW IF EXISTS remote_songs_view");
// for removing useless column
// db.execSQL("CREATE TABLE IF NOT EXISTS audio_meta2 ("
// + MusicDBInfo.AUDIO_TABLE_COLUMNS_DEFINITION_V1 + ");");
// // copy data from old table
// db.execSQL("INSERT OR REPLACE INTO audio_meta2 ("
// + MusicDBInfo.AUDIO_TABLE_COLUMNS + ") SELECT "
// + MusicDBInfo.AUDIO_TABLE_COLUMNS + " FROM audio_meta;");
db.execSQL("DROP TABLE IF EXISTS audio_meta");
// db.execSQL("ALTER TABLE audio_meta2 RENAME TO audio_meta;");
}
// 1st release's db version is 20061
if (fromVersion < 20061) {
// For base table
createAudioTable(db);
createPlaylistTable(db);
createMusicDBInfoTable(db);
// For Online
createOnlineTable(db);
// For CardView
createMusicCacheMapTable(db);
}
if (fromVersion < 20062) {
db.execSQL("AlTER TABLE " + MusicDBInfo.AUDIO_PLAYLIST_TABLE_NAME +
" ADD COLUMN server_id INTEGER;");
db.execSQL("AlTER TABLE " + MusicDBInfo.AUDIO_PLAYLIST_TABLE_NAME +
" ADD COLUMN sync_state INTEGER;");
db.execSQL("AlTER TABLE " + MusicDBInfo.AUDIO_PLAYLIST_TABLE_NAME +
" ADD COLUMN track_sync_state INTEGER;");
}
if (fromVersion < 20064) {
// create audio_meta_helper table to sync local contents.
db.execSQL("DROP TABLE IF EXISTS audio_meta_helper");
db.execSQL("CREATE TABLE audio_meta_helper AS SELECT * FROM audio_meta WHERE _id < 1");
}
if (fromVersion < 20065) {
db.execSQL("DROP TABLE IF EXISTS audio_meta_helper");
}
if (fromVersion < 20066) {
db.execSQL("DROP TABLE IF EXISTS " + OnlineTracks.MAP_TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineTracks.MAP_TABLE_NAME + " (" +
OnlineTracks.SCHEMA_COLUMNS_DEFINITION + ");");
}
if (fromVersion < 20067) {
db.execSQL("DROP TABLE IF EXISTS " + OnlineBanner.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineBanner.TABLE_NAME + " (" +
OnlineBanner.SCHEMA_COLUMNS_DEFINITION + ");");
}
if (fromVersion < 20068) {
createMusicDBInfoTable(db);
}
if (fromVersion < 20069) {
// recreate online topic
db.execSQL("DROP TABLE IF EXISTS " + OnlineTopics.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineTopics.TABLE_NAME + " (" +
OnlineTopics.SCHEMA_COLUMNS_DEFINITION + ");");
}
if (fromVersion < 20070) {
db.execSQL("DROP TABLE IF EXISTS " + OnlineBanner.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineBanner.TABLE_NAME + " (" +
OnlineBanner.SCHEMA_COLUMNS_DEFINITION + ");");
}
if (fromVersion < 20071) {
createMusicDBInfoTable(db);
db.execSQL("INSERT INTO " + MusicDBInfo.DBSyncInfo.TABLE_NAME + " values('" +
MusicDBInfo.DBSyncInfo.CP_MEDIA_PROVIDER + "', '" +
String.valueOf(System.currentTimeMillis()) + "', '" +
new SimpleDateFormat("MM-dd hh:mm:ss.SSS").format(new Date()).toString() +
"', '0', '', '" + Locale.getDefault().toString() + "');");
}
if (fromVersion < 20072) {
db.execSQL("DROP TABLE IF EXISTS " + OnlineRank.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineRank.TABLE_NAME + " (" +
OnlineRank.SCHEMA_COLUMNS_DEFINITION + ");");
}
if (fromVersion < 20073) {
createRadioCategory(db);
}
if (fromVersion < 20074) {
createDbIndex(db);
}
if (fromVersion < 20075) {
db.execSQL("DELETE FROM smusic_db_info WHERE " +
"sync_content_type = 'online_ultimate_radio_category';");
db.execSQL("DROP TABLE IF EXISTS " + OnlineRadioCategory.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineRadioCategory.TABLE_NAME + " (" +
OnlineRadioCategory.SCHEMA_COLUMNS_DEFINITION + ");");
}
if (fromVersion < 20076) {
if (AppFeatures.REGIONAL_CHN_PINYIN_ENABLED) {
try {
db.execSQL("ALTER TABLE audio_meta ADD COLUMN title_pinyin TEXT;");
db.execSQL(
"ALTER TABLE audio_meta ADD COLUMN genre_name_pinyin TEXT default '<unknown>';");
db.execSQL(
"ALTER TABLE audio_meta ADD COLUMN composer_pinyin TEXT default '<unknown>';");
db.execSQL("ALTER TABLE audio_meta ADD COLUMN _display_name_pinyin TEXT;");
db.execSQL(
"ALTER TABLE audio_meta ADD COLUMN bucket_display_name_pinyin TEXT;");
db.execSQL(
"ALTER TABLE audio_meta ADD COLUMN artist_pinyin TEXT default '<unknown>';");
db.execSQL(
"ALTER TABLE audio_meta ADD COLUMN album_pinyin TEXT default '<unknown>';");
db.execSQL("ALTER TABLE audio_meta ADD COLUMN artist_search_key TEXT;");
db.execSQL("ALTER TABLE audio_meta ADD COLUMN album_search_key TEXT;");
db.execSQL("ALTER TABLE audio_meta ADD COLUMN title_search_key TEXT;");
db.execSQL("ALTER TABLE audio_playlists ADD COLUMN name_pinyin TEXT;");
} catch (SQLiteException e) {
iLog.e(TAG, "duplicate column :" + e.toString());
}
db.execSQL("UPDATE audio_meta SET date_modified = 0 WHERE content_location = 1;");
}
}
if (fromVersion < 20078) {
// constraint is changed - artist_id -> (artist_id, artist_category_id)
db.execSQL("DROP TABLE IF EXISTS " + OnlineArtists.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineArtists.TABLE_NAME + " (" +
OnlineArtists.SCHEMA_COLUMNS_DEFINITION + ");");
}
if (fromVersion < 20079) {
// For local view
createArtistMapView(db);
createSearchHelperTitleView(db);
}
if (fromVersion < 20080) {
db.execSQL("DROP TABLE IF EXISTS " + MusicDBInfo.AUDIO_PLAYLISTS_MAP_CACHE_TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " +
MusicDBInfo.AUDIO_PLAYLISTS_MAP_CACHE_TABLE_NAME + " (" +
MusicDBInfo.PLAYLIST_MAP_CACHE_TABLE_COLUMNS_DEFINITION + ");");
}
if (fromVersion < 20081) {
createOnlineFmCategory(db);
}
if (fromVersion < 20083) {
recreateTableWithCpAttrsColumn(db);
createAlbumInfoView(db);
createArtistInfoView(db);
createGenresInfoView(db);
createFolderInfoView(db);
createComposerInfoView(db);
createSearchView(db);
}
if (fromVersion < 20084) {
db.execSQL("update audio_meta SET date_modified = 0");
// @formatter:off
// Cleans up when an audio file is deleted
db.execSQL("CREATE TRIGGER IF NOT EXISTS audio_meta_cleanup DELETE ON audio_meta "
+ "BEGIN "
+ " DELETE FROM audio_playlists_map WHERE audio_id = old._id;"
+ "END");
// for categorized tracks trigger.
// Cleans up when an audio file is deleted
db.execSQL("CREATE TRIGGER IF NOT EXISTS audio_meta_categorized_tracks_map_trigger DELETE ON audio_meta "
+ "BEGIN "
+ " DELETE FROM " + OnlineTracks.MAP_TABLE_NAME
+ " WHERE audio_id = old._id;"
+ "END");
// @formatter:on
}
if (fromVersion < 20085) {
db.execSQL(
"DELETE FROM audio_playlists_map WHERE audio_id NOT IN (SELECT _id FROM audio_meta)");
}
if (fromVersion < 20086) {
db.execSQL("DROP TABLE IF EXISTS online_cache_tracks");
}
if (fromVersion < 20087) {
createDownloadTable(db);
}
if (fromVersion < 20088) {
db.execSQL("AlTER TABLE " + MusicDBInfo.AUDIO_TABLE_NAME +
" ADD COLUMN drm_type INTEGER;");
}
if (fromVersion < 20089) {
// streaming cache table has been move to external streaming cache db.
db.execSQL("DROP TABLE IF EXISTS streaming_cache_table");
}
if (fromVersion < 20090) {
MusicSyncService.sync(context, MusicSyncService.EVENT_SYNC_DOWNLOADED);
}
if (fromVersion < 20091) {
createAlbumInfoView(db);
createSearchView(db);
}
}
private static void createPlaylistTable(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + MusicDBInfo.AUDIO_PLAYLIST_TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + MusicDBInfo.AUDIO_PLAYLISTS_MAP_TABLE_NAME);
// Contains audio playlist definitions
db.execSQL("CREATE TABLE IF NOT EXISTS " + MusicDBInfo.AUDIO_PLAYLIST_TABLE_NAME + " (" +
MusicDBInfo.PLAYLIST_TABLE_COLUMNS_DEFINITION + ");");
// Contains mappings between audio playlists and audio files
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + MusicDBInfo.AUDIO_PLAYLISTS_MAP_TABLE_NAME + " (" +
MusicDBInfo.PLAYLIST_MAP_TABLE_COLUMNS_DEFINITION + ");");
// @formatter:off
// Cleans up when an audio playlist is deleted
db.execSQL("CREATE TRIGGER IF NOT EXISTS audio_playlists_cleanup DELETE ON audio_playlists "
+ "BEGIN "
+ " DELETE FROM audio_playlists_map WHERE playlist_id = old._id;"
+ " SELECT _DELETE_FILE(old._data);"
+ "END");
// Cleans up when an audio file is deleted
db.execSQL("CREATE TRIGGER IF NOT EXISTS audio_meta_cleanup DELETE ON audio_meta "
+ "BEGIN "
+ " DELETE FROM audio_playlists_map WHERE audio_id = old._id;"
+ "END");
// @formatter:on
}
private static void createMusicCacheMapTable(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + MusicDBInfo.MusicCacheMap.MAP_TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + MusicDBInfo.MusicCacheMap.MAP_TABLE_NAME + " (" +
MusicDBInfo.MusicCacheMap.SCHEMA_COLUMNS_DEFINITION_V1 + ");");
}
private static void createDLNATable(SQLiteDatabase db) {
// create all share table
db.execSQL("DROP TABLE IF EXISTS " + MusicDBInfo.DLNA_TABLE_NAME);
db.execSQL("CREATE TABLE " + MusicDBInfo.DLNA_TABLE_NAME + " (" +
MusicDBInfo.DLNA_TABLE_COLUMNS_DEFINITION + ");");
// create all share open intent table
db.execSQL("DROP TABLE IF EXISTS " + MusicDBInfo.DLNA_OPEN_INTENT_CONTENTS_TABLE_NAME);
db.execSQL("CREATE TABLE " + MusicDBInfo.DLNA_OPEN_INTENT_CONTENTS_TABLE_NAME + " (" +
MusicDBInfo.DLNA_TABLE_COLUMNS_DEFINITION + ");");
// create all share provider table
db.execSQL("DROP TABLE IF EXISTS " + MusicDBInfo.DLNA_PROVIDER_TABLE_NAME);
db.execSQL("CREATE TABLE " + MusicDBInfo.DLNA_PROVIDER_TABLE_NAME + " (" +
MusicDBInfo.DLNA_PROVIDER_TABLE_COLUMNS_DEFINITION + ");");
// create all share avplayer table
db.execSQL("DROP TABLE IF EXISTS " + MusicDBInfo.DLNA_AVPLAYER_TABLE_NAME);
db.execSQL("CREATE TABLE " + MusicDBInfo.DLNA_AVPLAYER_TABLE_NAME + " (" +
MusicDBInfo.DLNA_AVPLAYER_TABLE_COLUMNS_DEFINITION + ");");
// album art Table for DLNA
db.execSQL("DROP TABLE IF EXISTS dlna_album_art");
db.execSQL("CREATE TABLE IF NOT EXISTS dlna_album_art (" + "album_id INTEGER PRIMARY KEY," +
"album_art TEXT" + ");");
}
static final String SEC_PLAYLIST_COLUMNS_ADDED = ",mini_thumb_data";
private static void createAudioTable(SQLiteDatabase db) {
iLog.d(TAG, "createAudioTable");
db.execSQL("DROP TABLE IF EXISTS " + MusicDBInfo.AUDIO_TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + MusicDBInfo.AUDIO_TABLE_NAME + " (" +
MusicDBInfo.AUDIO_TABLE_COLUMNS_DEFINITION_V1 + ");");
db.execSQL("DROP VIEW IF EXISTS " + MusicDBInfo.AUDIO_VIEW_NAME);
db.execSQL("CREATE VIEW " + MusicDBInfo.AUDIO_VIEW_NAME + " AS SELECT * FROM " +
MusicDBInfo.AUDIO_TABLE_NAME);
}
private static void createMusicDBInfoTable(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + MusicDBInfo.DBSyncInfo.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + MusicDBInfo.DBSyncInfo.TABLE_NAME + " (" +
MusicDBInfo.DBSyncInfo.SCHEMA_COLUMNS_DEFINITION + ");");
}
private static void createAlbumInfoView(SQLiteDatabase db) {
iLog.d(TAG, "createAlbumInfoView");
db.execSQL("DROP VIEW IF EXISTS " + MusicDBInfo.ALBUM_INFO_VIEW_NAME);
db.execSQL("CREATE VIEW IF NOT EXISTS " + MusicDBInfo.ALBUM_INFO_VIEW_NAME + " AS " +
MusicDBInfo.VIEW_ALBUM_INFO_QUERY);
}
private static void createArtistInfoView(SQLiteDatabase db) {
iLog.d(TAG, "createArtistInfoView");
db.execSQL("DROP VIEW IF EXISTS " + MusicDBInfo.ARTIST_INFO_VIEW_NAME);
db.execSQL("CREATE VIEW IF NOT EXISTS " + MusicDBInfo.ARTIST_INFO_VIEW_NAME + " AS " +
MusicDBInfo.VIEW_ARTIST_INFO_QUERY);
}
private static void createArtistMapView(SQLiteDatabase db) {
iLog.d(TAG, "createArtistMapView");
db.execSQL("DROP VIEW IF EXISTS " + MusicDBInfo.ARTIST_ALBUM_MAP_VIEW_NAME);
db.execSQL("CREATE VIEW IF NOT EXISTS " + MusicDBInfo.ARTIST_ALBUM_MAP_VIEW_NAME + " AS " +
MusicDBInfo.VIEW_ARTIST_ALBUM_MAP_QUERY);
}
private static void createComposerInfoView(SQLiteDatabase db) {
iLog.d(TAG, "createComposerInfoView");
db.execSQL("DROP VIEW IF EXISTS " + MusicDBInfo.COMPOSER_INFO_VIEW_NAME);
db.execSQL("CREATE VIEW IF NOT EXISTS " + MusicDBInfo.COMPOSER_INFO_VIEW_NAME + " AS " +
MusicDBInfo.VIEW_COMPOSER_INFO_QUERY);
}
private static void createFolderInfoView(SQLiteDatabase db) {
iLog.d(TAG, "createFolderInfoView");
db.execSQL("DROP VIEW IF EXISTS " + MusicDBInfo.FOLDER_INFO_VIEW_NAME);
db.execSQL("CREATE VIEW IF NOT EXISTS " + MusicDBInfo.FOLDER_INFO_VIEW_NAME + " AS " +
MusicDBInfo.VIEW_FOLDER_INFO_QUERY);
}
private static void createGenresInfoView(SQLiteDatabase db) {
iLog.d(TAG, "createFolderInfoView");
db.execSQL("DROP VIEW IF EXISTS " + MusicDBInfo.GENRES_INFO_VIEW_NAME);
db.execSQL("CREATE VIEW IF NOT EXISTS " + MusicDBInfo.GENRES_INFO_VIEW_NAME + " AS " +
MusicDBInfo.VIEW_GENRE_INFO_QUERY);
}
private static void createSearchHelperTitleView(SQLiteDatabase db) {
iLog.d(TAG, "createSearchHelperTitleView");
db.execSQL("DROP VIEW IF EXISTS " + MusicDBInfo.SEARCH_HELPER_TITLE_VIEW_NAME);
db.execSQL(
"CREATE VIEW IF NOT EXISTS " + MusicDBInfo.SEARCH_HELPER_TITLE_VIEW_NAME + " AS " +
MusicDBInfo.VIEW_SEARCH_HELPER_TITLE_QUERY);
}
private static void createSearchView(SQLiteDatabase db) {
iLog.d(TAG, "createSearchView");
// artist, album, title integrated search view
db.execSQL("DROP VIEW IF EXISTS " + MusicDBInfo.SEARCH_VIEW_NAME);
db.execSQL("CREATE VIEW IF NOT EXISTS " + MusicDBInfo.SEARCH_VIEW_NAME + " AS " +
MusicDBInfo.LOCAL_VIEW_SEARCH_QUERY_ARTIST
// Local Album union
+ " UNION ALL " + MusicDBInfo.LOCAL_VIEW_SEARCH_QUERY_ALBUM
// Local Title union
+ " UNION ALL " + MusicDBInfo.LOCAL_VIEW_SEARCH_QUERY_TRACK);
// artist search view
db.execSQL("DROP VIEW IF EXISTS " + MusicDBInfo.SEARCH_ALBUM_VIEW_NAME);
db.execSQL("CREATE VIEW IF NOT EXISTS " + MusicDBInfo.SEARCH_ALBUM_VIEW_NAME + " AS " +
MusicDBInfo.LOCAL_VIEW_SEARCH_QUERY_ALBUM);
// album search view
db.execSQL("DROP VIEW IF EXISTS " + MusicDBInfo.SEARCH_ARTIST_VIEW_NAME);
db.execSQL("CREATE VIEW IF NOT EXISTS " + MusicDBInfo.SEARCH_ARTIST_VIEW_NAME + " AS " +
MusicDBInfo.LOCAL_VIEW_SEARCH_QUERY_ARTIST);
// track search view
db.execSQL("DROP VIEW IF EXISTS " + MusicDBInfo.SEARCH_TRACK_VIEW_NAME);
db.execSQL("CREATE VIEW IF NOT EXISTS " + MusicDBInfo.SEARCH_TRACK_VIEW_NAME + " AS " +
MusicDBInfo.LOCAL_VIEW_SEARCH_QUERY_TRACK);
}
private static void createOnlineTable(SQLiteDatabase db) {
iLog.d("TAG", "createOnlineTable");
// for categorized tracks
db.execSQL("DROP TABLE IF EXISTS " + OnlineTracks.MAP_TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineTracks.MAP_TABLE_NAME + " (" +
OnlineTracks.SCHEMA_COLUMNS_DEFINITION + ");");
// for categorized tracks trigger.
// Cleans up when an audio file is deleted
db.execSQL("DROP TRIGGER IF EXISTS audio_meta_categorized_tracks_map_trigger;");
db.execSQL(
"CREATE TRIGGER IF NOT EXISTS audio_meta_categorized_tracks_map_trigger DELETE ON audio_meta " +
"BEGIN DELETE FROM " + OnlineTracks.MAP_TABLE_NAME +
" WHERE audio_id = old._id; END");
// online artist
db.execSQL("DROP TABLE IF EXISTS " + OnlineArtists.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineArtists.TABLE_NAME + " (" +
OnlineArtists.SCHEMA_COLUMNS_DEFINITION + ");");
// online album
db.execSQL("DROP TABLE IF EXISTS " + OnlineAlbums.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineAlbums.TABLE_NAME + " (" +
OnlineAlbums.SCHEMA_COLUMNS_DEFINITION + ");");
// online topic
db.execSQL("DROP TABLE IF EXISTS " + OnlineTopics.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineTopics.TABLE_NAME + " (" +
OnlineTopics.SCHEMA_COLUMNS_DEFINITION + ");");
}
/**
* Before create table, drop table
*/
private static void createTableInternal(SQLiteDatabase db, String tableName,
String tableDefinition) {
db.execSQL("DROP TABLE IF EXISTS " + tableName);
db.execSQL("CREATE TABLE IF NOT EXISTS " + tableName + " (" + tableDefinition + ");");
}
private static void createRadioCategory(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + OnlineRadioCategory.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineRadioCategory.TABLE_NAME + " (" +
OnlineRadioCategory.SCHEMA_COLUMNS_DEFINITION + ");");
}
private static void createOnlineFmCategory(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + OnlineFmCategory.TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + OnlineFmRecently.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineFmCategory.TABLE_NAME + " (" +
OnlineFmCategory.SCHEMA_COLUMNS_DEFINITION + ");");
db.execSQL("CREATE TABLE IF NOT EXISTS " + OnlineFmRecently.TABLE_NAME + " (" +
OnlineFmRecently.SCHEMA_COLUMNS_DEFINITION + ");");
}
private static void createDownloadTable(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + MusicDBInfo.Download.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + MusicDBInfo.Download.TABLE_NAME + " (" +
MusicDBInfo.Download.TABLE_COLUMNS_DEFINITION + ");");
db.execSQL("DROP TABLE IF EXISTS " + MusicDBInfo.Download.Tracks.TABLE_NAME);
db.execSQL("CREATE TABLE IF NOT EXISTS " + MusicDBInfo.Download.Tracks.TABLE_NAME + " (" +
MusicDBInfo.Download.Tracks.TABLE_COLUMNS_DEFINITION + ");");
db.execSQL(
"DROP TRIGGER IF EXISTS " + MusicDBInfo.Download.Trigger.DOWNLOAD_COMPLETE_TRIGGER);
db.execSQL("CREATE TRIGGER IF NOT EXISTS " +
MusicDBInfo.Download.Trigger.DOWNLOAD_COMPLETE_TRIGGER + " " +
MusicDBInfo.Download.Trigger.DOWNLOAD_COMPLETE_SCHEMA);
}
private static void createDbIndex(SQLiteDatabase db) {
db.execSQL("CREATE INDEX genre_name_index ON audio_meta(genre_name);");
db.execSQL("CREATE INDEX composer_index ON audio_meta(composer);");
db.execSQL("CREATE INDEX bucket_id_index ON audio_meta(bucket_id);");
}
private static void recreateTableWithCpAttrsColumn(SQLiteDatabase db) {
//@formatter:off
recreateTableWithCpAttrsColumn(db, MusicDBInfo.AUDIO_TABLE_NAME, MusicDBInfo.AUDIO_TABLE_COLUMNS_DEFINITION_V2, RESERVED_COLUMNS_AUDIO_META, "content_location", "cp_attrs");
recreateTableWithCpAttrsColumn(db, MusicDBInfo.MusicCacheMap.MAP_TABLE_NAME, MusicDBInfo.MusicCacheMap.SCHEMA_COLUMNS_DEFINITION_V2, RESERVED_COLUMNS_MUSIC_CACHE_MAP, "content_location", "cp_attrs");
//@formatter:on
}
private static void recreateTableWithCpAttrsColumn(SQLiteDatabase db, String tableName,
String columnsDefinition, String reservedColumns, String oldColumnName,
String newColumnName) {
//@formatter:off
String tempTable = tableName + "_temp";
db.execSQL("DROP TABLE IF EXISTS " + tempTable);
db.execSQL("CREATE TABLE IF NOT EXISTS " + tempTable + " (" + columnsDefinition + ");");
db.execSQL("INSERT INTO " + tempTable + " (" + reservedColumns + ", " + newColumnName + ") " +
"SELECT " + reservedColumns + "," +
" CASE WHEN " + oldColumnName + " = 1 THEN " + CpAttrs.LOCAL +
" WHEN " + oldColumnName + " = 2 THEN " + CpAttrs.ULTIMATE +
" WHEN " + oldColumnName + " = 0 THEN " + CpAttrs.LOCAL +
" WHEN " + oldColumnName + " = 4 THEN " + CpAttrs.DLNA + " END " +
"FROM " + tableName);
db.execSQL("DROP TABLE " + tableName);
db.execSQL("ALTER TABLE " + tempTable + " RENAME TO " + tableName);
//@formatter:on
}
private static final String RESERVED_COLUMNS_AUDIO_META =
"_id, source_id, _data, _size, mime_type, title, title_key, _display_name, duration, " +
"track, artist_id, artist, artist_key, album_id, album, album_key, album_art, " +
"album_artist, genre_name, composer, year, year_name, bucket_id, " +
"bucket_display_name, sampling_rate, bit_depth, is_music, is_favorite, " +
"is_secretbox, date_added, date_modified, date_updated, recently_played, " +
"most_played, provider_id, provider_name, extension, seed, media_type, " +
"is_downloaded, exclusivity";
private static final String RESERVED_COLUMNS_MUSIC_CACHE_MAP =
"_id, category, keyword, title, album_id, played_count, date_added, number_of_tracks, total_duration";
}
八、数据库的加密
开发中对于存储于数据库中的敏感数据,我们可以通过对数据库加密来进行保护。GreenDao可以通过SQLCipher来进行加密处理。
//build.gradle(module)
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin
android {
compileSdkVersion 29
buildToolsVersion "29.0.0"
defaultConfig {
applicationId "com.example.sourcecodetest"
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'org.greenrobot:greendao:3.2.2' // add library
implementation 'net.zetetic:android-database-sqlcipher:3.5.6' // add sqlcipher library
}
greendao {
schemaVersion 7 //数据库版本号
daoPackage 'com.example.sourcecodetest.database'
//设置DaoMaster、DaoSession、Dao包名
targetGenDir 'src/main/java' //设置DaoMaster、DaoSession、Dao目录,请注意,这里路径用 / 不要用 .
generateTests false //设置为true以自动生成单元测试
targetGenDirTests 'src/main/java' //应存储生成的单元测试的基本目录。默认为src/androidTest/java
}
//MyApplication
public class MyApplication extends Application {
private static final String TAG = "MyApplication";
private DaoSession daoSession;
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "zwm, onCreate");
initGreenDao();
}
/**
* 初始化GreenDao,直接在Application中进行初始化操作
*/
private void initGreenDao() {
Log.d(TAG, "zwm, initGreenDao");
//MyDaoMaster helper = new MyDaoMaster(this, "tomorrow.db"); //自定义DaoMaster.OpenHelper,用于处理数据库升级
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "tomorrow.db");
//SQLiteDatabase db = helper.getWritableDatabase(); //不加密的写法
Database db = helper.getEncryptedWritableDb("zwm"); //数据库加密密码为“zwm"的写法
DaoMaster daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession();
}
public DaoSession getDaoSession() {
return daoSession;
}
}
//MainActivity
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "zwm, onCreate");
insert(); //插入数据后注释掉,用于测试数据库升级
List<Student> list = loadStudents();
for(Student student : list) {
Log.d(TAG, "zwm, student NO." + student.getStudentNo() + ", _id: " + student.getId() + ", age: " + student.getAge() + ", name: " + student.getName());
Log.d(TAG, "zwm, student newField: " + student.getAddNewField());
List<Teacher> teacherList = student.getTeacherList();
Log.d(TAG, "zwm, teacherList.size: " + teacherList.size());
if(teacherList != null && teacherList.size() > 0) {
for(Teacher teacher : teacherList) {
Log.d(TAG, "zwm, teacher NO." + teacher.getTeacherNo() + ", _id: " + teacher.getId() + ", age: " + teacher.getAge() + ", name: " + teacher.getName());
}
}
}
List<Teacher> list2 = loadTeachers();
for(Teacher teacher : list2) {
Log.d(TAG, "zwm, teacher NO." + teacher.getTeacherNo() + ", _id: " + teacher.getId() + ", age: " + teacher.getAge() + ", name: " + teacher.getName());
List<Student> studentList = teacher.getStudentList();
Log.d(TAG, "zwm, studentList.size: " + studentList.size());
if(studentList != null && studentList.size() > 0) {
for(Student student : studentList) {
Log.d(TAG, "zwm, student NO." + student.getStudentNo() + ", _id: " + student.getId() + ", age: " + student.getAge() + ", name: " + student.getName());
}
}
}
}
public void insert() {
Log.d(TAG, "zwm, insert");
DaoSession daoSession = ((MyApplication) getApplication()).getDaoSession();
Student student = new Student();
student.setStudentNo(5551);
student.setAge(18);
student.setTelPhone("5524307");
student.setName("学生1");
student.setSex("男");
student.setAddress("广州");
student.setGrade("一");
student.setSchoolName("大学");
daoSession.insert(student);
Student student2 = new Student();
student2.setStudentNo(5552);
student2.setAge(19);
student2.setTelPhone("5524308");
student2.setName("学生2");
student2.setSex("男");
student2.setAddress("深圳");
student2.setGrade("二");
student2.setSchoolName("大学");
daoSession.insert(student2);
Student student3 = new Student();
student3.setStudentNo(5553);
student3.setAge(20);
student3.setTelPhone("5524309");
student3.setName("学生3");
student3.setSex("男");
student3.setAddress("北京");
student3.setGrade("三");
student3.setSchoolName("大学");
daoSession.insert(student3);
Teacher teacher1 = new Teacher();
teacher1.setTeacherNo(9991);
teacher1.setAge(28);
teacher1.setTelPhone("9924307");
teacher1.setName("教师1");
teacher1.setSex("男");
teacher1.setSubject("语文");
teacher1.setSchoolName("大学");
daoSession.insert(teacher1);
Teacher teacher2 = new Teacher();
teacher2.setTeacherNo(9992);
teacher2.setAge(29);
teacher2.setTelPhone("9924308");
teacher2.setName("教师2");
teacher2.setSex("男");
teacher2.setSubject("数学");
teacher2.setSchoolName("大学");
daoSession.insert(teacher2);
Teacher teacher3 = new Teacher();
teacher3.setTeacherNo(9993);
teacher3.setAge(30);
teacher3.setTelPhone("9924309");
teacher3.setName("教师3");
teacher3.setSex("男");
teacher3.setSubject("英语");
teacher3.setSchoolName("大学");
daoSession.insert(teacher3);
StudentAndTeacherBean studentAndTeacher = new StudentAndTeacherBean();
studentAndTeacher.setStudentId(Long.valueOf(1));
studentAndTeacher.setTeacherId(Long.valueOf(1));
daoSession.insert(studentAndTeacher);
StudentAndTeacherBean studentAndTeacher2 = new StudentAndTeacherBean();
studentAndTeacher2.setStudentId(Long.valueOf(1));
studentAndTeacher2.setTeacherId(Long.valueOf(2));
daoSession.insert(studentAndTeacher2);
StudentAndTeacherBean studentAndTeacher3 = new StudentAndTeacherBean();
studentAndTeacher3.setStudentId(Long.valueOf(2));
studentAndTeacher3.setTeacherId(Long.valueOf(1));
daoSession.insert(studentAndTeacher3);
StudentAndTeacherBean studentAndTeacher4 = new StudentAndTeacherBean();
studentAndTeacher4.setStudentId(Long.valueOf(2));
studentAndTeacher4.setTeacherId(Long.valueOf(3));
daoSession.insert(studentAndTeacher4);
StudentAndTeacherBean studentAndTeacher5 = new StudentAndTeacherBean();
studentAndTeacher5.setStudentId(Long.valueOf(3));
studentAndTeacher5.setTeacherId(Long.valueOf(1));
daoSession.insert(studentAndTeacher5);
StudentAndTeacherBean studentAndTeacher6 = new StudentAndTeacherBean();
studentAndTeacher6.setStudentId(Long.valueOf(3));
studentAndTeacher6.setTeacherId(Long.valueOf(2));
daoSession.insert(studentAndTeacher6);
StudentAndTeacherBean studentAndTeacher7 = new StudentAndTeacherBean();
studentAndTeacher7.setStudentId(Long.valueOf(3));
studentAndTeacher7.setTeacherId(Long.valueOf(3));
daoSession.insert(studentAndTeacher7);
}
public List<Student> loadStudents(){
Log.d(TAG, "zwm, loadStudents");
DaoSession daoSession = ((MyApplication) getApplication()).getDaoSession();
List<Student> students = daoSession.loadAll(Student.class);
return students;
}
public List<Teacher> loadTeachers(){
Log.d(TAG, "zwm, loadTeachers");
DaoSession daoSession = ((MyApplication) getApplication()).getDaoSession();
List<Teacher> teachers = daoSession.loadAll(Teacher.class);
return teachers;
}
}
//输出log
2020-01-08 20:23:43.476 3853-3853/com.example.sourcecodetest D/MyApplication: zwm, onCreate
2020-01-08 20:23:43.476 3853-3853/com.example.sourcecodetest D/MyApplication: zwm, initGreenDao
2020-01-08 20:23:44.113 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, onCreate
2020-01-08 20:23:44.113 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, insert
2020-01-08 20:23:44.357 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, loadStudents
2020-01-08 20:23:44.361 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, student NO.5551, _id: 1, age: 18, name: 学生1
2020-01-08 20:23:44.361 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, student newField: false
2020-01-08 20:23:44.369 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, teacherList.size: 2
2020-01-08 20:23:44.369 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9991, _id: 1, age: 28, name: 教师1
2020-01-08 20:23:44.370 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9992, _id: 2, age: 29, name: 教师2
2020-01-08 20:23:44.370 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, student NO.5552, _id: 2, age: 19, name: 学生2
2020-01-08 20:23:44.370 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, student newField: false
2020-01-08 20:23:44.376 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, teacherList.size: 2
2020-01-08 20:23:44.376 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9991, _id: 1, age: 28, name: 教师1
2020-01-08 20:23:44.376 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9993, _id: 3, age: 30, name: 教师3
2020-01-08 20:23:44.377 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, student NO.5553, _id: 3, age: 20, name: 学生3
2020-01-08 20:23:44.377 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, student newField: false
2020-01-08 20:23:44.380 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, teacherList.size: 3
2020-01-08 20:23:44.380 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9991, _id: 1, age: 28, name: 教师1
2020-01-08 20:23:44.380 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9992, _id: 2, age: 29, name: 教师2
2020-01-08 20:23:44.380 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9993, _id: 3, age: 30, name: 教师3
2020-01-08 20:23:44.380 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, loadTeachers
2020-01-08 20:23:44.384 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9991, _id: 1, age: 28, name: 教师1
2020-01-08 20:23:44.389 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, studentList.size: 3
2020-01-08 20:23:44.389 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, student NO.5551, _id: 1, age: 18, name: 学生1
2020-01-08 20:23:44.389 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, student NO.5552, _id: 2, age: 19, name: 学生2
2020-01-08 20:23:44.390 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, student NO.5553, _id: 3, age: 20, name: 学生3
2020-01-08 20:23:44.390 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9992, _id: 2, age: 29, name: 教师2
2020-01-08 20:23:44.393 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, studentList.size: 2
2020-01-08 20:23:44.394 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, student NO.5551, _id: 1, age: 18, name: 学生1
2020-01-08 20:23:44.394 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, student NO.5553, _id: 3, age: 20, name: 学生3
2020-01-08 20:23:44.394 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, teacher NO.9993, _id: 3, age: 30, name: 教师3
2020-01-08 20:23:44.396 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, studentList.size: 2
2020-01-08 20:23:44.396 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, student NO.5552, _id: 2, age: 19, name: 学生2
2020-01-08 20:23:44.397 3853-3853/com.example.sourcecodetest D/MainActivity: zwm, student NO.5553, _id: 3, age: 20, name: 学生3
//数据库文件
取出数据库文件(tomorrow.db)到电脑本地,无法通过SQLite Expert Professional软件打开,提示数据库文件已经加密了。
网友评论