android使用greenDao3.2.2存储数据
1、greenDao的源码和地址
官网地址:http://greenrobot.org/greendao/
github:https://github.com/greenrobot/greenDAO
参考介绍:https://www.cnblogs.com/whoislcj/p/5651396.html
2、android studio集成greenDao
Project下的build.gradle:
dependencies {
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
}
APP的build.gradle:
apply plugin: 'org.greenrobot.greendao'
android {
greendao {
schemaVersion 3
daoPackage 'com.safe.ticketing.greendao.gen'
targetGenDir 'src/main/java'
}
}
dependencies {
implementation 'org.greenrobot:greendao:3.2.2'
}
3、app代码部分:
DBManager.java 实例化 SQLiteOpenHelper 单利:
/**
* FileName: DBManager
* Author: bai
* Date: 2019/4/12 9:40
*/
public class DBManager {
private final static String dbName = "ticketing_db";
private static DBManager mInstance=null;
private MSQLiteOpenHelper openHelper;
private Context context;
/**
* 初始化数据库构造方法
* @param context Context
*/
private DBManager(Context context) {
this.context = context;
openHelper = new MSQLiteOpenHelper(context, dbName, null);
}
/**
* 获取单例引用
*
* @param context Context
* @return DBManager
*/
public static DBManager getInstance(Context context) {
if (mInstance == null) {
synchronized (DBManager.class) {
if (mInstance == null) {
mInstance = new DBManager(context);
}
}
}
return mInstance;
}
/**
* 获取可读数据库
*/
public SQLiteDatabase getReadableDatabase() {
if (openHelper == null) {
openHelper = new MSQLiteOpenHelper(context, dbName, null);
}
return openHelper.getReadableDatabase();
}
/**
* 获取可写数据库
*/
public SQLiteDatabase getWritableDatabase() {
if (openHelper == null) {
openHelper = new MSQLiteOpenHelper(context, dbName, null);
}
return openHelper.getWritableDatabase();
}
}
LoginBean.java 要添加到数据库的字段bean:
/**
* FileName: LoginBean
* Author: bai
* Date: 2019/4/12 9:34
*/
@Entity
public class LoginBean {
private String userName;
private String password;
private String telPhone;
public String getTelPhone() {
return telPhone;
}
public void setTelPhone(String telPhone) {
this.telPhone = telPhone;
}
@Generated(hash = 1741451137)
public LoginBean(String userName, String password, String telPhone) {
this.userName = userName;
this.password = password;
this.telPhone = telPhone;
}
@Generated(hash = 1112702939)
public LoginBean() {
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
LoginDao.java 处理增删改查:
/**
* FileName: LoginDao
* Author: bai
* Date: 2019/4/12 10:20
*/
public class LoginDao {
private DBManager dbManager = null;
/**
* 初始化数据库构造方法
* @param context Context
*/
public LoginDao(Context context) {
dbManager = DBManager.getInstance(context);
}
/**
* 插入一条记录
*
* @param loginBean LoginBean
*/
public void insertLoginBean(LoginBean loginBean) {
com.safe.ticketing.greendao.gen.DaoMaster daoMaster = new DaoMaster(dbManager.getWritableDatabase());
DaoSession daoSession = daoMaster.newSession();
LoginBeanDao loginBeanDao = daoSession.getLoginBeanDao();
loginBeanDao.insert(loginBean);
}
/**
* 插入用户集合
*
* @param loginBeans List<LoginBean>
*/
public void insertLoginList(List<LoginBean> loginBeans) {
if (loginBeans == null || loginBeans.isEmpty()) {
return;
}
DaoMaster daoMaster = new DaoMaster(dbManager.getWritableDatabase());
DaoSession daoSession = daoMaster.newSession();
LoginBeanDao loginBeanDao = daoSession.getLoginBeanDao();
loginBeanDao.insertInTx(loginBeans);
}
/**
* 删除一条记录
*
* @param loginBean LoginBean
*/
public void deleteLogin(LoginBean loginBean) {
DaoMaster daoMaster = new DaoMaster(dbManager.getWritableDatabase());
DaoSession daoSession = daoMaster.newSession();
LoginBeanDao loginBeanDao = daoSession.getLoginBeanDao();
loginBeanDao.delete(loginBean);
}
/**
* 更新一条记录
*
* @param loginBean LoginBean
*/
public void updateLogin(LoginBean loginBean) {
DaoMaster daoMaster = new DaoMaster(dbManager.getWritableDatabase());
DaoSession daoSession = daoMaster.newSession();
LoginBeanDao loginBeanDao = daoSession.getLoginBeanDao();
loginBeanDao.update(loginBean);
}
/**
* 查询用户列表
*/
public List<LoginBean> queryLoginList() {
DaoMaster daoMaster = new DaoMaster(dbManager.getReadableDatabase());
DaoSession daoSession = daoMaster.newSession();
LoginBeanDao loginBeanDao = daoSession.getLoginBeanDao();
QueryBuilder<LoginBean> qb = loginBeanDao.queryBuilder();
List<LoginBean> list = qb.list();
return list;
}
/**
* 查询用户列表
*/
public List<LoginBean> queryLoginList(String userName) {
DaoMaster daoMaster = new DaoMaster(dbManager.getReadableDatabase());
DaoSession daoSession = daoMaster.newSession();
LoginBeanDao loginBeanDao = daoSession.getLoginBeanDao();
QueryBuilder<LoginBean> qb = loginBeanDao.queryBuilder();
qb.where(LoginBeanDao.Properties.UserName.gt(userName)).orderAsc(LoginBeanDao.Properties.UserName);
List<LoginBean> list = qb.list();
return list;
}
}
MigrationHelper2.java 、MSQLiteOpenHelper.java 数据库升级的处理(也就是数据库表添加新的字段或者删除后,gradle版本号+1时处理)
**
* FileName: MigrationHelper2
* Author: bai
* Date: 2019/4/12 14:16
*/
public class MigrationHelper2 {
public static boolean DEBUG = false;
private static String TAG = "MigrationHelper2";
private static final String SQLITE_MASTER = "sqlite_master";
private static final String SQLITE_TEMP_MASTER = "sqlite_temp_master";
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(Database database, Class<? extends AbstractDao<?, ?>>... daoClasses) {
printLog("【Generate temp table】start");
generateTempTables(database, daoClasses);
printLog("【Generate temp table】complete");
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】");
}
private static void createAllTables(Database db, boolean ifNotExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) {
reflectMethod(db, "createTable", ifNotExists, daoClasses);
printLog("【Create all table】");
}
/**
* 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<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);
StringBuilder insertTableStringBuilder = new StringBuilder();
insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
insertTableStringBuilder.append(columnSQL);
insertTableStringBuilder.append(") SELECT ");
insertTableStringBuilder.append(columnSQL);
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, info);
}
}
}
/**
* FileName: MSQLiteOpenHelper
* Author: bai
* Date: 2019/4/12 14:19
* TODO 自定义 MySQLiteOpenHelper集成 DaoMaster.OpenHelper 重写更新数据库的方法
* 当app下的build.gradle 的schemaVersion数据库的版本号改变时,,创建数据库会调用onUpgrade更细数据库的方法
*/
public class MSQLiteOpenHelper extends DaoMaster.OpenHelper{
/**
*
* @param context 上下文
* @param name 原来定义的数据库的名字 新旧数据库一致
* @param factory 可以null
*/
public MSQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
/**
*
* @param db Database
* @param oldVersion int
* @param newVersion int
* 更新数据库的时候它自己会调用
*/
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
Log.d("flag","-----调用了");
//具体的数据转移在MigrationHelper2类中
/**
* 将db传入 将gen目录下的所有的Dao.类传入
*/
MigrationHelper2.migrate(db,LoginBeanDao.class);
}
}
MainActivity.java调用greenDao增删改查的使用:
/**
* https://github.com/yuweiguocn/GreenDaoUpgradeHelper 升级数据库官网源码
* https://blog.csdn.net/xuwb123xuwb/article/details/73509107 升级参考
*/
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val loginBean = LoginBean()
loginBean.userName = "漠天"
loginBean.password = "111111"
loginBean.telPhone = "8888888888888888"
val loginDao = LoginDao(this)
loginDao.insertLoginBean(loginBean)
val loginResultBean = loginDao.queryLoginList()
Log.d("login",loginResultBean[0].userName)
}
}
demo源码:https://download.csdn.net/download/u010326875/11109916