在JavaEE中,有hibernate这个史诗级的框架在坐镇,所以安卓怎么可以少,虽然大部分安卓的框架都是开源的个人的或者团队的作品,但是也不妨碍我们使用;
安卓中常用的一些数据库框架有:
GreenDAO
OrmLite
Androrm
至于使用哪个,在网上找了一些资料,GreenDAO的资料还是较为完整,并且拥有以下的优点:
1 稳定
2 速度快
单凭这两点,就已经足够吸引我使用了。
GreenDAO的github地址:https://github.com/greenrobot/greenDAO
官方Demo里共有六个工程目录,分别为:
(1).DaoCore:库目录,即jar文件greendao-1.3.0-beta-1.jar的代码,用来跟踪源代码
(2).DaoExample:android范例工程;
(3).DaoExampleGenerator:DaoExample工程的DAO类构造器,java工程;
(4).DaoGenerator:DAO类构造器,java工程;
(5).DaoTest、PerformanceTestOrmLite:其他测试相关的工程。
安卓开发使用前面两个工程就可以了,如果使用了jar包,DaoExample中引入,直接就可以运行了;
下面是我的测试程序:
我没有引入库文件,只是使用了jar包,没有库文件,导入的时候就不需要配置库文件了;
我的程序中实现了增删改查,总结一下用法就好了;
使用这个框架首先有3个类是必须的;
重写 AbstractDaoMaster
重写 AbstractDaoSession
重写 SQLiteOpenHelper (adk的)
数据层必须重写:
重写 AbstractDao<T, K>
建立 T (就是Javabean)
这里还需要实现SQLiteOpenHelper进行数据库操作;
下面顺序开始GreenDAO数据库开源框架的使用:
建立JavaBean(建立模型)
public class Student {
private int id;
private String name;
private int age;
private int sex;
public Student() {
super();
}
public Student(int id, String name, int age, int sex) {
super();
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
重写 AbstractDao(建立DAO)
public class StudentDao extends AbstractDao<Student, Long> {
public static final String TABLENAME = "NOTE";
private String tag = "StudentDao";
private DaoConfig config;
public static class Properties {
public final static Property Id = new Property(0, String.class, "id",
true, "_id");
public final static Property Text = new Property(1, String.class,
"name", false, "NAME");
public final static Property Comment = new Property(2, Integer.class,
"age", false, "AGE");
public final static Property Date = new Property(3, Integer.class,
"sex", false, "SEX");
}
// 必须实现了两个构造函数
public StudentDao(DaoConfig config, AbstractDaoSession daoSession) {
super(config, daoSession);
Log.i(tag, "StudentDao(两个参数)");
this.config = config;
}
// 必须实现了两个构造函数
public StudentDao(DaoConfig config) {
super(config);
Log.i(tag, "StudentDao(一个参数)");
this.config = config;
}
@Override
protected Student readEntity(Cursor cursor, int offset) {
// 使用当前游标和偏移量读取一个实例
//父类操作该方法并添加到查询列表中
Student entity = new Student( //
(int) cursor.getLong(offset + 0), // id
cursor.getString(offset + 1), // text
(int) cursor.getLong(offset + 2), // comment
(int) cursor.getLong(offset + 3) // date
);
Log.i(tag, "readEntity(2个参数)");
return entity;
}
@Override
protected Long readKey(Cursor cursor, int offset) {
// 读取一个键?应该是读一个值吧
// return null;
Log.i(tag, "readKey(2个参数)");
return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);
}
@Override
protected void readEntity(Cursor cursor, Student entity, int offset) {
// 根据参数把值set进Student对象中
Log.i(tag, "readEntity(3个参数)");
}
@Override
protected void bindValues(SQLiteStatement stmt, Student entity) {
// 用于组合Update和Insert中的SQL语句
stmt.clearBindings();
Integer id = entity.getId();
if (id != null) {
stmt.bindLong(1, id);
}
stmt.bindString(2, entity.getName());
Integer age = entity.getAge();
if (age != null) {
stmt.bindLong(3, age);
}
Integer sex = entity.getSex();
if (sex != null) {
stmt.bindLong(4, sex);
}
}
@Override
protected Long updateKeyAfterInsert(Student entity, long rowId) {
//更新完成之后调用
entity.setId((int) rowId);
return rowId;
}
@Override
protected Long getKey(Student entity) {
// 返回 PRIMARY KEY ,不能有相同,用于查找
Log.i(tag, "getKey(1个参数)");
if (entity != null) {
return Long.parseLong(entity.getId() + "");
} else {
return null;
}
}
@Override
protected boolean isEntityUpdateable() {
Log.i(tag, "isEntityUpdateable(1个参数)");
return true;
}
/**
* 写一个静态类给SQLiteOpenHelper在onCreate中调用
*/
public static void createTable(SQLiteDatabase db, boolean ifNotExists) {
String constraint = ifNotExists ? " IF NOT EXISTS " : "";
db.execSQL("CREATE TABLE " + constraint + TABLENAME + "("// 表名
+ " '_id' INTEGER,"// int _id;0
// +"'NAME' TEXT NOT NULL,"//String NAME ; 1
+ "'NAME' TEXT," // name ;1
+ "'AGE' INTEGER,"// int AGE ; 2
+ " 'SEX' INTEGER"// INT SEX ; 3
+ ");");
}
}
实现DAO的时候有一些注意的地方,需要严格遵循标准来操作;
表名:
TABLENAME
一定要使用这个命名;
静态类:
Properties
一定要使用这个命名;
这两个严格的命名规定,是因为在DaoConfig.java中,使用了映射的方式读取这两个字段来获取表名和数据库中的字段名字;虽然字段类型可以较为宽松,但是也需要注意;
重写SQLiteOpenHelper(创建数据库)
public class DevOpenHelper extends SQLiteOpenHelper {
public DevOpenHelper(Context context, String name, CursorFactory factory,
int version, DatabaseErrorHandler errorHandler) {
super(context, name, factory, version, errorHandler);
}
public DevOpenHelper(Context context, String name, CursorFactory factory){
super(context, name, factory, 100);
}
public DevOpenHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
//执行SQL语句建表
StudentDao.createTable(db, false);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
实现SQLiteOpenHelper已经没有什么好说的了,遵循sdk规范就好;
重写AbstractDaoMaster(注册DAO)
public class DaoMaster extends AbstractDaoMaster {
public DaoMaster(SQLiteDatabase db, int schemaVersion) {
super(db, schemaVersion);
registerDaoClass(StudentDao.class);
}
@Override
public DaoSession newSession() {
return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);
}
@Override
public DaoSession newSession(IdentityScopeType type) {
return new DaoSession(db, type, daoConfigMap);
}
}
类DaoMaster有两个作用:
1 创建Session对象;
2 登记Dao的类(不是实例化);
重写AbstractDaoSession(关联DAO和JavaBean)
public class DaoSession extends AbstractDaoSession {
private final DaoConfig stuDaoConfig;
private final StudentDao studentDao;
public DaoSession(SQLiteDatabase db, IdentityScopeType type,
Map<Class<? extends AbstractDao<?, ?>>, DaoConfig> daoConfigMap) {
super(db);
stuDaoConfig = daoConfigMap.get(StudentDao.class).clone();
stuDaoConfig.initIdentityScope(type);
studentDao = new StudentDao(stuDaoConfig, this);
registerDao(Student.class, studentDao);
}
public StudentDao getStudentDao() {
return studentDao;
}
}
类DaoSession也有两个作用:
1 实例化Dao,并且提供get方法保证单例;
2 上使用registerDao登记Dao的实例和登记JavaBean类;
下面使用Activity进行增删改查 测试这个例子;
Activity.java
public class MainActivity extends Activity {
private Context context;
private ListView listView1;
private AlertDialog dialog;
private int index;
private DemoAdapter adapter;
private String DB_NAME = "demo_orm";
private StudentDao noteDao;
/** 用于数据区分 */
private int number = 0;
private List<Student> datas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
datas = new ArrayList<>();
adapter = new DemoAdapter(datas, context);
initDataBase();
findViewById(R.id.button1).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
search();
}
});
findViewById(R.id.btn_insert).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
insert();
}
});
listView1 = (ListView) findViewById(R.id.listView1);
listView1.setAdapter(adapter);
listView1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
index = position;
dialog.show();
}
});
Builder builder = new AlertDialog.Builder(context);
builder.setTitle("请选择操作");
builder.setMessage("Message");
builder.setNegativeButton("删除", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
delete();
}
});
builder.setNeutralButton("修改", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
update();
}
});
dialog = builder.create();
}
/**
* 初始化数据库工具类
*/
private void initDataBase() {
DevOpenHelper helper = new DevOpenHelper(context, DB_NAME , null);
DaoMaster daoMaster = new DaoMaster(helper.getWritableDatabase(),1000);
DaoSession daoSession = daoMaster.newSession();
noteDao = daoSession.getStudentDao();
}
private void insert() {
if(datas == null){
datas = new ArrayList<Student>();
}
Student stu = new Student();
stu.setId(Math.abs((int)System.currentTimeMillis()));
stu.setName("name#"+number);
stu.setAge(18+number);
stu.setSex(number%2);
long result = noteDao.insert(stu);
Toast.makeText(context, "result="+result, Toast.LENGTH_SHORT).show();
number++;
}
private void search() {
//loadAll里面有 new ArrayList<>();所以不是同一个了
datas = noteDao.loadAll();
for(Student stu : datas){
Log.i("Main","查询结果stu#"+stu.getName()+"|"+stu.getAge()+"|"+stu.getSex());
}
adapter = new DemoAdapter(datas, context);
listView1.setAdapter(adapter);
//adapter.notifyDataSetChanged();//因为重新new了一个列表,所以刷新不起作用了;
}
protected void delete() {
noteDao.delete(datas.get(index));
}
protected void update() {
Student stu = new Student();
stu = datas.get(index);
stu.setName(stu.getName()+"更新");
noteDao.update(stu);
}
}
DemoAdapter.java
public class DemoAdapter extends BaseAdapter {
private List<Student> datas;
private Context context;
public DemoAdapter(List<Student> datas, Context context) {
super();
this.datas = datas;
this.context = context;
}
@Override
public int getCount() {
return datas.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(context);
textView.setText(datas.get(position).getName()+"|"+datas.get(position).getAge());
textView.setTextSize(25);
return textView;
}
}
这个是我简化了官方demo的例子,官方例子是有3个表的,所以如果想添加一个表的话,照猫画虎完成JavaBean和DAO并且在DaoMaster和
DaoSession分别进行注册就好;
分别是:
DaoMaster 中的 registerDaoClass(StudentDao.class);
DaoSession中的 registerDao(Student.class, studentDao);
当然还要在Dao对象的DaoSession提供get方法;
运行效果是:
注:GreenDAO的github地址:https://github.com/greenrobot/greenDAO
这里推荐5种ORM框架:
1OrmLite:OrmLite 不是 Android 平台专用的ORM框架,它是Java ORM。
2SugarORM: 是 Android 平台专用ORM。提供简单易学的APIs。
3GreenDao:当性能很重要时(数据访问频繁),GreenDao是一个很快的解决方案
4Active Record:是Yii、Rails等框架中对ORM实现的典型命名方式,以面向对象的方式来操作SQLite。
5Realm:是一个将可以使用的Android ORM,基于C++编写,直接运行在你的设备硬件上(不需要被解释),因此运行很快。
Demo下载地址:
http://download.csdn.net/detail/dreamintheworld/8820923
本文来自CSDN博客 转载请联系作者
注明出处http://blog.csdn.net/dreamintheworld/article/details/39450365