配置就完成了,之后点击Sync Now
在Sync时,出现了下载依赖很慢的事情,所以我在工程目录下的build.gradle将buildscript的repositories改成了
repositories {
google()
//jcenter()
maven{ url ‘http://maven.aliyun.com/nexus/content/groups/public/’}
}
以及
allprojects {
repositories {
google()
//jcenter()
maven{ url ‘http://maven.aliyun.com/nexus/content/groups/public/’}
}
}
把地址改成了阿里云的仓库,下载就快了。
二、使用greendao(1)
2.1. 创建一个实体类
在目录下创建一个Package名为bean,在bean包下面创建一个Java类,类为实体类,即仅有属性以及getter、setter、构造方法以及toString()方法的类,一个实体类则对应一张数据库的表,我将这个实体类取名为UserInfo,类中有id,userName,phoneNumber,address等属性
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Property;
@Entity
public class UserInfo {
@Id
private Long id;
@Property(nameInDb = “user_name”)
private String userName;
@Property(nameInDb = “phone_number”)
private String phoneNumber;
@Property(nameInDb = “address”)
private String address;
}
在这里,我用了许多注解,而这些注解有什么作用呢?简单介绍一下在GreenDao中常用的一些注解
@Entity:将我们的java普通类变为一个能够被greenDAO识别的数据库类型的实体类,也就是将这个类标记为要映射到数据库的实体类
@Id:主键,选择使用long或Long,若写成@Id(autoincrement = true)则可标记为自增长。
@Property(nameInDb = “”) :表示该类的这个属性是表的一个字段(即一列),且非主键,nameInDb值则是这个字段的名字,
@NotNull: 不为null
@Transient 不保存于数据库,添加此标记后不会生成数据库表的列
@Index 作为一个属性来创建一个索引,通过name设置索引别名,也可以通过unique给索引添加约束
@Unique: 唯一约束,也就是值必须唯一
@ToOne 表为一对一关系
@ToMany 一对多关系
@Generated 由greendao产生的构造函数或方法,此注释标记的所有代码元素都可以在生成的下一次运行中更改/删除
编译(Make Project)之后,代码就自动生成了构造函数及set get方法,之后再加上toString方法,在进行数据库操作时,可用toString()方法打印来验证结果的正确性。
@Entity
public class UserInfo {
@Id
private long id;
@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);
}
最后
以前一直是自己在网上东平西凑的找,找到的东西也是零零散散,很多时候都是看着看着就没了,时间浪费了,问题却还没得到解决,很让人抓狂。
后面我就自己整理了一套资料,还别说,真香!
资料有条理,有系统,还很全面,我不方便直接放出来,大家可以先看看有没有用得到的地方吧。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
elfPermission(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);
}
最后
以前一直是自己在网上东平西凑的找,找到的东西也是零零散散,很多时候都是看着看着就没了,时间浪费了,问题却还没得到解决,很让人抓狂。
后面我就自己整理了一套资料,还别说,真香!
资料有条理,有系统,还很全面,我不方便直接放出来,大家可以先看看有没有用得到的地方吧。
[外链图片转存中…(img-Fed3NGiy-1714803375825)]
[外链图片转存中…(img-hj1jcCAm-1714803375826)]
[外链图片转存中…(img-dFxtzx5Y-1714803375826)]
[外链图片转存中…(img-HojX9nB2-1714803375826)]
[外链图片转存中…(img-exnKPVPl-1714803375827)]
[外链图片转存中…(img-7Wqu6VaO-1714803375827)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!