前言
greenDAO作为Android移动端的一款开源的orm框架,因其快速开发,而且小而快,为众多安卓程序员所知,成为一款热门,现在迎来了更便捷的3.0+版本,主要亮点就是提供了注解。官网又快速使用的教程How To Start!
greenDAO的特性
最大的性能 (可能是最快的ORM Android);我们的基准是开源易于使用的 强大的api
最小的 内存消耗
jar包很小(< 100 kb),减少构建时间,避免65 k方法限制
数据库加密 :greenDAO支持SQLCipher保证用户的数据安全
强大的社区 :GitHub热门支持https://github.com/greenrobot/greenDAO/
基本使用
按惯例先看demo效果图
1.本文案例基于Android studio,首先在app下的build.gradle下添加如下配置参数来导入当前最新的greenDAO框架
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.0'
}
}
apply plugin: 'org.greenrobot.greendao'
dependencies {
compile 'org.greenrobot:greendao:3.2.0'
}
现在,当你build项目的时候,就会执行生成greendao代码。在Android Studio中,当你选择build->make project的时候,也会触发。默认情况下,在build/generated/source/greendao目录下生成代码,将这个目录添加为gradle build时的资源目录。
温馨提示:如果你觉得生成的代码有错误,请首先检查build/generated/source/greendao目录。
如果自己配置dao路径和数据库版本,需要再添加以下配置
greendao {
//相当于数据库的版本号,每次更新表结构就要改变
schemaVersion 3
//设置DAO生成包的路径
daoPackage "com.example.myapp.db.dao"
//生成代码的存放地址
targetGenDir 'src/main/java'
}
2. 创建一个User实体,然后再build -> rebuild project,greenDAO会在指定的目录生成代码。
注意我们这里用的是注解,3.0之前用的都是用它的构建工具来构建dao等类,非常不好用,现在终于可以改革了。
package com.example.myapp.bean;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.NotNull;
import org.greenrobot.greendao.annotation.Property;
import org.greenrobot.greendao.annotation.Transient;
import java.util.Date;
/**
* Created by jan on 2016/10/18.
*/
@Entity
public class User {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "name")
private String name;
@NotNull
private String repos;
@Transient
private String tempUseageCount;
private Date createTime;
private String icon;
private int age;
private String sex;
@Generated(hash = 2124177453)
public User(Long id, String name, @NotNull String repos, Date createTime,
String icon, int age, String sex) {
this.id = id;
this.name = name;
this.repos = repos;
this.createTime = createTime;
this.icon = icon;
this.age = age;
this.sex = sex;
}
@Generated(hash = 586692638)
public User() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getRepos() {
return this.repos;
}
public void setRepos(String repos) {
this.repos = repos;
}
public Date getCreateTime() {
return this.createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getIcon() {
return this.icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return this.sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
@Id:该注解选择一个long类型的属性作为实体类的ID。在数据库里面,它就是主键。这个参数 autoincrement 是一个标记,标志着ID一直都是增长的,从不适用旧值;
@Property:使用该属性定义一个非默认的列名,该变量和该列进行映射。如果缺少,greendao会使用这个变量名来命名数据库的列名(全部大写,并且使用下划线来代替驼峰命名法,eg:customName会变成CUSTOM_NAME)。
NotNull:非空,通常情况下修饰基础类型,比如long,int,short,byte,当然也可以是包装类:Long,Integer,Short,Byte
@Transient:表示该属性不是持久化的,仅仅作为临时变量使用。
Build完之后你会发现,加入了新的小伙伴
知识点:
1.DaoMaster DaoMaster保存数据库对象(SQLiteDatabase)和管理DAO类(而不是对象)为特定的模式。它的静态方法来创建表或删除它们。它的内部类OpenHelper和DevOpenHelper是创建SQLite数据库架构SQLiteOpenHelper实现。
2.DaoSession 管理所有可用的DAO对象,DaoSession还提供了一些通用的持久性的方法,如插入,装载,更新,刷新和删除实体。最后,DaoSession对象也跟踪标识范围。
3.Dao 各个表的Dao类,例如 UserDao,ImageDao等,负责增删改查
3.自己可以继承OpenHelper,为后期的数据库更新添加更新方法(不是本次重点),先贴下代码
public class MySqliteOpenHelper extends DaoMaster.OpenHelper {
private static final String DB_NAME = "app.db";
private static final SortedMap<Integer, Migration> ALL_MIGRATIONS = new TreeMap<>();
static {
//1-2-....迁移的递增
ALL_MIGRATIONS.put(1, new V1Migration());
ALL_MIGRATIONS.put(2, new V2Migration());
}
public MySqliteOpenHelper(Context context) {
this(context, DB_NAME, null);
}
public MySqliteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, DB_NAME, factory);
}
@Override
public void onCreate(SQLiteDatabase db) {
super.onCreate(db);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
Log.w(MySqliteOpenHelper.class.getSimpleName(), "Upgrade from" + oldVersion + "to" + newVersion);
SortedMap<Integer, Migration> migrations = ALL_MIGRATIONS.subMap(oldVersion, newVersion);
executeMigrations(sqLiteDatabase, migrations.keySet());
}
private void executeMigrations(final SQLiteDatabase paramSQLiteDatabase, final Set<Integer>
migrationVersions) {
for (final Integer version : migrationVersions) {
ALL_MIGRATIONS.get(version).migrate(paramSQLiteDatabase);
}
}
}
/**
* 实现更新数据库的迁移方案的接口
*/
interface Migration {
void migrate(SQLiteDatabase db);
}
class V1Migration implements Migration {
@Override
public void migrate(SQLiteDatabase db) {
db.execSQL("ALTER TABLE USER ADD COLUMN AGE");
}
}
class V2Migration implements Migration {
@Override
public void migrate(SQLiteDatabase db) {
db.execSQL("ALTER TABLE USER ADD COLUMN SEX");
}
}
4.对DaoMaster.DaoSession,UserDao类进行第一次简单封装-DaoManager.java
/**
* Created by Jan on 2016/10/19.
*/
public class DBManager {
private static DBManager mDBManager;
private static MySqliteOpenHelper mOpenHelper;
private static DaoMaster mDaoMaster;
private static DaoSession mDaoSession;
private Context mContext;
private DBManager(Context context) {
this.mContext = context;
// 初始化数据库信息
mOpenHelper = new MySqliteOpenHelper(context);
getDaoMaster(context);
getDaoSession(context);
}
public static DBManager getInstance(Context context) {
if (null == mDBManager) {
synchronized (DBManager.class) {
if (null == mDBManager) {
mDBManager = new DBManager(context);
}
}
}
return mDBManager;
}
/**
* @desc 获取可读数据库
**/
public static SQLiteDatabase getReadableDatabase(Context context) {
if (null == mOpenHelper) {
getInstance(context);
}
return mOpenHelper.getReadableDatabase();
}
/**
* @desc 获取可写数据库
**/
public static SQLiteDatabase getWritableDatabase(Context context) {
if (null == mOpenHelper) {
getInstance(context);
}
return mOpenHelper.getWritableDatabase();
}
/**
* @desc 获取DaoMaster
**/
public static DaoMaster getDaoMaster(Context context) {
if (null == mDaoMaster) {
synchronized (DBManager.class) {
if (null == mDaoMaster) {
mDaoMaster = new DaoMaster(getWritableDatabase(context));
}
}
}
return mDaoMaster;
}
/**
* @desc 获取DaoSession
**/
public static DaoSession getDaoSession(Context context) {
if (null == mDaoSession) {
synchronized (DBManager.class) {
mDaoSession = getDaoMaster(context).newSession();
}
}
return mDaoSession;
}
}
在DaoManager基础上,我们可以再对User的数据库业务层的操作进行一次封装,把最基础的几个增删查改操作做封装,这个类就是:UserDaoOpe.java
package com.example.myapp.db.dao;
import android.content.Context;
import com.example.myapp.bean.User;
import com.example.myapp.db.DBManager;
import org.greenrobot.greendao.query.QueryBuilder;
import java.util.List;
/**
* 用户表的数据库方法的简单封装和管理的类
* Created by Jan on 2016/10/19.
*/
public class UserDaoOpe {
private static UserDaoOpe instance;
private static Context appContext;
private DaoSession mDaoSession;
private UserDao mUserDao;
private UserDaoOpe(){
}
/**
* 单例
* @param context
* @return
*/
public static UserDaoOpe getInstance(Context context) {
if (instance == null) {
instance = new UserDaoOpe();
if (appContext == null){
appContext = context.getApplicationContext();
}
instance.mDaoSession = DBManager.getDaoSession(context);
instance.mUserDao = DBManager.getDaoSession(context).getUserDao();
}
return instance;
}
/**
* 插入一个用户实体数据
* @param user
*/
public void insert(User user) {
try {
mUserDao.insert(user);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 删除一个用户
* @param user
*/
public void delete(User user){
try {
mUserDao.delete(user);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据主键ID来删除user
* @param id
*/
public void deleteUserById(Long id){
try {
mUserDao.deleteByKey(id);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 清空表中的内容
*/
public void deleteAll(){
try {
mUserDao.deleteAll();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 更新User
* @param user
*/
public void upgrade(User user){
try {
mUserDao.update(user);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 利用事务来插入list
* @param list
*/
public void insertList(List<User> list){
if(list==null || list.size()==0){
return;
}
try {
mUserDao.insertInTx(list);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 查询所有的user
* @return
*/
public List<User> queryAll(){
try {
QueryBuilder<User> builder = mUserDao.queryBuilder();
return builder.build().list();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 查询大于指定年龄的用户群
* @param age
* @return
*/
public List<User> findGtAgeUsers(int age){
List<User> userList = null;
try {
userList = mUserDao.queryBuilder().where(UserDao.Properties.Age.gt(age)).list();
}catch (Exception e){
e.printStackTrace();
}
return userList;
}
/**
* 根据主键ID来查询指定的User数据
* @param id
* @return
*/
public User findUserById(String id){
User user= null;
try {
QueryBuilder qb = mUserDao.queryBuilder().where(UserDao.Properties.Id.eq(id));
// qb.limit(1);
// qb.offset(0);
List<User> userList = qb.list();
user = userList.get(0);
} catch (Exception e) {
e.printStackTrace();
}
return user;
}
}
5.以上都是我们对greenDao方法的简单使用,应该是很好理解的,基本的增删查改方法,在下面我们就是在视图层的调用,直接调用UserDaoOpe这个类的API,很方便。如果你有更好的方式可以留言哦。
下面就是贴本次Activity的代码了。不是很重要,有兴趣的朋友可以看看哦。
GreenDaoDemo.java
public class GreenDaoDemo extends BaseActivity {
ListView mListview;
Button mSaveBtn,mDelBtn,mQueryBtn;
PtrClassicFrameLayout mPtrFl;
UserListAdapter mListAdapter;
Random random = new Random();
private Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_greendao);
context = this;
initViews();
}
private void initViews() {
mSaveBtn = (Button) findViewById(R.id.btn_save);
mDelBtn = (Button) findViewById(R.id.btn_reset);
mQueryBtn = (Button) findViewById(R.id.btn_querylist);
mListview = (ListView) findViewById(R.id.lv_user);
//下拉刷新组件的默认设置-与本次主题无关,请忽略
mPtrFl = (PtrClassicFrameLayout) findViewById(R.id.ptr_frame);
mPtrFl.setLastUpdateTimeRelateObject(this);
mPtrFl.setResistance(1.7f);
mPtrFl.setRatioOfHeaderHeightToRefresh(1.2f);
mPtrFl.setDurationToClose(200);
mPtrFl.setDurationToCloseHeader(1000);
mPtrFl.setPullToRefresh(false);
mPtrFl.setKeepHeaderWhenRefresh(true);
mSaveBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addUser();
}
});
mDelBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
resetAndCleanAll();
}
});
mQueryBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
findUserGt(30);
}
});
mPtrFl.setPtrHandler(new PtrHandler() {
@Override
public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
return PtrDefaultHandler.checkContentCanBePulledDown(frame, content, header);
}
@Override
public void onRefreshBegin(PtrFrameLayout frame) {
frame.postDelayed(new Runnable() {
@Override
public void run() {
notifyListview();
}
}, 1500);
}
});
mListAdapter = new UserListAdapter(this);
mListview.setAdapter(mListAdapter);
mListAdapter.setOnItemMenuSelectedListener(new UserListAdapter.OnItemMenuSelectedListener() {
@Override
public void onItemDel(int position) {
User user = (User) mListAdapter.getItem(position);
// UserDaoOpe.getInstance(context).delete(user);
UserDaoOpe.getInstance(context).deleteUserById(user.getId());
}
@Override
public void onItemUpdate(int position) {
User user = (User) mListAdapter.getItem(position);
BusPoster.postSticky(context,user,UserDetailActivity.class);
}
});
}
@Override
protected void onStart() {
super.onStart();
notifyListview();
}
@Override
public void onEvent(BaseEvent myEvent) {
super.onEvent(myEvent);
notifyListview();
}
private void notifyListview() {
try {
List<User> users = UserDaoOpe.getInstance(context).queryAll();
if (users.size() > 0) {
Log.d("DaoExample", "user's size is " + users.size());
Log.d("DaoExample", "the last user 's icon's site " + users.get(users.size() - 1).getIcon());
}
mListAdapter.updateData(users);
mPtrFl.refreshComplete();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 查询用户年龄大于age的数据
* @param age
*/
private void findUserGt(int age){
List<User> users = UserDaoOpe.getInstance(context).findGtAgeUsers(age);
mListAdapter.updateData(users);
}
/**
* 清空所有数据
*/
private void resetAndCleanAll(){
UserDaoOpe.getInstance(context).deleteAll();
notifyListview();
}
/**
* 添加一个用户到本地数据库
*/
private void addUser() {
int randomInt = random.nextInt(100);
Log.d("DaoExample", "Inserted random Int: " + randomInt);
User user = new User(null, "NewName : " + randomInt, "content:" + randomInt, new Date(), "http://blog.youkuaiyun.com/jan_s/", randomInt, null);
UserDaoOpe.getInstance(context).insert(user);
Log.d("DaoExample", "Inserted new user, ID: " + user.getId());
notifyListview();
}
/**
* 模拟插入1000条用户信息
*/
private void addUsers() {
List<User> userList = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
int randomInt = random.nextInt();
User user = new User(null, "NewName" + randomInt, "content:" + randomInt, new Date(), "http://blog.youkuaiyun.com/jan_s/", randomInt, null);
userList.add(user);
}
UserDaoOpe.getInstance(context).insertList(userList);
// userDao.insertInTx(userList);
notifyListview();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
修改的界面-UserDetailActivity.java
public class UserDetailActivity extends BaseActivity {
EditText mIdEt,mNameEt,mReposEt,mAgeEt;
Button mUpgradeBtn;
User mUser;
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_userdetail);
context = this;
initViews();
initEvent();
}
@Override
public void onEvent(BaseEvent myEvent) {
super.onEvent(myEvent);
}
@Override
protected void onDestroy() {
super.onDestroy();
BusPoster.removeSticky(User.class);
}
private void initViews(){
mIdEt = (EditText) findViewById(R.id.et_id);
mNameEt = (EditText) findViewById(R.id.et_name);
mReposEt = (EditText) findViewById(R.id.et_repos);
mAgeEt = (EditText) findViewById(R.id.et_age);
mUpgradeBtn = (Button) findViewById(R.id.btn_upgrade);
}
private void initEvent(){
mUpgradeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
updateUser();
}
});
mUser = (User) BusPoster.getSticky(User.class);
mUser = UserDaoOpe.getInstance(context).findUserById(mUser.getId()+"");
if(mUser!=null){
mIdEt.setText(mUser.getId()+"");
mNameEt.setText(mUser.getName());
mReposEt.setText(mUser.getRepos());
mAgeEt.setText(""+mUser.getAge());
}
}
private void updateUser(){
try {
if(mUser!=null){
String id = mIdEt.getText().toString().trim();
String name = mNameEt.getText().toString().trim();
String repos = mReposEt.getText().toString().trim();
String age = mAgeEt.getText().toString().trim();
mUser.setId(Long.parseLong(id));
mUser.setName(name);
mUser.setRepos(repos);
mUser.setAge(Integer.parseInt(age));
UserDaoOpe.getInstance(context).upgrade(mUser);
}
}catch (Exception e){
e.printStackTrace();
Toast.makeText(context,"数据不对哦",Toast.LENGTH_SHORT).show();
}
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
}
OK!结束!
本文链接,转载请留言(http://blog.youkuaiyun.com/jan_s/article/details/53127108)