@Property(nameInDb = “user_name”)
private String userName;
@Property(nameInDb = “phone_number”)
private String phoneNumber;
@Property(nameInDb = “address”)
private String address;
@Generated(hash = 459973421)
public UserInfo(long id, String userName, String phoneNumber, String address) {
this.id = id;
this.userName = userName;
this.phoneNumber = phoneNumber;
this.address = address;
}
@Generated(hash = 1279772520)
public UserInfo() {
}
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public String getUserName() {
return this.userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPhoneNumber() {
return this.phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return “UserInfo{” +
“id=” + id +
“, userName='” + userName + ‘’’ +
“, phoneNumber='” + phoneNumber + ‘’’ +
“, address='” + address + ‘’’ +
‘}’;
}
}
2.2. 查看UserInfoDAO,DaoMaster及DaoSession
上述操作结束之后,在工程目录下,GreenDAO的生成目录中可以找到相应的数据库操作类,我实体类UserInfo的操作类名称为UserInfoDAO,同时也会自动生成DaoMaster和DaoSession
可以看到生成了三个文件,一个是实体类的操作类,还有DaoMaster,DaoSession等类。
我们先看看DaoMaster类,DaoMaster类主要定义了几个函数
(1)createAllTables、dropAllTables
/** Creates underlying database table using DAOs. */
public static void createAllTables(Database db, boolean ifNotExists) {
UserInfoDao.createTable(db, ifNotExists);
}
/** Drops underlying database table using DAOs. */
public static void dropAllTables(Database db, boolean ifExists) {
UserInfoDao.dropTable(db, ifExists);
}
这两个方法表明了DaoMaster的两个作用,创建和删除所有表。
(2)newSession
public DaoSession newSession() {
return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);
}
public DaoSession newSession(IdentityScopeType type) {
return new DaoSession(db, type, daoConfigMap);
}
这两个类可以创建Session绘画,有两种重载形式,一种可以让我们自定义类型。
(3)构造函数
public DaoMaster(SQLiteDatabase db) {
this(new StandardDatabase(db));
}
public DaoMaster(Database db) {
super(db, SCHEMA_VERSION);
registerDaoClass(UserInfoDao.class);
}
两个重载形式,一个时生成一个数据库,另一个则是注册Config,查看一下registerDaoClass类则会发现,daoConfigMap是一个Map结构
protected final Map<Class<? extends AbstractDao<?, ?>>, DaoConfig> daoConfigMap;
protected void registerDaoClass(Class<? extends AbstractDao<?, ?>> daoClass) {
DaoConfig daoConfig = new DaoConfig(db, daoClass);
daoConfigMap.put(daoClass, daoConfig);
}
通过传进来的UserInfoDao.class作为key,对这个daoConfig进行绑定操作。
而进入到DaoConfig类中,查看DaoConfig的源码时,可以看到注释中的介绍
/**
-
Internal class used by greenDAO. DaoConfig stores essential data for DAOs, and is hold by AbstractDaoMaster. This
-
class will retrieve the required information from the DAO classes.
*/
DaoConfig存储DAO的基本数据,并由AbstractDaoMaster所持有。 该类将从DAO类中检索所需的信息。即将DAO类作为key来检索信息
而DaoSession类则主要是用来操作DAO对象的,它有三个方法
(1)构造函数
public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig>
daoConfigMap) {
super(db);
userInfoDaoConfig = daoConfigMap.get(UserInfoDao.class).clone();
userInfoDaoConfig.initIdentityScope(type);
userInfoDao = new UserInfoDao(userInfoDaoConfig, this);
registerDao(UserInfo.class, userInfoDao);
}
从代码中我们可以看到,构造函数做了这么几件事儿
1.取出map中对应DAO的daoConfig
2.初始化缓存类型
3.根据配置可以得到一个DAO对象
4.将DAO对象进行注册,也是通过Map进行管理
(2)getUserInfoDao方法
public UserInfoDao getUserInfoDao() {
return userInfoDao;
}
可返回dao对象,说明可以返回dao对象并对其进行具体的操作了。
(3)clear函数
public void clear() {
userInfoDaoConfig.clearIdentityScope();
}
clear函数就是清楚缓存的函数, clearIdentityScope()
2.3编写DaoManage类
其实,上面操作过后,可以直接进行数据库的使用了,但是这里仍然编写了一个DaoManage类,希望在使用过程中更方便的进行初始化工作
主要内容就是进行各种变量的初始化之后,获得数据库,获取DaoSession对象好对表进行数据操作。
代码如下:
public class DaoManage {
private Context mContext;
//数据库的名称
private static final String DB_NAME = “user.db”;
//多线程中要被共享的要用volatile修饰,Greendao管理类
private volatile static DaoManage mInstance;
//DAOMaster 保存数据库对象
private static DaoMaster mDaoMaster;
//Helper类
private static DaoMaster.DevOpenHelper mHelper;
//Dao对象中的增删改查的对象
private static DaoSession mDaoSession;
private DaoManage(){
}
//使用单例模式来获取GreenDao管理类的对象,即操作数据库的对象
public static DaoManage getInstance(){
if (mInstance == null){
synchronized (DaoManage.class){
if(mInstance == null){
mInstance = new DaoManage();
}
}
}
return mInstance;
}
//初始化上下文
public void init(Context context){
this.mContext = context;
}
//创建(若没有)并获取数据库
public DaoMaster getDaoMaster(){
if(mDaoMaster == null){
//创建一个数据库
mHelper = new DaoMaster.DevOpenHelper(mContext, DB_NAME, null);
mDaoMaster = new DaoMaster(mHelper.getWritableDatabase());
}
return mDaoMaster;
}
//获取DaoSession对象,完成增删改查操作
public DaoSession getDaoSession(){
if(null == mDaoSession){
//若表为空,new一个
if(null == mDaoMaster){
//若数据库为空,则创建数据库
mDaoMaster = getDaoMaster();
}
mDaoSession = mDaoMaster.newSession();
}
return mDaoSession;
}
//关闭连接
public void closeConnection(){
if(mHelper != null){
mHelper.close();
mHelper = null;
}
if(mDaoSession != null){
mDaoSession.clear();
mDaoSession = null;
}
}
}
三、GreenDao使用(2)
3.1. 编写DBHelper类
实际上,GreenDao的数据库操作已经十分简便,我们是可以直接进行使用的,但是为了更加整洁的使用,我还是将增删改查的操作进行了封装,写在了DBHelper类中
(0)加入UserInfoDao对象属性并初始化
private UserInfoDao userInfoDao = DaoManage.getInstance().getDaoSession().getUserInfoDao();
(1)按id查找数据
//查找(按id查找)
public UserInfo queryById(Long id){
List list = userInfoDao.queryBuilder().where(UserInfoDao.Properties.Id.eq(id)).build().list();
UserInfo userInfo = list.isEmpty() ? null : list.get(0);
return userInfo;
}
(2)查找全部
//查找全部
public List queryAll(){
return userInfoDao.queryBuilder().build().list();
}
查询还可以批量查询,多条件查询,模糊搜索等等内容,由于太多,就不全部列出来了,可以查阅相关文档按照需要进行使用。
(3)增
//增加
public void add(UserInfo userInfo){
if (queryById(userInfo.getId()) == null){
userInfoDao.insert(userInfo);
}else{
userInfoDao.update(userInfo);
}
}
//批量增加
public void add(List userInfoList){
userInfoDao.insertInTx(userInfoList);
}
(4)删
//删除一个对象
public void delete(UserInfo userInfo){
userInfoDao.delete(userInfo);
}
//删除一个列表的对象
public void deleteByList(List userInfoList){
userInfoDao.deleteInTx(userInfoList);
}
//按主键删除
public void delteByKey(long key){
userInfoDao.deleteByKey(key);
}
//按主键列表删除
public void deleteByKeyList(List idList){
userInfoDao.deleteByKeyInTx(idList);
}
//删除所有
public void deleteAll(){
userInfoDao.deleteAll();
}
(5)改
//修改
public boolean update(UserInfo userInfo){
UserInfo findUser = userInfoDao.queryBuilder().where(UserInfoDao.Properties.Id.eq(userInfo)).build().unique();
if (findUser != null){
userInfoDao.update(userInfo);
return true;
}else{
return false;
}
}
3.2.在MainActivity中进行使用
在Android6.0之后,我们需要在代码中先对权限进行检查,即检查有没有文件的读写权限,如果没有权限,要申请权限,所以在onCreate()函数中,在前面要先加入一段代码:
//检查当前权限,如果没有,申请request,
if(ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
//申请一个或多个权限
ActivityCompat.requestPermissions(MainActivity.this, new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
}, 100);
}
在类中添加DBHelper类的成员对象,并进行初始化
DBHelper dbHelper = new DBHelper();
之后可以在onCreate()函数中进行使用
先增加一个数据
UserInfo userInfo1 = new UserInfo(null, “laichangping1”, “12345678901”, “longyan”);
dbHelper.add(userInfo1);
进行查找,并查看结果
//查找
List userInfos = dbHelper.queryAll();
for(UserInfo userInfo : userInfos){
Log.i(“add>>”, userInfo.toString());
}
添加成功
之后,再添加userInfo2和userInfo3,将他们按列表添加,再进行查找
List userInfoList = new ArrayList<>();
userInfoList.add(userInfo2);
userInfoList.add(userInfo3);
dbHelper.add(userInfoList);
//查找
List userInfos = dbHelper.queryAll();
for(UserInfo userInfo : userInfos){
Log.i(“add>>”, userInfo.toString());
}
按主键删除userInfo1并查找
//按主键删除
dbHelper.deleteByKey(userInfo1.getId());
//查找
List userInfos = dbHelper.queryAll();
for(UserInfo userInfo : userInfos){
Log.i(“add>>”, userInfo.toString());
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
![](https://i-blog.csdnimg.cn/blog_migrate/bbfd7a6cccd2abc51ff65159dc51f40d.jpeg)
尾声
最后,我再重复一次,如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。
Android进阶学习资料库
一共十个专题,包括了Android进阶所有学习资料,Android进阶视频,Flutter,java基础,kotlin,NDK模块,计算机网络,数据结构与算法,微信小程序,面试题解析,framework源码!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
712231288204)]
[外链图片转存中…(img-PwEzgviE-1712231288204)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
![](https://i-blog.csdnimg.cn/blog_migrate/bbfd7a6cccd2abc51ff65159dc51f40d.jpeg)
尾声
最后,我再重复一次,如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。
[外链图片转存中…(img-rJruKwfc-1712231288204)]
Android进阶学习资料库
一共十个专题,包括了Android进阶所有学习资料,Android进阶视频,Flutter,java基础,kotlin,NDK模块,计算机网络,数据结构与算法,微信小程序,面试题解析,framework源码!
[外链图片转存中…(img-neWpjdFJ-1712231288204)]