Android 快速开发系列 ORMLite 框架最佳实践
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Android 快速开发系列 ORMLite 框架最佳实践,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含11068字,纯文字阅读大概需要16分钟。
内容图文
![Android 快速开发系列 ORMLite 框架最佳实践](/upload/InfoBanner/zyjiaocheng/1221/4379947e198e414e83ade0c6506f4d63.jpg)
上一篇已经对ORMLite框架做了简单的介绍:Android ORMLite 框架的入门用法~~本篇将介绍项目可能会使用到的一些用法,也为我们的使用ORMLite框架总结出一个较合理的用法。
通过上一篇的了解,我们使用ORMLite,需要自己写一个DatabaseHelper去继承OrmLiteSqliteOpenHelper,下面我们首先给出一个我认为比较靠谱的Helper的写法:
1、DatabaseHelper
[java] view plaincopy
-
package com.zhy.zhy_ormlite.db;
-
-
import java.sql.SQLException;
-
import java.util.HashMap;
-
import java.util.Map;
-
-
import android.content.Context;
-
import android.database.sqlite.SQLiteDatabase;
-
-
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
-
import com.j256.ormlite.dao.Dao;
-
import com.j256.ormlite.support.ConnectionSource;
-
import com.j256.ormlite.table.TableUtils;
-
import com.zhy.zhy_ormlite.bean.Article;
-
import com.zhy.zhy_ormlite.bean.Student;
-
import com.zhy.zhy_ormlite.bean.User;
-
-
public class DatabaseHelper extends OrmLiteSqliteOpenHelper
-
{
-
private static final String TABLE_NAME = "sqlite-test.db";
-
-
private Map<String, Dao> daos = new HashMap<String, Dao>();
-
-
private DatabaseHelper(Context context)
-
{
-
super(context, TABLE_NAME, null, 4);
-
}
-
-
@Override
-
public void onCreate(SQLiteDatabase database,
-
ConnectionSource connectionSource)
-
{
-
try
-
{
-
TableUtils.createTable(connectionSource, User.class);
-
TableUtils.createTable(connectionSource, Article.class);
-
TableUtils.createTable(connectionSource, Student.class);
-
} catch (SQLException e)
-
{
-
e.printStackTrace();
-
}
-
}
-
-
@Override
-
public void onUpgrade(SQLiteDatabase database,
-
ConnectionSource connectionSource, int oldVersion, int newVersion)
-
{
-
try
-
{
-
TableUtils.dropTable(connectionSource, User.class, true);
-
TableUtils.dropTable(connectionSource, Article.class, true);
-
TableUtils.dropTable(connectionSource, Student.class, true);
-
onCreate(database, connectionSource);
-
} catch (SQLException e)
-
{
-
e.printStackTrace();
-
}
-
}
-
-
private static DatabaseHelper instance;
-
-
/**
-
* 单例获取该Helper
-
*
-
* @param context
-
* @return
-
*/
-
public static synchronized DatabaseHelper getHelper(Context context)
-
{
-
context = context.getApplicationContext();
-
if (instance == null)
-
{
-
synchronized (DatabaseHelper.class)
-
{
-
if (instance == null)
-
instance = new DatabaseHelper(context);
-
}
-
}
-
-
return instance;
-
}
-
-
public synchronized Dao getDao(Class clazz) throws SQLException
-
{
-
Dao dao = null;
-
String className = clazz.getSimpleName();
-
-
if (daos.containsKey(className))
-
{
-
dao = daos.get(className);
-
}
-
if (dao == null)
-
{
-
dao = super.getDao(clazz);
-
daos.put(className, dao);
-
}
-
return dao;
-
}
-
-
/**
-
* 释放资源
-
*/
-
@Override
-
public void close()
-
{
-
super.close();
-
-
for (String key : daos.keySet())
-
{
-
Dao dao = daos.get(key);
-
dao = null;
-
}
-
}
-
-
}
1、整个DatabaseHelper使用单例只对外公布出一个对象,保证app中只存在一个SQLite Connection , 参考文章:http://www.touchlab.co/2011/10/single-sqlite-connection/
2、我们对每个Bean创建一个XXXDao来处理当前Bean的数据库操作,当然真正去和数据库打交道的对象,通过上面代码中的getDao(T t)进行获取
getDao为一个泛型方法,会根据传入Class对象进行创建Dao,并且使用一个Map来保持所有的Dao对象,只有第一次调用时才会去调用底层的getDao()。
2、Bean的Dao
[java] view plaincopy
-
package com.zhy.zhy_ormlite.db;
-
-
import java.sql.SQLException;
-
-
import android.content.Context;
-
-
import com.j256.ormlite.dao.Dao;
-
import com.zhy.zhy_ormlite.bean.User;
-
-
public class UserDao
-
{
-
private Context context;
-
private Dao<User, Integer> userDaoOpe;
-
private DatabaseHelper helper;
-
-
public UserDao(Context context)
-
{
-
this.context = context;
-
try
-
{
-
helper = DatabaseHelper.getHelper(context);
-
userDaoOpe = helper.getDao(User.class);
-
} catch (SQLException e)
-
{
-
e.printStackTrace();
-
}
-
}
-
-
/**
-
* 增加一个用户
-
* @param user
-
*/
-
public void add(User user)
-
{
-
try
-
{
-
userDaoOpe.create(user);
-
} catch (SQLException e)
-
{
-
e.printStackTrace();
-
}
-
-
}//...other operations
-
-
-
}
我们的所有的XXXDao遵循以上的风格~
好了,基本了解了我们的代码的结构~~ps:如果觉得不合理可以留言指出,如果觉得不能接收,直接忽略。。。
3、ORMLite外键引用
现在我们有两张表一张User,一张Article;
Article中当然需要存储User的主键,作为关联~~那么在ORMLite中如何做到呢?
可能有人会直接在Article中声明一个int类型userId属性,当作普通属性处理搞定,这种做法并没有做,但是没有体现出面向对象的思想。
面向对象是这样的:Article属于某个User
类这么定义:
[java] view plaincopy
-
package com.zhy.zhy_ormlite.bean;
-
-
import com.j256.ormlite.field.DatabaseField;
-
import com.j256.ormlite.table.DatabaseTable;
-
-
@DatabaseTable (tableName = "tb_article" )
-
public class Article
-
{
-
@DatabaseField(generatedId = true)
-
private int id;
-
@DatabaseField
-
private String title;
-
@DatabaseField(canBeNull = true, foreign = true, columnName = "user_id")
-
private User user;
-
-
public int getId()
-
{
-
return id;
-
}
-
-
public void setId(int id)
-
{
-
this.id = id;
-
}
-
-
public String getTitle()
-
{
-
return title;
-
}
-
-
public void setTitle(String title)
-
{
-
this.title = title;
-
}
-
-
public User getUser()
-
{
-
return user;
-
}
-
-
public void setUser(User user)
-
{
-
this.user = user;
-
}
-
-
@Override
-
public String toString()
-
{
-
return "Article [id=" + id + ", title=" + title + ", user=" + user
-
+ "]";
-
}
-
-
}
不会去定义一个int类型的userId,而是直接定义一个User成员变量,表示本Article属于该User;
然后在User user属性上添加:@DatabaseField(canBeNull = true, foreign = true, columnName = "user_id")
canBeNull -表示不能为null;foreign=true表示是一个外键;columnName 列名
User类暂且就两个属性:
[java] view plaincopy
-
package com.zhy.zhy_ormlite.bean;
-
-
import com.j256.ormlite.field.DatabaseField;
-
import com.j256.ormlite.table.DatabaseTable;
-
-
@DatabaseTable (tableName = "tb_user" )
-
public class User
-
{
-
@DatabaseField(generatedId = true)
-
private int id;
-
@DatabaseField(columnName = "name")
-
private String name;
-
-
-
public User()
-
{
-
}
-
-
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;
-
}
-
-
@Override
-
public String toString()
-
{
-
return "User [id=" + id + ", name=" + name
-
+ "]";
-
}
-
-
-
-
-
-
}
现在看我们的ArticleDao
[java] view plaincopy
-
package com.zhy.zhy_ormlite.db;
-
-
import java.sql.SQLException;
-
import java.util.List;
-
-
import android.content.Context;
-
-
import com.j256.ormlite.dao.Dao;
-
import com.zhy.zhy_ormlite.bean.Article;
-
import com.zhy.zhy_ormlite.bean.User;
-
-
public class ArticleDao
-
{
-
private Dao<Article, Integer> articleDaoOpe;
-
private DatabaseHelper helper;
-
-
@SuppressWarnings("unchecked")
-
public ArticleDao(Context context)
-
{
-
try
-
{
-
helper = DatabaseHelper.getHelper(context);
-
articleDaoOpe = helper.getDao(Article.class);
-
} catch (SQLException e)
-
{
-
e.printStackTrace();
-
}
-
}
-
-
/**
-
* 添加一个Article
-
* @param article
-
*/
-
public void add(Article article)
-
{
-
try
-
{
-
articleDaoOpe.create(article);
-
} catch (SQLException e)
-
{
-
e.printStackTrace();
-
}
-
}
-
-
/**
-
* 通过Id得到一个Article
-
* @param id
-
* @return
-
*/
-
@SuppressWarnings("unchecked")
-
public Article getArticleWithUser(int id)
-
{
-
Article article = null;
-
try
-
{
-
article = articleDaoOpe.queryForId(id);
-
helper.getDao(User.class).refresh(article.getUser());
-
-
} catch (SQLException e)
-
{
-
e.printStackTrace();
-
}
-
return article;
-
}
-
-
/**
-
* 通过Id得到一篇文章
-
* @param id
-
* @return
-
*/
-
public Article get(int id)
-
{
-
Article article = null;
-
try
-
{
-
article = articleDaoOpe.queryForId(id);
-
-
} catch (SQLException e)
-
{
-
e.printStackTrace();
-
}
-
return article;
-
}
-
-
/**
-
* 通过UserId获取所有的文章
-
* @param userId
-
* @return
-
*/
-
public List<Article> listByUserId(int userId)
-
{
-
try
-
{
-
return articleDaoOpe.queryBuilder().where().eq("user_id", userId)
-
.query();
-
} catch (SQLException e)
-
{
-
e.printStackTrace();
-
}
-
return null;
-
}
-
-
}
接下来看我们的测试类:
[java] view plaincopy
-
public class OrmLiteDbTest extends AndroidTestCase
-
{
-
public void testAddArticle()
-
{
-
User u = new User();
-
u.setName("张鸿洋");
-
new UserDao(getContext()).add(u);
-
Article article = new Article();
-
article.setTitle("ORMLite的使用");
-
article.setUser(u);
-
new ArticleDao(getContext()).add(article);
-
-
}
-
-
public void testGetArticleById()
-
{
-
Article article = new ArticleDao(getContext()).get(1);
-
L.e(article.getUser() + " , " + article.getTitle());
-
}
-
-
public void testGetArticleWithUser()
-
{
-
-
Article article = new ArticleDao(getContext()).getArticleWithUser(1);
-
L.e(article.getUser() + " , " + article.getTitle());
-
}
-
-
public void testListArticlesByUserId()
-
{
-
-
List<Article> articles = new ArticleDao(getContext()).listByUserId(1);
-
L.e(articles.toString());
-
}
分别测试,添加一个Article;通过Id获取一个Article;通过Id获取一个Article且携带User;通过userId获取所有的Article;
主要看第三个:通过Id获取一个Article且携带User,testGetArticleWithUser(id)
如何值传一个Article的Id,然后能够拿到Article对象,且内部的user属性直接赋值呢?
两种方式:
1、即上述写法
[java] view plaincopy
-
article = articleDaoOpe.queryForId(id);
-
helper.getDao(User.class).refresh(article.getUser());
2、在user属性的注解上:@DatabaseField(canBeNull = true, foreign = true, columnName = "user_id", foreignAutoRefresh = true)
添加foreignAutoRefresh =true,这样;当调用queryForId时,拿到Article对象则直接携带了user;
4、关联一个集合
每个User关联一个或多个Article,如果我在User中声明一个Collection<Article> articles,我能否在查询User的时候,一并能够获取到articles的值呢?
答案是可以的。在User中添加如下属性,且注解如下:
@ForeignCollectionField
private Collection<Article> articles;
我们在UserDao中书写查询User的代码:
[java] view plaincopy
-
public User get( int id)
-
{
-
try
-
{
-
return userDaoOpe.queryForId(id);
-
} catch (SQLException e)
-
{
-
e.printStackTrace();
-
}
-
return null ;
-
}
测试代码:
[java] view plaincopy
-
public void testGetUserById()
-
{
-
User user = new UserDao(getContext()).get(1);
-
L.e(user.getName());
-
if (user.getArticles() != null)
-
for (Article article : user.getArticles())
-
{
-
L.e(article.toString());
-
}
-
}
输出:
[java] view plaincopy
-
09 - 07 22 : 49 : 06.484 : E/zhy( 7293 ): 张鸿洋
-
09 - 07 22 : 49 : 06.484 : E/zhy( 7293 ): Article [id= 1 , title=ORMLite的使用]
可以看到,我们通过一个queryForId,成功的获取了User,以及User关联的所有的Articles;
5、条件查询QueryBuilder的使用
上述代码其实已经用到了简单的条件查询了:
1、简单的where等于
articleDaoOpe.queryBuilder().where().eq("user_id", userId).query();直接返回Article的列表
2、where and
[java] view plaincopy
-
QueryBuilder<Article, Integer> queryBuilder = articleDaoOpe
-
.queryBuilder();
-
Where<Article, Integer> where = queryBuilder.where();
-
where.eq("user_id", 1);
-
where.and();
-
where.eq("name", "xxx");
-
-
//或者
-
articleDaoOpe.queryBuilder().//
-
where().//
-
eq("user_id", 1).and().//
-
eq("name", "xxx");
上述两种都相当与:select * from tb_article where user_id = 1 and name = ‘xxx‘ ;
3、更复杂的查询
[java] view plaincopy
-
where.or(
-
//
-
where.and(//
-
where.eq("user_id", 1), where.eq("name", "xxx")),
-
where.and(//
-
where.eq("user_id", 2), where.eq("name", "yyy")));
select * from tb_article where ( user_id = 1 and name = ‘xxx‘ ) or ( user_id = 2 and name = ‘yyy‘ ) ;
好了,再复杂的查询估计也能够凑出来了~~
6、updateBuilder、deleteBuilder
使用queryBuilder是因为我们希望执行完成查询直接返回List<Bean>集合;
对于Update我们并不关注返回值,直接使用
articleDaoOpe.updateRaw(statement, arguments);传入sql和参数即可~~
何必在那articleDaoOpe.updateBuilder().updateColumnValue("name","zzz").where().eq("user_id", 1);这样的痛苦呢~~~
同理还有deleteBuilder还是建议直接拼写sql,当然很简单的除外,直接使用它的API~
7、事务操作
在我们的Dao中直接写如下代码:
[java] view plaincopy
-
//事务操作
-
TransactionManager.callInTransaction(helper.getConnectionSource(),
-
new Callable<Void>()
-
{
-
-
@Override
-
public Void call() throws Exception
-
{
-
return null;
-
}
-
});
8、其他操作
1、当Bean继承BaseDaoEnabled时,可以使用bean.create(bean);bean.update(bean)一类操作
例如:
Student extends BaseDaoEnabled<Student, Integer>
Dao dao = DatabaseHelper.getHelper(getContext()).getDao(Student.class);
Student student = new Student();
student.setDao(dao);
student.setName("张鸿洋");
student.create();
前提dao需要手动设置,如果dao为null会报错,尼玛,我觉得一点用没有。。。
2、Join
[java] view plaincopy
-
QueryBuilder<Article, Integer> articleBuilder = articleDaoOpe
-
.queryBuilder();
-
QueryBuilder userBuilder = helper.getDao(User.class).queryBuilder();
-
articleBuilder.join(userBuilder);
Article与User做Join操作;
本篇主要想介绍在项目中如何写DataBaseHelper已经如何写BeanDao,以及列出了在项目中可能会用到的ORMLite的功能,如果需要详细了解,还请看ORMLite官方文档,源码中也会提供~~
原文:http://my.oschina.net/u/1177694/blog/492247
内容总结
以上是互联网集市为您收集整理的Android 快速开发系列 ORMLite 框架最佳实践全部内容,希望文章能够帮你解决Android 快速开发系列 ORMLite 框架最佳实践所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。