}
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
{
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
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
答案是可以的。在User中添加如下属性,且注解如下:
@ForeignCollectionField
private Collection
我们在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
总结
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的Android开发中高级必知必会核心笔记,共计2968页PDF、58w字,囊括Android开发648个知识点,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。
虽然面试失败了,但我也不会放弃入职字节跳动的决心的!建议大家面试之前都要有充分的准备,顺顺利利的拿到自己心仪的offer。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
3): 张鸿洋
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
总结
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的Android开发中高级必知必会核心笔记,共计2968页PDF、58w字,囊括Android开发648个知识点,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。
[外链图片转存中…(img-wOVX339j-1714686451776)]
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。
虽然面试失败了,但我也不会放弃入职字节跳动的决心的!建议大家面试之前都要有充分的准备,顺顺利利的拿到自己心仪的offer。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!