android中數據庫框架 GreenDao
代碼已上傳 http://download.csdn.net/download/qq_24349695/10240859
樓主之前的項目用到了本地緩存,SharedPreferences緩存的數據有限,就研究了SQLite,發現SQLite的存儲查詢過程比較繁瑣,搜索過之後選擇了GreeDao框架
GreenDao官網 http://greenrobot.org/greendao/documentation/introduction/
樓主使用android studio編譯器
GreenDao配置
一、添加依賴
compile'org.greenrobot:greendao:3.0.1'
compile'org.greenrobot:greendao-generator:3.0.0'
二、配置app的Gradle
apply plugin: 'org.greenrobot.greendao'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'
}
}
greendao {
schemaVersion 1
daoPackage 'com.example.anonymous.greendao'
targetGenDir 'src/main/java'
}
schemaVersion—->指定數據庫schema版本號,遷移等操作會用到
daoPackage——–>通過gradle插件生成的數據庫相關文件,這裏我設置的文件路徑是com.example.anonymous.greendao
targetGenDir——–>這就是我們上面說到的自定義生成數據庫文件的目錄了,可以將生成的文件放到我們的java目錄中,而不是build中,這樣就不用額外的設置資源目錄了
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'
}
}
可以寫在oroject build.gradle 中
如下
// 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.2.2'
classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
當然寫在app的Gradle中也可以,官網是寫在project中的
app的Gradle整體
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'
}
}
greendao {
schemaVersion 1
daoPackage 'com.example.anonymous.greendao'
targetGenDir 'src/main/java'
}
android {
compileSdkVersion 25
buildToolsVersion "27.0.1"
defaultConfig {
applicationId "com.ljm.greendao"
minSdkVersion 15
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.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile'org.greenrobot:greendao:3.0.1'
compile'org.greenrobot:greendao-generator:3.0.0'
testCompile 'junit:junit:4.12'
}
添加數據庫數據的實體類
@Entity
public class User {
@Id
private Long id;
private String name;
}
@Entity:將我們的java普通類變爲一個能夠被greenDAO識別的數據庫類型的實體類
@Id:通過這個註解標記的字段必須是Long類型的,這個字段在數據庫中表示它就是主鍵,並且它默認就是自增的
make project後自動生成數據
這是GreenDao自動爲你生成的,路徑就是你在gradle中配置的路徑
增、刪、改、查
數據庫初始化
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(MyApplication.getContext(), "my-db", null);
DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
DaoSession daoSession = daoMaster.newSession();
UserDao userDao = daoSession.getUserDao();
my-db是數據庫的名字,自己隨便寫就行。
通過GreenDao生成的代碼,我們可以獲取到實體類的實例,也就是數據庫表的實例,這樣我們才能操作數據庫
一、增加
User user1 = new User(null,"zhangsan");
userDao.insert(user1);
二、刪除
1、根據Id刪除
User findUser = userDao.queryBuilder().where(UserDao.Properties.Name.eq("zhangsan")).build().unique();
if(findUser != null){
userDao.deleteByKey(findUser.getId());
}
2、刪除全部數據
userDao.deleteAll();
三、更新、修改
//1.where是查詢條件,
//2.unique()表示查詢結果爲一條數據,若數據不存在,findUser爲null。
User findUser = userDao.queryBuilder().where(UserDao.Properties.Name.eq("zhangsan")).build().unique();
if(findUser != null) {
findUser.setName("lisi");
userDao.update(findUser);
Toast.makeText(MyApplication.getContext(), "修改成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MyApplication.getContext(), "用戶不存在", Toast.LENGTH_SHORT).show();
}
zhangsan修改成lisi
四、查詢
List<User> userList = userDao.queryBuilder()
.where(UserDao.Properties.Id.notEq(0))
.limit(5)
.build().list();
queryBuilder()方法,生成一個查找構造器,可以給構造器添加where條件判斷、按照某某字段排序以及查詢的條數等基本的數據庫操作。list()方法表示查詢的結果爲一個集合.上述代碼查詢的就是ID號不等於999,按升序排序,做多5條,返回List類型
list()所有實體被加載到內存中。其結果通常是一個 ArrayList中,最容易使用。
listLazy()實體被裝入點播存儲器。一旦列表中的一個元素被首次訪問,它被加載並高速緩存以供將來使用。必須關閉。
listLazyUncached()一個“虛擬”實體名單:任何接觸到從數據庫加載其數據的列表元素的結果。必須關閉。
ListIterator()通過懶加載的數據讓你通過迭代的結果的。數據不會被緩存。必須關閉
上面查詢的是一個list這個就是一個單例
User user = userDao.queryBuilder()
.where(UserDao.Properties.Id.eq(999)).unique();
封裝 封裝 封裝 封裝 封裝 封裝 封裝 封裝 封裝
對代碼進行封裝,以便於多次調用
1、MyApplication:返回Context對象
2、DaoManager:初始化數據庫,獲取相應的操作對象
3、EntityManager:對數據庫表的初始化,獲取實體類的操作對象
MyApplication
public class MyApplication extends Application {
private static Context mContext;
@Override
public void onCreate() {
super.onCreate();
mContext = getApplicationContext();
}
public static Context getContext() {
return mContext;
}
}
EntityManager
public class EntityManager {
private static EntityManager entityManager;
public UserDao userDao;
/**
* 創建User表實例
*
* @return
*/
public UserDao getUserDao(){
userDao = DaoManager.getInstance().getSession().getUserDao();
return userDao;
}
/**
* 創建單例
*
* @return
*/
public static EntityManager getInstance() {
if (entityManager == null) {
entityManager = new EntityManager();
}
return entityManager;
}
}
DaoManager
public class DaoManager {
private static DaoManager mInstance;
private DaoMaster mDaoMaster;
private DaoSession mDaoSession;
private DaoManager() {
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(MyApplication.getContext(), "my-db", null);
DaoMaster mDaoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
mDaoSession = mDaoMaster.newSession();
}
public DaoMaster getMaster() {
return mDaoMaster;
}
public DaoSession getSession() {
return mDaoSession;
}
public static DaoManager getInstance() {
if (mInstance == null) {
mInstance = new DaoManager();
}
return mInstance;
}
}
使用以插入爲例子
UserDao userDao = EntityManager.getInstance().getUserDao();
User user1 = new User(null,"zhangsan");
userDao.insert(user1);
DaoManager和EntityManager主要作用是對數據庫和表的初始化工作抽出來作爲複用,在Activity中使用的時候,我們可以直接操作表,不需要在初始化工作了。
所有操作封裝
public class DbService {
private static DbService instance;
private static Context appContext;
private UserDao userDao;
private DbService() {
}
/**
* 採用單例模式
* @param context 上下文
* @return dbservice
*/
public static DbService getInstance(Context context) {
if (instance == null) {
instance = new DbService();
if (appContext == null){
appContext = context.getApplicationContext();
}
instance.userDao = EntityManager.getInstance().getUserDao();
}
return instance;
}
/**
* 根據用戶id,取出用戶信息
* @param id 用戶id
* @return 用戶信息
*/
public User loadNote(long id) {
if(!TextUtils.isEmpty(id + "")) {
return userDao.load(id);
}
return null;
}
/**
* 取出所有數據
* @return 所有數據信息
*/
public List<User> loadAllNote(){
return userDao.loadAll();
}
/**
* 生成按id倒排序的列表
* @return 倒排數據
*/
public List<User> loadAllNoteByOrder()
{
return userDao.queryBuilder().orderDesc(UserDao.Properties.Id).list();
}
/**
* 根據查詢條件,返回數據列表
* @param where 條件
* @param params 參數
* @return 數據列表
*/
public List<User> queryNote(String where, String... params){
return userDao.queryRaw(where, params);
}
/**
* 根據用戶信息,插件或修改信息
* @param user 用戶信息
* @return 插件或修改的用戶id
*/
public long saveNote(User user){
return userDao.insertOrReplace(user);
}
/**
* 批量插入或修改用戶信息
* @param list 用戶信息列表
*/
public void saveNoteLists(final List<User> list){
if(list == null || list.isEmpty()){
return;
}
userDao.getSession().runInTx(new Runnable() {
@Override
public void run() {
for(int i=0; i<list.size(); i++){
User user = list.get(i);
userDao.insertOrReplace(user);
}
}
});
}
/**
* 刪除所有數據
*/
public void deleteAllNote(){
userDao.deleteAll();
Toast.makeText(appContext, "刪除成功", Toast.LENGTH_SHORT).show();
}
/**
* 根據id,刪除數據
* @param id 用戶id
*/
public void deleteNote(long id){
userDao.deleteByKey(id);
}
/**
* 根據用戶類,刪除信息
* @param user 用戶信息類
*/
public void deleteNote(User user){
userDao.delete(user);
}
}
具體使用,以刪除所有數據爲例。
findViewById(R.id.bt_deleteall).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DbService.getInstance(MainActivity.this).deleteAllNote();
//DeleteAllData();
}
});
具體使用
public class MainActivity extends AppCompatActivity {
private UserDao userDao;
private DaoSession daoSession;
private DaoMaster daoMaster;
private DaoMaster.DevOpenHelper devOpenHelper;
private List<User> userList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
devOpenHelper = new DaoMaster.DevOpenHelper(MainActivity.this, "my-db", null);
daoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
daoSession = daoMaster.newSession();
//userDao = daoSession.getUserDao();
userDao = EntityManager.getInstance().getUserDao();
findViewById(R.id.bt_insert).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AddData();
}
});
findViewById(R.id.bt_delete).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DeleteData();
}
});
findViewById(R.id.bt_update).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
UpdateData();
}
});
findViewById(R.id.bt_query).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
QueryData();
}
});
findViewById(R.id.bt_deleteall).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DbService.getInstance(MainActivity.this).deleteAllNote();
//DeleteAllData();
}
});
}
private void AddData(){
User user1 = new User(null,"zhangsan");
userDao.insert(user1);
Toast.makeText(MainActivity.this, "添加成功", Toast.LENGTH_SHORT).show();
/*QueryData();
for(int i = 0;i<userList.size();i++){
if("zhangsan".equals(userList.get(i).getName())){
Toast.makeText(MainActivity.this, "用戶已存在", Toast.LENGTH_SHORT).show();
}else{
User user1 = new User(null,"zhangsan");
userDao.insert(user1);
Toast.makeText(MainActivity.this, "添加成功", Toast.LENGTH_SHORT).show();
}
}*/
}
private void DeleteAllData() {
userDao.deleteAll();
Toast.makeText(MainActivity.this, "刪除成功", Toast.LENGTH_SHORT).show();
}
private void DeleteData(){
User findUser = userDao.queryBuilder().where(UserDao.Properties.Name.eq("zhangsan")).build().unique();
if(findUser != null){
userDao.deleteByKey(findUser.getId());
Toast.makeText(MainActivity.this, "刪除成功", Toast.LENGTH_SHORT).show();
}
}
private void UpdateData(){
User findUser = userDao.queryBuilder().where(UserDao.Properties.Name.eq("zhangsan")).build().unique();
if(findUser != null) {
findUser.setName("lisi");
userDao.update(findUser);
Toast.makeText(MainActivity.this, "修改成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "用戶不存在", Toast.LENGTH_SHORT).show();
}
}
private void QueryData(){
userList = userDao.queryBuilder()
.where(UserDao.Properties.Id.notEq(0))
.limit(5)
.build().list();
for(int i = 0;i<userList.size();i++){
System.out.println("_____________i____________"+userList.get(i).getId()+"_______"+userList.get(i).getName());
}
}
}
ps:
一、這份代碼只是簡單的入門,代碼中還是存在bug的,重複添加再點刪除的時候會報錯org.greenrobot.greendao.DaoException: Expected unique result, but count was 2,如果在項目中用到,在插入之前先查詢下數據庫,然後再插入,或者刪除的時候根據ID去刪除。
二、代碼封裝過後記得在AndroidManifest中添加MyApplication不然會報空指針異常的。
代碼已上傳 http://download.csdn.net/download/qq_24349695/10240859