Bmob使用笔记之二

一些注意事项说明

(1) Bmob创建应用的 AppId可以和我们本地的应用不同哦,包名都不需要写,但是退送服务必须填写包名

MyUser user = BmobUser.getCurrentUser(this, MyUser.class);

该方法只需用户登陆成功后(只要不卸载应用),从内存中得到User对象(包含objectId,username,password等等)
(2)增删改查 原理其实都是根据 id 改变的(和 Sqlite,设置Hibernate其实是一样的)所以做这些操作时候一定要保证 id不为NULL

(3) 当一个用户的邮件被新添加或者修改过的话emailVerified会被默认设为false,如果应用设置中开启了邮箱认证功能,Bmob会对用户填写的邮箱发送一个链接,
这个链接可以把emailVerified设置为 true.
email还没有验证成功的情况下,用户或者邮箱 也可以登录成功,仅仅emailVerified为false而已

(4)BmobQuery 查询单条数据使用
query.getObject(context, objectId, callback)
BmobQuery 查询 多条数据使用
query.findObjects(this, new FindListener() { ....}

(5)User bmobUser = (User) User.getCurrentUser(this);抛出错误,不能转换,看来本地缓存对象只保存了 BmobUser

数据库操作(查询)

查询单条数据

BmobQuery query = new BmobQuery();
            query.getObject(this, "b343b9d4f7", new GetListener() {
                
                @Override
                public void onFailure(int code, String reason) {
                    Toast.makeText(MainActivity.this, "code"+code +" "+reason, Toast.LENGTH_SHORT).show();
                }
                
                @Override
                public void onSuccess(MyUser user) {
                    Toast.makeText(MainActivity.this, user.getUsername(), Toast.LENGTH_SHORT).show();
                    
                }
            }); 
            

查询多条数据

BmobQuery query = new BmobQuery();
            query.findObjects(this, new FindListener() {
                
                @Override
                public void onSuccess(List list) {
                    Toast.makeText(MainActivity.this, "得到的用户数是:"+list.size(), Toast.LENGTH_SHORT).show();

                }
                
                @Override
                public void onError(int code, String msg) {
                    // TODO Auto-generated method stub
                    Toast.makeText(MainActivity.this, "code"+code +" "+msg, Toast.LENGTH_SHORT).show();

                }
            });

注意 : query.getObject(this, "b343b9d4f7", new GetCallback() //查询单条
query.findObjects(this, new FindCallback() {} //查询多条
这 两个回调函数什么也查不到,故不要使用。

官方说: 应该在使用 自定义表名 的情况下使用上面两个方法(上面两个回调返回的参数是Json格式的,需要自己解析)

数据库操作(更新)

(1)需要用户先登录成功
(2)MyUser user = BmobUser.getCurrentUser(this,MyUser.class);

MyUser myuser = BmobUser.getCurrentUser(this, MyUser.class);
            myuser.setNickName("稻草人2");
            myuser.setAddress("北京市");
            myuser.update(this, new UpdateListener() {
                
                @Override
                public void onSuccess() {
                    // TODO Auto-generated method stub
                    toast("更新用户信息成功");
                }
                
                @Override
                public void onFailure(int arg0, String arg1) {
                    // TODO Auto-generated method stub
                    
                }
            });

登录功能
只需要 开启邮箱验证,或者手机验证等等,那么user.setUsername(user) user 就可以填写邮箱号码或手机号充当username。

MyUser user  = new MyUser();
        user.setUsername("可填用户名或者邮箱号"); //开启邮箱验证的情况下
        user.setPassword("abc");
        user.setEmail("这里可填可不填");
        
        user.login(this, new SaveListener() {
            
            @Override
            public void onSuccess() {
                Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show();               
            }
            
            @Override
            public void onFailure(int arg0, String arg1) {
                // TODO Auto-generated method stub
                Toast.makeText(MainActivity.this, "登录失败:"+arg1, Toast.LENGTH_SHORT).show();

            }
        });
        

重置密码(该方法直接发送更新密码的邮件,不需要登陆用户就可以使用)

因为如果用户真的使用 xx邮箱注册过,那么他就可以直接登陆xx邮箱 修改 密码,这是安全的做法,请放心使用

final String email = "[email protected]";
            BmobUser.resetPasswordByEmail(this, email, new ResetPasswordByEmailListener() {
                
                @Override
                public void onSuccess() {
                    // TODO Auto-generated method stub
                    Toast.makeText(MainActivity.this,"重置密码请求成功,请到" + email + "邮箱进行密码重置操作",Toast.LENGTH_SHORT).show();
                }
                
                @Override
                public void onFailure(int arg0, String arg1) {
                    // TODO Auto-generated method stub
                    
                }
            });
                    

等价关系

MyUser user = BmobUser.getCurrentUser(this, MyUser.class);

user.setValue("age", "10000");
等价于 
user.setAge("10000");

注意: user.setAge(null); 和user.setValue("age",null); 
测试对数据无效,故删除age字段数据使用user.setAge(""); 或者 user.remove("age");
user.update(this);

保存对象和数组的功能

           MyUser user = BmobUser.getCurrentUser(this,MyUser.class);
        List hobbys = new ArrayList();
        hobbys.add("阅读");
        hobbys.add("篮球");
        hobbys.add("唱歌");
        user.setHobbys(hobbys);
        
        BankCard bankCard = new BankCard();
        bankCard.setTitle("中南银行");
                
            user.setBankCard(bankCard); //等价user.setValue("bankCard",bankCard);
            
        user.update(this);

查看云端 数据 发现 存储形式是:

hobbys(Array) ["阅读","篮球","唱歌"]
bankCard(Object) {"title":"中南银行"} 对象以 json格式存储

删除hobbys中的数据
删除user用户的hobby属性中含有 阅读","唱歌","游泳的 字符串
user.removeAll("hobby", Arrays.asList("阅读","唱歌","游泳"));

成功删除阅读,游泳(唱歌在云端原本不存在哦)
user.update(this, new UpdateListener() {
.....
}

数组 数据的添加

对于数组类型数据, add addAll (在一个数组字段的后面添加一些指定的对象(包装在一个数组内)
如 : user.add("hobbys","泡妞"); user.update(this);
更新之后  云端数据是: ["篮球","唱歌","泡妞"]
如 : user.addAll("hobbys", Arrays.asList("打架", "斗殴"));
云端数据 : ["篮球","唱歌","泡妞","打架","斗殴"]
当然了: 数组里面不仅可以放String类型,也可以放Object类型哦
 如: user.add("hobbys",new XingQu("泡妞"));

addUnique、addAllUnique(只会在原本数组字段中没有这些对象的情形下才会添加入数组,插入数组的位置随机)

删除数组数据 ,同理我们也可以使用removeAll从数组字段中移除某些值:

Person p = new Person();
p.removeAll("hobby", Arrays.asList("阅读","唱歌","游泳"));
p.update(this, new UpdateListener() {
 .......
}

查询数组数据

BmobQuery query = new BmobQuery();
String [] hobby = {"阅读","唱歌"};
query.addWhereContainsAll("hobby", Arrays.asList(hobby));
query.findObjects(this, new FindListener() {
  ...
}

分页查询

query.setLimit(10); // 限制最多10条数据结果作为一页
query.setSkip(10); // 忽略前10条数据(即第一页数据结果)
类似 mysql 的limit

排序

// 根据score字段升序显示数据
query.order("score");
// 根据score字段降序显示数据
query.order("-score");
// 多个排序字段可以用(,)号分隔
query.order("-score,createdAt");
说明:多个字段排序时,先按第一个字段进行排序,再按第二个字段进行排序,依次进行。

批量操作

注意:
1.任何一种批量操作每次只支持最大50条记录的操作。
2.批量操作不支持对User表的操作。

new BmobObject().insertBatch
new BmobObject().updateBatch
new BmobObject().deleteBatch

批量上传

Bmob.uploadBatch(context, filePaths, new UploadBatchListener() {
BmobProFile.getInstance(context).uploadBatch(files, new UploadBatchListener() {....}

关联关系(关联关系映射)

问题代码 (下面成功创建两张表,且创建了关联关系,但是 user.setDepartment(department);失败,因为本地对象还没有赋值objectId)

结果:

User表
objectId         name           department Pointer  
8cb0fd1660      "经理部"           null

错误代码如下

    Department department = new Department();
    department.setName("网购部门");
    department.save(this);
            
    User user = new User();
    user.setName("xx");
    user.setAge("20");
    user.setDepartment(department);
    user.save(this); 

注:include的查询对象只能为BmobPointer类型,而不能是BmobRelation类型。

一对一
知道一个Department depart,查询该 depar下所有的User(User方设置外键 )

Bmob的做法:

Department depart = findDepartmentById(d9330d061c);

BmobQuery query = new BmobQuery();
query.addWhereEqualTo("depart",depart);  //
query.include("depart"); //查询得到的Users里面含有 depart(外键属性)
query.findObjects(this,new FindListener(){.......} );

总结: 上面的方式就如同

Hibernate中 Department表   
Set users = new HashSetusers();
Department depart = findDepartmentById(d9330d061c);
depart.getUsers();

一对多

查询评论(很像上面查询 用户)

//Conmment评论 ,Post帖子,User用户
Post post = findDepartmentById(1ffegca);  //这个对象只需要  objectId即可 

BmobQuery query = new BmobQuery();   
query.addWhereEqualTo("post",new BmobPointer(post));        
//希望同时查询该评论的发布者的信息,以及该帖子的作者的信息,这里用到上面`include`的并列对象查询和   内嵌对象的查询
query.include("user,post.author");
query.findObjects(this, new FindListener(){....}

知道了一个User user,查询 该User对应的Department

User user = findById(0ffg034);
BmobQuery query = new BmobQuery();
query.include("depart");
query.getObject(); //query.findObjects();  和    [知道一个Department depart,查询该 depar下所有的User]用法完全一样,仅仅addWhereEqualTo不一样而已啦

多对多关系
一个帖子可以被很多用户所喜欢,一个用户也可能会喜欢很多帖子,那么可以使用Relation类型来表示这种多对多关联关系。
Relation本质上可以理解为其存储的是一个对象,而这个对象中存储的是多个指向其它记录的指针。(中间关系表 )

内部查询

非常类似于 mysql中的 子查询

如: 查询带有图片的帖子的评论列表:
mysql的做法是
1.先查询所有带图片的帖子
2.从这些帖子里面查询所有评论)

BmobQuery query = new BmobQuery();
BmobQuery innerQuery = new BmobQuery();
innerQuery.addWhereExists("image", true);
// 第一个参数为评论表中的帖子字段名post(我理解为外键名)
// 第二个参数为Post字段的表名,也可以直接用"Post"字符串的形式(我理解为One方的表名)
// 第三个参数为内部查询条件
query.addWhereMatchesQuery("post", "Post", innerQuery);//反之,不想匹配某个子查询,你可以使用addWhereDoesNotMatchQuery方法(查询不带图片的帖子的评论列表)
query.findObjects(this, new FindListener() {
    @Override
    public void onSuccess(List object) {
        // TODO Auto-generated method stub
        toast("查询成功:");
    }
    @Override
    public void onError(int code, String msg) {
        // TODO Auto-generated method stub
        toast("查询失败:"+msg);
    }
});

内部查询实例2:

BmobQuery userQuery = new BmobQuery();
            BmobQuery innerQuery = new BmobQuery();
            innerQuery.addWhereEqualTo("name", "经理部");
            
            userQuery.addWhereMatchesQuery("department", "Department", innerQuery);
            userQuery.findObjects(this, new FindListener() {
                
                @Override
                public void onSuccess(List arg0) {
                    Toast.makeText(MainActivity.this, "查询成功"+arg0.size(), Toast.LENGTH_SHORT).show();
                    
                }
                
                @Override
                public void onError(int arg0, String arg1) {
                    // TODO Auto-generated method stub
                    Toast.makeText(MainActivity.this, "查询失败", Toast.LENGTH_SHORT).show();
                    
                }
            });

文件上传操作

文件上传操作:
先上传文件,上传成功后,像普通对象一样,再进行数据的添加操作。
insertObject(new MyUser("wangli",bmobFile));

注意: MyUser表结构是 String | BmobFile类型

BmobFile icon = bmobFile.getIcon();
icon.loadImage(TestFileActivity.this, iv_icon);// iv_icon是ImageView 


BmobFile icon = bmobFile.getIcon();
icon.loadImageThumbnail(TestFileActivity.this, iv_icon, 100, 100, 100); //iv_icon是ImageView

文件操作详解

旧版 BmobFile 文件下载的具体代码实现需要大家自行实现
新版 BmobProFile文件下载已经实现

虽然新版上传下载更好,但是 云端字段最好还是设置成 BmobFile类型的;
User表 name(String) icon(BmobFile)

新版: 文件的单一上传、批量上传、文件下载、生成缩略图等功能。

单一上传   
BmobProFile.getInstance(context).upload(filePath, new UploadListener() {
  @Override
            public void onSuccess(String fileName,String url,BmobFile file) {
                Log.i("bmob","文件上传成功:"+fileName+",可访问的文件地址:"+file.getUrl());
                // TODO Auto-generated method stub
                // fileName :文件名(带后缀),这个文件名是唯一的,开发者需要记录下该文件名,方便后续下载或者进行缩略图的处理
                // url        :文件地址
                // file        :BmobFile文件类型,`V3.4.1版本`开始提供,用于兼容新旧文件服务。
                注:若上传的是图片,url地址并不能直接在浏览器查看(会出现404错误),需要经过`URL签名`得到真正的可访问的URL地址,当然,`V3.4.1`的版本可直接从'file.getUrl()'中获得可访问的文件地址。
            }
}



批量上传 :BmobProFile.getInstance(context).uploadBatch(files, new UploadBatchListener() {}


文件下载: BmobProFile.getInstance(context).download(fileName, new DownloadListener() {}//这个filename参数是 使用BmobProFile上传成功的 fileName,自行保存

获取文件地址: BmobProFile.getInstance(context).getAccessURL(fileName, new GetAccessUrlListener() {} //fileName也是 BmobProFile上传成功的fileName 


文件删除:BmobProFile.getInstance(context).deleteFile(fileName, new DeleteFileListener() {}//fileName也是 BmobProFile上传成功的fileName 

缓存目录:(里面存储了BmobProFile下载下来的文件)
1.可以自定义缓存目录名称,可在Apllication中对其进行初始化配置(下载文件前调用哦)

BmobConfiguration config = new BmobConfiguration.Builder(context).customExternalCacheDir("目录名").build();
BmobPro.getInstance(context).initConfig(config);

2.注意事项

(1)缓存总目录下,包含上面两个分目录,分别用于保存下载文件和缩略图(这个缩略图我们都不需要,自己写算了)。

(2)因为Android手机系统的高定制度和复杂性,此方法只允许定义缓存目录的名称,并不支持自定义缓存路径,缓存路径由SDK根据手机系统进行分配。

(3)获取各分目录的完整路径:
通过如下方法可获取保存下载文件的完整路径:

//可自行打印此路径,通过文件管理器查看文件是否下载成功
BmobPro.getInstance(context).getCacheDownloadDir()

(4)获取缓存大小:

//文件大小(单位:字节)
String cacheSize = String.valueOf(BmobPro.getInstance(context).getCacheFileSize());

//对文件大小进行格式化,转化为'B'、'K'、'M'、'G'等单位
String formatSize = BmobPro.getInstance(context).getCacheFormatSize();

(5)清除缓存:

 BmobPro.getInstance(context).clearCache();

你可能感兴趣的:(Bmob使用笔记之二)