Android 快速开发系列 ORMLite 框架最佳实践

本文介绍了在Android应用中如何使用ORMLite库进行数据库操作,包括单例模式管理SQLite连接,创建针对不同Bean的Dao,处理外键引用,以及如何执行条件查询。作者还展示了如何在关联对象中设置外键自动刷新和集合查询示例。
摘要由CSDN通过智能技术生成

}

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

==========

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

类这么定义:

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类暂且就两个属性:

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

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

listByUserId(int userId)

{

try

{

return articleDaoOpe.queryBuilder().where().eq(“user_id”, userId)

.query();

} catch (SQLException e)

{

e.printStackTrace();

}

return null;

}

}

接下来看我们的测试类:

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

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、即上述写法

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

articles,我能否在查询User的时候,一并能够获取到articles的值呢?

答案是可以的。在User中添加如下属性,且注解如下:

@ForeignCollectionField

private Collection

articles;

我们在UserDao中书写查询User的代码:

public User get(int id)

{

try

{

return userDaoOpe.queryForId(id);

} catch (SQLException e)

{

e.printStackTrace();

}

return null ;

}

测试代码:

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());

}

}

输出:

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

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

如何做好面试突击,规划学习方向?

面试题集可以帮助你查漏补缺,有方向有针对性的学习,为之后进大厂做准备。但是如果你仅仅是看一遍,而不去学习和深究。那么这份面试题对你的帮助会很有限。最终还是要靠资深技术水平说话。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。建议先制定学习计划,根据学习计划把知识点关联起来,形成一个系统化的知识体系。

学习方向很容易规划,但是如果只通过碎片化的学习,对自己的提升是很慢的。

我们搜集整理过这几年字节跳动,以及腾讯,阿里,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。

img

我们在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

enmXK-1713759538825)]

[外链图片转存中…(img-emEP0MQV-1713759538826)]

[外链图片转存中…(img-if3oWJmy-1713759538827)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

[外链图片转存中…(img-q1Bke7N6-1713759538828)]

如何做好面试突击,规划学习方向?

面试题集可以帮助你查漏补缺,有方向有针对性的学习,为之后进大厂做准备。但是如果你仅仅是看一遍,而不去学习和深究。那么这份面试题对你的帮助会很有限。最终还是要靠资深技术水平说话。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。建议先制定学习计划,根据学习计划把知识点关联起来,形成一个系统化的知识体系。

学习方向很容易规划,但是如果只通过碎片化的学习,对自己的提升是很慢的。

我们搜集整理过这几年字节跳动,以及腾讯,阿里,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。

[外链图片转存中…(img-YpRP58ag-1713759538828)]

我们在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 14
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值