GreenDao和ORMLite一样,都是基于ORM(Object Relation Mapping,对象关系映射)的用于操作Sqlite数据库的第三方框架。ORM简单来说就是把数据库中的数据映射成Java中的一个Bean类,便于操作。GreenDao是greenrobot公司的产品。这个公司的另一个非常成功的框架是EventBus,是一个很好的“订阅/发布”的事件处理框架。
好了,闲话不说,下面来简单介绍以下GreenDao这个框架。
1、GreenDao和ORMLite的比较
ORMLite:
GreenDao:
优点:效率很高。下面是GreenDao官网上的一张图,将GreenDao的各方面与其他的框架做比较。从图中可以非常清晰的看到,GreenDao在增、改、查方面都比其他框架快出一大截,尤其是查询。这是因为,GreenDao本身底层使用的不是反射,而是有一个Java工程来专门生成必要的代码。
缺点:GreenDao的缺点是学习成本高。这个框架不像ORMLite那样简单易上手,使用GreenDao之前需要配置一大堆参数,即它封装的不是很完整。
从上面的比较来看,如果项目对数据库操作的效率要求非常高,那么我们可以考虑使用GreenDao,否则,我们还是使用简单易上手的ORMLite吧。
2、配置GreenDao
1、在项目build.gradle中
// In your root build.gradle file: buildscript { repositories { jcenter() mavenCentral() // add repository } dependencies { classpath 'com.android.tools.build:gradle:2.3.1' classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin } }
2、在主Module的build.gradle中配置GreenDao的一些参数,加入GreenDao的依赖以及SourceSets。具体代码如下:
apply plugin: 'com.android.application' apply plugin: 'org.greenrobot.greendao' android { compileSdkVersion 27 defaultConfig { applicationId "com.example.greendaodemo" minSdkVersion 15 targetSdkVersion 26 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//<--数据库的版本,用于升级时候进行更改 daoPackage 'com.example.greendaodemo.gen'//这个是生成DAOs、DaoMaster、DaoSession代码保存的包名,默认为entities所在包名 targetGenDir 'src/main/java'//生成DAOs、DaoMaster、DaoSession的目录。默认为build/generated/source/greendao } // -------------------上面加入的代码----------------------- } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:appcompat-v7:27.0.2' implementation 'com.android.support.constraint:constraint-layout:1.0.2' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' // -------------------下面加入的代码----------------------- compile 'org.greenrobot:greendao:3.2.2' // -------------------上面加入的代码----------------------- implementation 'com.android.support:recyclerview-v7:27.0.2' }三.实现
1.创建bean类
@Entity public class UserInfo { @Id(autoincrement = true) private Long id; private String name; private int age; private int sex; }
编写完变量之后,编译项目,(1)会自动构造方法,get,set方法。(2)会生成 DaoMaster、DaoSession、DAOS类,类的位置位于你在app的build.gradle的schema配置
@Entity:告诉GreenDao该对象为实体,只有被@Entity注释的Bean类才能被dao类操作
@Id:对象的Id,使用Long类型作为EntityId,否则会报错。(autoincrement = true)表示主键会自增,如果false就会使用旧值
@Property:可以自定义字段名,注意外键不能使用该属性
@NotNull:属性不能为空
@Unique:该属性值必须在数据库中是唯一值
@Generated:greenDao生产代码注解,手动修改报错
2.数据库的创建
在MyApplication的onCreate()方法中初始化
public class MyApplication extends Application { private static Context context; @Override public void onCreate() { super.onCreate(); context = getApplicationContext(); //初始化greendao GreenDaoManager.getInstance(); } public static Context getContext() { return context; } }
MyApplication记得在AndroidManifest.xml中注册。
<application android:name=".MyApplication"
GreenDaoManager中创建数据库,并对其进行管理:
public class GreenDaoManager { private static final String DB_NAME = "greendao"; private static GreenDaoManager mInstance; private DaoMaster daoMaster; private DaoSession daoSession; public static GreenDaoManager getInstance() { if (mInstance == null) { synchronized (GreenDaoManager.class) { if (mInstance == null) { mInstance = new GreenDaoManager(); } } } return mInstance; } private GreenDaoManager() { if (mInstance == null) { MySQLiteOpenHelper helper = new MySQLiteOpenHelper(MyApplication.getContext(), DB_NAME, null); Database db = helper.getWritableDb(); daoMaster = new DaoMaster(db); daoSession = daoMaster.newSession(); } } public DaoSession getDaoSession() { return daoSession; } public DaoMaster getDaoMaster() { return daoMaster; } }
MySQLiteOpenHelper类继承DaoMaster.OpenHelper,并重载onUpgrade方法,里面处理数据库升级的逻辑:
public class MySQLiteOpenHelper extends DaoMaster.OpenHelper { public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) { super(context, name, factory); } public MySQLiteOpenHelper(Context context, String name) { super(context, name); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { super.onUpgrade(db, oldVersion, newVersion); //----------------------------使用sql实现升级逻辑 if (oldVersion == newVersion) { Log.e("onUpgrade", "数据库是最新版本,无需升级"); return; } Log.e("onUpgrade", "数据库从版本" + oldVersion + "升级到版本" + newVersion); switch (oldVersion) { case 1: String sql = ""; db.execSQL(sql); case 2: default: break; } } }DaoMaster.OpenHelper :创建SQLite数据库的SQLiteOpenHelper的具体实现
DaoMaster : GreenDao的顶级对象,用于创建和删除表
DaoSession : 管理所有的Dao对象,Dao对象可以通过 daoSession.getUserInfoDao()获得
3.增删改查
创建一个Dao类,把增删改查的方法封装起来,提高代码的可复用性,简洁性
public class UserDao { private final GreenDaoManager daoManager; private static UserDao mUserDao; public UserDao() { daoManager = GreenDaoManager.getInstance(); } public static UserDao getInstance() { if (mUserDao == null) { mUserDao = new UserDao(); } return mUserDao; } /** * 插入数据 若未建表则先建表 * * @param userInfo * @return */ public boolean insertUserData(UserInfo userInfo) { boolean flag = false; flag = getUserInfoDao().insert(userInfo) == -1 ? false : true; return flag; } /** * 插入或替换数据 * * @param userInfo * @return */ public boolean insertOrReplaceData(UserInfo userInfo) { boolean flag = false; try { flag = getUserInfoDao().insertOrReplace(userInfo) == -1 ? false : true; } catch (Exception e) { e.printStackTrace(); } return flag; } /** * 插入多条数据 子线程完成 * * @param list * @return */ public boolean insertOrReplaceMultiData(final List<UserInfo> list) { boolean flag = false; try { getUserInfoDao().getSession().runInTx(new Runnable() { @Override public void run() { for (UserInfo userInfo : list) { daoManager.getDaoSession().insertOrReplace(userInfo); } } }); flag = true; } catch (Exception e) { e.printStackTrace(); } return flag; } /** * 更新数据 * * @param userInfo * @return */ public boolean updateUserData(UserInfo userInfo) { boolean flag = false; try { getUserInfoDao().update(userInfo); flag = true; } catch (Exception e) { e.printStackTrace(); } return flag; } /** * 根据id删除数据 * * @param userInfo * @return */ public boolean deleteUserData(UserInfo userInfo) { boolean flag = false; try { getUserInfoDao().delete(userInfo); flag = true; } catch (Exception e) { e.printStackTrace(); } return flag; } /** * 删除所有数据 * * @return */ public boolean deleteAllData() { boolean flag = false; try { getUserInfoDao().deleteAll(); flag = true; } catch (Exception e) { e.printStackTrace(); } return flag; } /** * 根据主键查询 * * @param key * @return */ public UserInfo queryUserDataById(long key) { return getUserInfoDao().load(key); } /** * 查询所有数据 * * @return */ public List<UserInfo> queryAllData() { return getUserInfoDao().loadAll(); } /** * 根据名称查询 以年龄降序排列 * * @param name * @return */ public List<UserInfo> queryUserByName(String name) { Query<UserInfo> build = null; try { build = getUserInfoDao().queryBuilder() .where(UserInfoDao.Properties.Name.eq(name)) .orderDesc(UserInfoDao.Properties.Age) .build(); } catch (Exception e) { e.printStackTrace(); } return build.list(); } /** * 根据参数查询 * * @param where * @param param * @return */ public List<UserInfo> queryUserByParams(String where, String... param) { return getUserInfoDao().queryRaw(where, param); } public UserInfoDao getUserInfoDao() { return daoManager.getDaoSession().getUserInfoDao(); } }4.调用
在需要用到的地方调用方法,我这里是建了一个RecyclerView,更直观的显示数据的操作。你可以根据需要在适当的地方调用增删改查方法就行。
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private List<UserInfo> lists; private RecyclerView recyclerView; private Button add, del, update, query; private MainAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = findViewById(R.id.rv); recyclerView.setLayoutManager(new LinearLayoutManager(this)); adapter = new MainAdapter(); recyclerView.setAdapter(adapter); queryData(); add = findViewById(R.id.add); del = findViewById(R.id.del); update = findViewById(R.id.update); query = findViewById(R.id.query); add.setOnClickListener(this); del.setOnClickListener(this); update.setOnClickListener(this); query.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.add: addData(); break; case R.id.del: deleteData(); break; case R.id.update: updateData(); break; case R.id.query: queryData(); break; default: break; } } class MainAdapter extends RecyclerView.Adapter<MainAdapter.MainViewHolder> { private List<UserInfo> mLists; @Override public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); MainViewHolder holder = new MainViewHolder(view); return holder; } @Override public void onBindViewHolder(MainViewHolder holder, int position) { final int pos = holder.getLayoutPosition(); Log.d("onBindViewHolder", "position-->" + position + ",holder.getLayoutPosition()-->" + pos); holder.tv.setText(mLists.get(position).getName() + "--" + mLists.get(position).getAge() + "--" + mLists.get(position).getSex()); } @Override public int getItemCount() { return mLists.size(); } public void setData(List<UserInfo> lists) { mLists = lists; notifyDataSetChanged(); } class MainViewHolder extends RecyclerView.ViewHolder { TextView tv; public MainViewHolder(View view) { super(view); tv = view.findViewById(R.id.tv); } } } private void updateData() { if (!lists.isEmpty()) { UserInfo userInfo = lists.get(0); userInfo.setName("李四"); UserDao.getInstance().updateUserData(userInfo); queryData(); } } private void deleteData() { if (!lists.isEmpty()) { UserDao.getInstance().deleteUserData(lists.get(0)); queryData(); } } private void addData() { UserInfo userInfo = new UserInfo(); userInfo.setName("张三"); userInfo.setAge(18); userInfo.setSex(1); UserDao.getInstance().insertUserData(userInfo); queryData(); } private void queryData() { lists = UserDao.getInstance().queryAllData(); adapter.setData(lists); Toast.makeText(this, "查询到" + lists.size() + "条数据", Toast.LENGTH_SHORT).show(); } }
5.其他方法
添加
单条数据
getUserInfoDao().insert(userInfo)
getUserInfoDao().insertOrReplace(userInfo);
多条数据
getUserInfoDao().insertInTx(userInfoList);
getUserInfoDao().insertOrReplaceInTx(userInfoList);
查询
单个条件
where()
whereOr()
多个条件
where(,,)
whereOr(,,)
降序 orderDesc()
升序 orderAsc()
当页限制个数 limit()
根据key查询 .load(key)
全部 .loadAll() 或者.queryBuilder().list()
修改
单条 .update(userInfo)
多条 .updateInTx(userInfoList)
删除
单条 .delete(userInfo)
多条 .deleteInTx(userInfoList)
全部 .deleteAll()
6.demo下载