GreenDao和ORMLite一样,都是基于ORM(Object Relation Mapping,对象关系映射)的用于操作Sqlite数据库的第三方框架。ORM简单来说就是把数据库中的数据映射成Java中的一个Bean类,便于操作。GreenDao是greenrobot公司的产品。这个公司的另一个非常成功的框架是EventBus,是一个很好的“订阅/发布”的事件处理框架。
好了,闲话不说,下面来简单介绍以下GreenDao这个框架。
1、GreenDao和ORMLite的比较
ORMLite:
优点:ORMLite最大的优点是简单,容易上手。
缺点:ORMLite是基于反射机制工作的,而反射是非常耗时的,因此这便成为了ORMLite的一个缺点,也是GreenDao最针对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下载