游戏服务器里webEs文件管理器被删了,然后用软件恢复之后问什么不能使用了,里面是后台管理网站和游戏下载

8月29日 &杭州校区 &前端基础班现已开始报名啦!
新增品优购电商项目 + 小程序开发基础
品优购电商项目贯穿全程项目阶段,从开发到部署,完全还原企业的真实开发场景
项目基于工程化的方式组织开发,从原型设计、PSD切图、静态页面制作再到业务功能实现,完成整个项目周期
采用目前非常流行的Vue.js框架实现电商管理后台开发,让学员熟练掌握Vue.js框架的企业级项目应用
—————开设校区—————
北京前端与移动开发基础班北京前端与移动开发基础班北京前端与移动开发基础班北京前端与移动开发基础班北京前端与移动开发就业班北京前端与移动开发就业班北京前端与移动开发就业班北京前端与移动开发就业班
深圳前端与移动开发基础班深圳前端与移动开发基础班深圳前端与移动开发基础班深圳前端与移动开发基础班深圳前端与移动开发就业班深圳前端与移动开发就业班深圳前端与移动开发就业班深圳前端与移动开发就业班
上海前端与移动开发基础班上海前端与移动开发基础班上海前端与移动开发基础班上海前端与移动开发基础班上海前端与移动开发就业班上海前端与移动开发就业班上海前端与移动开发就业班上海前端与移动开发就业班
郑州前端与移动开发基础班郑州前端与移动开发基础班郑州前端与移动开发基础班郑州前端与移动开发基础班郑州前端与移动开发就业班郑州前端与移动开发就业班郑州前端与移动开发就业班郑州前端与移动开发就业班
武汉前端与移动开发基础班武汉前端与移动开发基础班武汉前端与移动开发基础班武汉前端与移动开发基础班武汉前端与移动开发就业班武汉前端与移动开发就业班武汉前端与移动开发就业班武汉前端与移动开发就业班
西安前端与移动开发基础班西安前端与移动开发基础班西安前端与移动开发基础班西安前端与移动开发基础班西安前端与移动开发就业班西安前端与移动开发就业班西安前端与移动开发就业班西安前端与移动开发就业班
广州前端与移动开发基础班广州前端与移动开发基础班广州前端与移动开发基础班广州前端与移动开发基础班广州前端与移动开发就业班广州前端与移动开发就业班广州前端与移动开发就业班广州前端与移动开发就业班
长沙前端与移动开发基础班长沙前端与移动开发基础班长沙前端与移动开发基础班长沙前端与移动开发就业班长沙前端与移动开发就业班长沙前端与移动开发就业班长沙前端与移动开发就业班
杭州前端与移动开发基础班杭州前端与移动开发就业班
南京前端与移动开发基础班南京前端与移动开发基础班南京前端与移动开发基础班南京前端与移动开发基础班南京前端与移动开发就业班南京前端与移动开发就业班南京前端与移动开发就业班南京前端与移动开发就业班
Web前端 — IT互联网的“门面”
有人的地方就有江湖,有网站的地方就有Web前端,无所不用,互联网大势所在
Web时代2018年,谷歌、微软、苹果已经全数宣布支持基于Web开发的PWA技术,并推向自己的所有平台,互联网即将迎来全新的Web时代
微信小程序跳一跳、头脑王者等小程序火爆网络的同时,各大企业也掀起了应用小程序开发产品服务的浪潮
网络应用(Web App)Web开发的手机应用可以完美的在苹果手机和安卓手机上同时运行,“跨平台”特性,App开发更轻松快捷
游戏切水果,飞机大战,围住神经猫,Web开发的游戏已经越来越成熟,未来趋势之选
网页、浏览器、H5页面炫酷的网页交互特效、3D动态画面,H5更是成为商家品牌造势,产品营销的首选
其他各种你想象不到的产品,已经出现在你的生活中,等待你去探索
时代的选择,“职”等你来
时代在发展,用户对互联网体验需求不断提高,各大企业对Web前端工程师愈发重视,前景“薪薪”向荣
专注品质教育,口碑做经营
黑马程序员每10名学员中,有7名来自老学员推荐,学员更认可的IT教育品牌
北京**科技股份有限公司
北京***科技公司
六险一金+补助
北京***科技股份有限公司
北京****金管理有限公司
北京***科技发展有限公司
五险一金+补助
北京***科技有限公司
北京***信息科技有限公司
五险一金+13薪资
北京***传媒有限公司
北京***科技有限公司
北京***科技股份有限公司
上海***信息科技有限公司
北京**有限公司
大连**软件有限公司
北京**迷科技有限公司
北京**公司
北京***服务外包有限公司
江苏*****科技有限公司
六险一金+补助
北京***科技有限公司
五险一金+13薪
北京**信息技术有限公司
北京*彦科技有限公司
五险一金+13薪
北京**科技有限公司
成都***北京分公司
五险一金+14薪资
北京***技股份有限公司
北京***信息技术有限公司
北京***技术有限公司
*为了避免就业信息给已就业学员带来不必要的麻烦,公布的就业信息会有部分信息暂时隐藏,相关数据来源于公司内部统计
六大课程优势,助你成为大前端时代的佼佼者
适应市场需求,打造高标准用户体验
课程循序渐进
技术小白可以快速上手
课程结构由浅入深,基础课程讲解充分,了解网页的结构组成、分析页面的布局、使用JavaScript和JQuery完成页面常见特效,最终帮助学员成为企业项目需求型Web前端工程师。
移动端开发技能
学完可独立开发和制作移动端网站
掌握HTML5、CSS3、Viewport、rem、Bootstrap主流适配方案、移动端布局、媒体查询,设备尺寸划分、主流响应式布局框架、touch事件、手势封装以及移动端常用框架学习。
开设服务器课程体系
掌握管理企业服务器后台的能力
熟悉后台编程语言PHP的基础语法,能够开发简单的动态页面和后台接口,从而能够快速适应与后台协作开发的工作场景。
模拟真实企业项目开发
在学习中获得职场工作经验
模拟企业中的真实开发,从交互稿、设计稿、接口文档,到项目打包工具,源代码管理工具,团队式开发,真实体会企业开发完整过程,直至项目上线。
引入三大流行框架
每一项学成都可以独当一面
Vue.js与React.js和Angular.js构成了当前前端最热门的三大开发框架,让学员由原来的面向过程编程转变到面向对象编程,模块化编程、组件化编程上来,使代码更优雅,更好维护。
实战名师教学
学到总监级开发思维
从业5-10年,统筹过一线项目的Web前端技术大牛亲身授课,授业解惑,传递开发思维、工作技巧,真正的做到化繁为简,学员技能稳步提升。
技术学到手,前途不限量
从技术小白,到IT牛人,你也许只差一步选择
精通炫酷的H5页面开发移动端布局更是不在话下
灵活运用各种常见框架和库玩转服务端数据交互
Web前端开发方向
服务端开发方向
项目定向开发方向
匠心课程,案例贯穿知识点,所学皆所用
引入时下前端主流三大框架,让学员从容应对各个框架开发工作
品优购综合实战项目
可掌握的核心能力:(1)了解常用浏览器和浏览器内核
(2)了解语义化的概念(3)能够掌握HTML、CSS使用技巧(4)能够掌握DIV+CSS布局模式 (5)能够掌握HTML5新特性与常用标签(6)能够完成动画效果
可解决的现实问题:与美工对接,完成网站静态页面的开发,为后期编写页面动态效果打基础
市场价值:了解网页的组成,能够实现静态页面编写,可以使用CSS3完成简单的页面动画
关键词:HTML5、CSS3、Flexbox、Photoshop、电商首页
前端基本功
JavaScript基础
JavaScript高级
可掌握的核心能力:(1)能够掌握JavaScript基本语法
(2)掌握DOM的各种操作(3)熟练使用面向对象思想进行DOM编程(4)掌握JavaScript的高级语法(5)掌握使用jQuery操作DOM(6)熟练使用和编写jQuery插件(7)独立完成电商网站的页面搭建(包括HTML结构、CSS样式、JavaScript特效组件)(8)掌握应对业务编程的能力
可解决的现实问题:学员具备JavaScript开发能力,能够完成常见页面效果开发,为就业班后期课程打基础
市场价值:能够独立完成常见网站的静态页面开发(包括HTML结构、CSS样式、JavaScript开发常见页面特效)
关键词:编程、JavaScript高级、面向对象、闭包、原型、jQuery、jQuery插件
PHP+AJAX+前端模块化
PHP服务端开发
前端模块化
阿里百秀项目
可掌握的核心能力:(1)能够建立客户端服务器交互模型,熟悉网络通信相关概念(2)熟悉PHP基础语法,能够开发简单的后台接口(3)能够使用PHP操作MySQL数据库(4)能够理解HTTP协议(5)熟悉原生AJAX请求流程与细节,并掌握常见跨域技巧(6)能够基于jQuery的AJAX相关API熟练开发常见的前端功能(7)能够独立开发基于后台接口的动态网站、AJAX数据交互的项目
可解决的现实问题:学员能够建立起客户端服务器交互模型,熟练使用AJAX实现前端功能点、能够进行前后端协作开发、能够独立开发基于后台接口的数据管理平台
市场价值:掌握前后端协作开发相关技术、能够快速融入实际的工作场景
关键词:服务端、HTTP协议、数据结构、会话技术、表单处理、模块化、CMS系统开发
移动Web开发课程要点
HTML5 + CSS3
移动端电商项目
可掌握的核心能力:(1)熟练使用HTML5&CSS3实现网页特炫效果(2)掌握常用移动端框架使用方法(3)掌握常用移动端调试方法(4)掌握常用移动端适配方法(5)熟练使用移动端touch事件及手势封装(6)掌握响应式布局的写法(7)掌握CSS预处理器less的使用(8)使用Git对比文件差异、还原、合并,能够解决远端仓库与本地仓库合并时的冲突(9)掌握移动端整站开发架构搭建、项目开发、性能优化等整站开发能力
可解决的现实问题:学员具备移动端Web开发能力,拥有根据设计图转化为对应的web,同时处理移动设备适配问题,能够掌握工作中多人开发的操作方式
市场价值:备移动Web开发能力,能够和后台交互,独立开发移动端的交互网站
关键词:HTML5 API、CSS3 动画、Bootstrap、移动端适配方案、源代码管理、Git、移动Web
移动Web开发
Vue.js基础
Vue.js实战项目
微信小程序
可掌握的核心能力:(1)了解项目开发的流程(2)能够熟练开发移动端和PC端的交互式网站(3)能够用目前热门JavaScript框架Vue.js来开发项目(4)掌握Express的使用(5)能够使用NodeJS开发后台接口,打通前后端(6)掌握源代码管理软件的使用(7)掌握小程序开发
可解决的现实问题:通过实战项目掌握Vue.js的开发电商网站核心业务开发使用微信小程序开发电商项目
市场价值:学完以后能够一个人胜任前端项目的独立开发,从项目框架搭建开始到业务功能的实现,以及后台api的调用均能胜任,使课程不仅仅只有教还有练,让学员能够快速上手企业项目开发
关键词:Node.js、ES6、NPM、工程化、Vue.js、Vue.js项目实战、Axios、Webpack、微信小程序
React.js实战项目
可掌握的核心能力:(1)了解常见的设计模式(2)掌握React框架的使用(3)能够利用webpack、gulp打包工具实现网站资源的打包
可解决的现实问题:能够使用React.js完成Web应用的开发
市场价值:能跟上最新技术的脚步,具有前后端开发能力的前端开发者。 能熟练使用各种前端工具,具有项目部署的能力,能与其他开发者合理沟通协作开发项目, 符合企业高端需求
关键词:React.js、JSX、组件化、React.js实战、Gulp、前端工具、项目部署
以市场需求为导向,特色实战项目
夯实工作技能的同时,让你的简历丰富三倍以上
项目介绍:项目属于整体电商项目的移动端实现,项目主要包含主页展示,商品分类展示,商品列表&商品详情展示,购物车,用户中心,用户注册&登录,订单展示等功能组成。是整个电商项目的一部分。
项目特色:系统不仅可以方便对数据进行管理,还加上了一些人性化的界面设计,使用户对博客的操作更为的方便
项目技术点:以 node.js + gulp 作为项目构建核心
集成第三方UI框架 MUI静态模版引擎 handlerbars动态模版引擎 artTemplate利用 axios 进行统一网络请求处理使用 javawebtoken 技术
项目介绍:品优购电商平台属于B2C电商,类似于京东、天猫等。该项目属于整体电商项目,项目主要包含网站首页、商品详情信息展示、购物车功能、注册新用户并发送验证邮件、登录、会员中心、购物车结算和支付、会员资料和收货地址维护、我的订单展示等。
项目特色:品优购电商平台贯穿整个课程,每个阶段结束会完成该平台的特定部分,最后组成一个完整的电商平台项目。
项目技术点:MVC、 Express、 Sequelize、
Handlebars 、 jQuery、jQuery插件
项目介绍:项目属于整体电商项目的后台管理系统,项目主要包含登录退出、用户和权限管理、上皮管理、订单管理、订单跟踪、数据报表模块。是整个电商项目的一部分。
项目特色:项目整体技术选型和开发模式贴合主流技术方案,开发流程贴合实际的工作模式,包括项目开发、优化、打包,部署上线完整流程。
项目技术点:完全采用前后端分离lodash
echarts百度地图api物流接口Vue技术栈(Vue2、Vue-router、webpack、axios、Element-UI2)
项目介绍:项目属于整体电商项目的小程序实现,项目主要包含微信登录,微信支付,主页展示,商品分类展示,商品列表&商品详情展示,购物车,订单结算,用户中心,订单展示等功能组成。是整个电商项目的一部分。
项目特色:项目整体技术选型和开发模式使用小程序主流技术方案,开发流程按实际工作模式标准进行,最后完成一个完整的电商平台项目,并发布上线,用户可直接搜索打开小程序完成登录,下单与支付。
项目技术点:完全前后端分离小程序MINA框架
小程序 Wepy组件化框架ES6,ES7语法组件化页面控件实现高复用性封装类似 axios 方法进行统一网络请求处理微信登录授权,微信支付小程序真实发布上线
项目介绍:阿里百秀项目属于CMS(内容管理系统),系统可以分享生活、科技、微信热门文章的自媒体。用户可以通过登录系统的后台发布文章,管理文章的分类等。
项目特色:系统不仅可以方便对数据进行管理,还加上了一些人性化的界面设计,使用户对博客的操作更为的方便。
项目技术点:PHP、 MySQL 、 AJAX、 文件上传模板引擎、 会话技术、 模块化
你的作品就是你的职业通行证
看一下师兄、师姐们学习了一个月的作品
示之美好,授以希望
实战讲师授课,认识一下真正的名企IT大牛
高级软件架构师,全栈开发,多年大型项目管理经验。对Web Components、Node.js、HTML5移动应用有深入研究。曾任职于....
资深移动互联软件开发工程师。从事移动互联开发6年,从事教学工作三年。熟悉Windows Phone, iOS等平台的应用级开发。参与项目:广东省大学生....
多年软件开发经验和教学经验,精通html,css,js,asp.net等编程语言和数据库系统。深入研究流行框架bootstrap,ligerui,easyui等....
前端开发工程师和软件开发工程师, 5年软件开发项目经验,精通网站前端设计和Html、JavaScript、CSS+DIV、Regular Expressions....
后端开发出身,曾在金和软件参与大型SOA项目开发;后入职国美集团旗下,负责前端开发工作。基础扎实,深入原理。热爱技术,喜欢读书,看过大量有....
师范大学计算机科学与技术专业毕业。多年互联网和移动互联网开发经验,参与开发项目:广东省移动物流信息管理系统、深圳移动配送一体化平台、深圳移动....
多年大中型项目开发经验,曾就职于某大型外企,在软件开发和培训方面积累了丰富的经验,参与电商平台、特许行业CRM系统等项目,涉足跨....
精通XHTML/HTML5,Css/Css3,Javascript,响应式等前端技术,擅长解决兼容性问题,深入掌握jQuery,Bootstrap,Less,Sass等技术框架...
6年互联网行业从业经验,曾任职国内某著名电信运营商工程师一职。精通html、css、js、jquery、HTML5、Ajax等各种前端技术....
从事前端开发工作多年,精通JavaScript、DOM、JQuery、Ajax等前端技术,对前端各个领域均有浓厚兴趣。在教学方面喜欢“较真”,对课程知识....
多年前端工作经验, 独立架构"兜世宝"项目pc端及移动端,多家企业前端规范制定者 。 并参与“星通北斗”,“办公24”,“淘美人”,“项目后台管理系统”等....
从事前端开发多年,有丰富的浏览器兼容和前端开发经验,精通html5+css3,精通移动web开发。曾担任某互联网公司前端主管。
Web前端工程师,具有多年Web开发经验,喜爱并热衷于前端开发,熟悉并掌握主流的前端开发技术,特别在移动开发方面积累了丰富的经验...
狂热型技术控,先后涉足网络安全,软件/网站开发,移动应用开发等领域。精通C\C++、OC、C#、JavaScript、Python等多项开发语言....
从事软件开发工作多年,涉及.Net、HTML5、Unity3d、IOS等平台,曾参与乌龟猜猜,敲打乐敲你妹等跨平台游戏项目的开发,之后投身教育....
技术深耕,规划学员的未来
视频课程,知识点深耕,讲授技术难点、技术延伸,为学员的长期发展提供保障
毕业后提供视频学习资料帮助学员继续深造
六大教学辅导系统,专心为你
多名辅导老师指导一名学员,保姆式教学服务,保障你的学习质量
每晚对学员当天知识的吸收程度、老师授课内容难易程度进行评分,根据学员反馈及吸收情况调整授课内容、课程节奏,最终让每位学员都跟上班级学习的整体节奏。
为每个就业班安排一名技术指导老师,不管是白天还是晚自习时间,实时解答学员问题,进一步巩固和加强课堂知识。
为辅助学员掌握所学知识,我们自主研发了6大学习系统,包括教学反馈系统、学习难易和吸收分析系统、学习测试系统、在线作业系统、学习任务手册、学员综合能力评定分析等。
末位辅导队列的学员,将会得到重点关心。技术辅导老师会在学员休息时间,针对学员的疑惑进行知识点梳理、答疑、辅导。以确保知识点掌握上没有一个学员掉队,真正落实不抛弃,不放弃任何一个学员。
从学员学习中的心态调整,到生活中的困难协助,从课上班级氛围塑造到课下多彩的班级活动,班主任360度暖心鼓励相伴。
小到五险一金的解释、面试礼仪的培训;大到500强企业面试实训及如何针对性地制定复习计划,帮助学员拿到Offer。
不一样的城市一样的黑马程序员
学习择业更方便
相同的课程大纲
黑马每年都会进行课程的升级和更新,一旦更新,全国所有校区课程将统一使用最新教学大纲。
相同的教学管理
黑马只有直营,不搞加盟!总部直接派讲师到分校区授课,采用相同的培训模式和课程。
相同的师资力量
分校区的师资在同一套教师培训体系下完成培训,保障师资质量。
相同的就业服务
全国各分校设置有与总部相同的就业服务部门,享受同样的就业指导服务。Bmob平台为您的移动应用提供了一个完整的后端解决方案,我们提供轻量级的SDK开发包,让开发者以最小的配置和最简单的方式使用Bmob平台提供的服务,进而完全消除开发者编写服务器代码以及维护服务器的操作。快速入门
建议您在阅读本开发文档之前,先阅读我们提供的 ,便于您后续的开发。SDK导入
Android Studio配置
鉴于目前Google官方推荐使用 Android Studio 进行Android项目开发,自 V3.4.2 开始,Bmob Android SDK 可以使用Gradle来进行包依赖管理,如果你使用Android Studio来进行基于BmobSDK的项目开发,请按照如下两个步骤进行:一、 在Project的build.gradle文件中添加Bmob的maven仓库地址,示例如下:(注意文字说明部分):
buildscript {
repositories {
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
allprojects {
repositories {
//Bmob的maven仓库地址,必须填写
maven { url &https://raw.github.com/bmob/bmob-android-sdk/master& }
二、 在app的build.gradle文件中添加compile依赖文件,示例如下:(注意文字说明部分):
apply plugin: 'com.android.application'
compileSdkVersion 22
buildToolsVersion '22.0.1'
//**兼容Android6.0系统所需,如果这句话报错,可在dependencies标签下使用compile 'cn.bmob.android:http-legacy:1.0'**
useLibrary 'org.apache.http.legacy'
defaultConfig {
applicationId &cn.bmob.android&
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName &1.0&
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
//以下SDK开发者请根据需要自行选择
//bmob-sdk:Bmob的android sdk包,包含了Bmob的数据存储、文件等服务,以下是最新的bmob-sdk:
//3.4.7-aar:具务必查看下面注释[1]
compile 'cn.bmob.android:bmob-sdk:3.4.7-aar'
//bmob-push:Bmob的推送包
compile 'cn.bmob.android:bmob-push:0.8'
//bmob-im:Bmob的即时通讯包,注意每个版本的im依赖特定版本的bmob-sdk,具体的依赖关系可查看下面注释[3]
compile 'cn.bmob.android:bmob-im:2.0.4'
compile 'cn.bmob.android:androidasync:2.1.6'
compile 'cn.bmob.android:bmob-sdk:3.4.6'
//注:别忘记导入3.4.6的相关依赖包[2]
//bmob-sms :Bmob单独为短信服务提供的包
compile 'cn.bmob.android:bmob-sms:1.0.1'
//如果你想应用能够兼容Android6.0,请添加此依赖(org.apache.http.legacy.jar)
compile 'cn.bmob.android:http-legacy:1.0'
注:[1]、为了降低开发者的使用成本,现提供3.4.7-aar,此aar包含libbmob.so、okhttp、okio及自动更新组件所需要的资源文件。开发者再也不需要配置libbmob.so,不需要添加okhttp、okio,也不需要复制自动更新组件的资源文件啦,只需要添加以下依赖即可。compile 'cn.bmob.android:bmob-sdk:3.4.7-aar'
注:由于PermissionManager权限管理类需要依赖support-v4:23.2.1的jar包,导致开发者认为SDK依赖文件较多,故分离出SDK。开发者如果需要兼容Android6.0系统,可以在下载的SDK的官方Demo的com.example.bmobexample.permission包下面查看该类源码。[2]、bmob-sdk:3.4.6依赖以下包:compile 'cn.bmob.android:bmob-sdk:3.4.6'
compile 'com.squareup.okhttp:okhttp:2.4.0'//CDN文件服务使用okhttp相关包进行文件的上传和下载(必填)
compile 'com.squareup.okio:okio:1.4.0'
如果需要兼容Android6.0系统,请添加以下两项:compile 'com.android.support:support-v4:23.2.1'
compile 'cn.bmob.android:http-legacy:1.0'
[3]、每个版本的im依赖特定版本的bmob-sdk:
bmob-im:1.1.8---&bmob-sdk:3.3.5
bmob-im:1.1.9---&bmob-sdk:3.4.3
bmob-im:2.0.1---&bmob-sdk:3.4.6-0304
bmob-im:2.0.2---&bmob-sdk:3.4.6-0304
bmob-im:2.0.3---&bmob-sdk:3.4.6
bmob-im:2.0.4---&bmob-sdk:3.4.6
其中bmob-sdk:3.4.6-0304是Bmob Android SDK的过渡版本,主要用于NewIM_v2.0.1及v2.0.2。
[4]、bmob-sms适用于只需要使用Bmob短信功能的开发者,而bmob-sdk内部包含了bmob-sms的短信功能,请不要重复添加。[5]、BmobSDK的官方仓库:,开发者可到此仓库查看最新发布的各版本SDK,我们会尽量与官网发布的SDK保持同步更新。Eclipse导入
找到对应SDK下载之后,在Eclipse工程的项目根目录中新建libs文件夹,将下载的jar包添加到此文件夹即可。注:1、若配置不成功,则需要额外增加以下步骤:右键工程根目录,选择Properties -& Java Build Path -& Libraries,然后点击Add External JARs... 选择指向该libs文件夹下的jar的路径,点击OK即可。2、BmobSDK_v3.4.7需要依赖okhttp3(3.2.0)、okio(1.7.0)及libbmob.so库,so库的导入方式是把下载后的libs文件夹中的各种so文件拷贝到项目中的libs文件夹下。3、BmobSDK_v3.4.6需要依赖okhttp(2.4.0)、okio(1.4.0),如果需要兼容Android6.0系统,则还需要添加support-v4(23.2.1)及org.apache.http.legacy依赖包。兼容Android6.0
自v3.4.6版本开始,Bmob提供了一些新的方法和工具类来帮助开发者为自己的应用兼容Android6.0系统。配置org.apache.http.legacy
Android6.0版本移除了对Appache的HTTP client的支持,因此,需要添加org.apache.http.legacy.jar包,请参照如下方式添加:
Eclipse 你需要在Eclipse工程的项目根目录中新建libs文件夹,将org.apache.http.legacy.jar包,添加到libs文件夹中
AndroidStudio 你需要在app的build.gradle文件添加配置信息useLibrary 'org.apache.http.legacy'声明编译时依赖 android { compileSdkVersion 23
buildToolsVersion &23.0.2&
useLibrary 'org.apache.http.legacy'
注:如果在build.gradle文件中useLibrary 'org.apache.http.legacy'这句话报错,可将该jar直接放到libs目录下即可。运行时权限管理
Android6.0中对特定的权限进行了动态授权的方式,需要在运行时用户手动授予,如果用户拒绝后再次申请还可以向用户弹框说明权限的作用,用户点击确认后再去申请。因此,我们提供了一个权限管理的工具类PermissionManager(cn.bmob.v3.helper),具体使用如下:注:在v3.4.6的BmobSDK内部集成PermissionManager类,自v3.4.7以后的SDK内部将不再提供该类,开发者可以在下载的配套官方Demo的com.example.bmobexample.permission包下面查看该类源码。1.构建PermissionManager对象PermissionM
helper = PermissionManager.with(MainActivity.this)
//添加权限请求码
.addRequestCode(MainActivity.REQUEST_CODE_CAMERA)
//设置权限,可以添加多个权限
.permissions(Manifest.permission.CAMERA)
//设置权限监听器
.setPermissionsListener(new PermissionListener() {
public void onGranted() {
//当权限被授予时调用
Toast.makeText(MainActivity.this, &Camera Permission granted&,Toast.LENGTH_LONG).show();
public void onDenied() {
//用户拒绝该权限时调用
Toast.makeText(MainActivity.this, &Camera Permission denied&,Toast.LENGTH_LONG).show();
public void onShowRationale(String[] permissions) {
//当用户拒绝某权限时并点击`不再提醒`的按钮时,下次应用再请求该权限时,需要给出合适的响应(比如,给个展示对话框来解释应用为什么需要该权限)
Snackbar.make(btn_camera, &需要相机权限去拍照&, Snackbar.LENGTH_INDEFINITE)
.setAction(&ok&, new View.OnClickListener() {
public void onClick(View v) {
//必须调用该`setIsPositive(true)`方法
helper.setIsPositive(true);
helper.request();
}).show();
//请求权限
.request();
with方法可以传入Activity或者Fragment;
addRequestCode方法传入请求码,用于区分各种不同的权限申请;
permissions方法传入的是你所要请求的权限,支持可变参数,可以批量申请权限;
PermissionListener接口回调的三个方法:
onGranted()会在权限申请通过后被调用;
onDenied()在权限申请被拒绝时被调用
onShowRationale()方法中你可以弹对话框向用户解释权限的作用,不过记得要调用setIsPositive(true)。
request方法用来请求权限申请
2.覆写onRequestPermissionsResult方法@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CODE_CAMERA:
helper.onPermissionResult(permissions, grantResults);
Notification变更
Android6.0中,Notification.setLatestEventInfo()方法被移除,替代的方案是用Notification.Builder来构建通知,对此SDK提供了NotificationCompat(cn.bmob.v3.helper)类来做版本兼容(与android.support.v4.app包下的NotificationCompat用法一样)。参照代码如下:NotificationManager notificationManager = (NotificationManager) mContext
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent pi = PendingIntent.getActivity(mContext, 0,
new Intent(MainActivity.this, MainActivity.class), 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext)
.setTicker(&更新啦&)
.setContentTitle(&标题&)
.setContentText(&内容&)
.setSmallIcon(R.drawable.ic_launcher);
Notification notification = builder.build();
notificationManager.notify(0, notification);
一个数据对象(APP中创建的BmobObject类的子类)对应于Bmob后台的一个数据表。数据对象
Bmob存储的数据是建立在BmobObject基础上的,所以任何要保存的数据对象必须继承自BmobObject类。BmobObject类本身包含objectId、createdAt、updatedAt、ACL四个默认的属性,objectId是数据的唯一标示,相当于数据库中表的主键,createdAt是数据的创建时间,updatedAt是数据的最后修改时间,ACL是数据的操作权限。如,你的游戏中使用GameScore表来记录玩家的比分信息,其中表的字段有:score(分数)、playerName(玩家名字)、isPay(是否付费玩家)、pic(玩家头像)属性,那么这个数据对象为如下定义://必须要继承自BmobObject类
public class GameScore extends BmobObject{
private String playerN
private Boolean isP
private BmobF
public String getPlayerName() {
return playerN
public void setPlayerName(String playerName) {
this.playerName = playerN
public Integer getScore() {
public void setScore(Integer score) {
this.score =
public Boolean getIsPay() {
return isP
public void setIsPay(Boolean isPay) {
this. isPay = isP
public BmobFile getPic() {
public void setPic(BmobFile pic) {
this.pic =
需要注意的是:
JavaBean不需要对objectId、createdAt、updatedAt、ACL四个属性进行定义。
不少开发者会没有注意到createdAt和updatedAt属性中的字母d,写成createAt和updateAt。
尽可能使用Integer、Boolean,而不是int、boolean,也就是选择包装类,而不是使用基本数据类型(这两者的区别大家可以看这篇文章:
为了提供更好的服务,BmobSDK中提供了BmobUser、BmobInstallation、BmobRole三个特殊的BmobObject对象来完成不同的功能,在这里我们统一称为特殊对象。
BmobUser对象主要是针对应用中的用户功能而提供的,它对应着web端的User表,使用BmobUser对象可以很方便的在应用中实现用户的注册、登录、邮箱验证等功能,具体的使用方法可查看文档的部分。
BmobInstallation对象主要用于应用的安装设备管理中,它对应着web端的Installation表,任何安装了你应用的设备都会在此表中产生一条数据标示该设备。结合Bmob提供的推送功能,还可以实现将自定义的消息推送给不同的设备终端,具体的使用方法可查看文档的部分。
BmobRole对象主要用于角色管理,对应用于Web端的Role表,具体的使用方法可查看文档的部分。
目前为止,Bmob支持的数据类型:String、Integer、Float、Short、Byte、Double、Character、Boolean、Object、Array。同时也支持BmobObject、BmobDate、BmobGeoPoint、BmobFile特有的数据类型。以下为Web端类型与SDK端支持的JAVA类型对应表:
支持的JAVA类型
Integer、Float、Short、Byte、Double、Character
对应数据库的Number类型
Bmob特有类型,用来标识文件类型
BmobGeoPoint
Bmob特有类型,用来标识地理位置
Bmob特有类型,用来标识日期类型
Bmob特有类型,用来标识指针类型
BmobRelation
Bmob特有类型,用来标识数据关联
注:1、不能使用int、float、short byte、double、character等基本数据类型。类名和表名的关系
Bmob官方推荐类名和表名完全一致的映射使用方式, 即如,上面的GameScore类,它在后台对应的表名也是GameScore(区分大小写)。
如果你希望表名和类名并不相同,如表名为T_a_b,而类名还是GameScore,那么你可以使用BmobObject提供的setTableName(&表名&)的方法,示例代码如下://这时候实际操作的表是T_a_b
public class GameScore extends BmobObject{
private String playerN
private Boolean isP
private BmobF
public GameScore() {
this.setTableName(&T_a_b&);
public String getPlayerName() {
return playerN
//其他方法,见上面的代码
当然了,除了在构造函数中直接调用setTableName方法之外,你还可以在GameScore的实例中动态调用setTableName方法。
查询自定义表名的数据
如果您使用了setTableName方法来自定义表名,那么在对该表进行数据查询的时候必须使用以下方法。需要注意的是查询的结果是JSONArray,需要自行解析JSONArray中的数据。/**
* 查询数据
public void queryData(){
BmobQuery query = new BmobQuery(&T_a_b&);
query.findObjects(this, new FindCallback() {
public void onSuccess(JSONArray arg0) {
//注意:查询的结果是JSONArray,需要自行解析
showToast(&查询成功:&+arg0.length());
public void onFailure(int arg0, String arg1) {
showToast(&查询失败:&+arg1);
自定义表名情况下的更新、删除数据和普通的更新、删除数据方式一样,没有变化。为方便大家了解学习,我们提供了一个关于自定义表名情况下增删改查数据的Demo,下载地址是:。添加数据
添加数据使用BmobObject对象的save方法,就可以将当前对象的内容保存到Bmob服务端。例如,你现在要保存一条游戏分数的记录,代码如下:GameScore gameScore = new GameScore();
//注意:不能调用gameScore.setObjectId(&&)方法
gameScore.setPlayerName(&比目&);
gameScore.setScore(89);
gameScore.setIsPay(false);
gameScore.save(mContext, new SaveListener() {
public void onSuccess() {
toast(&添加数据成功,返回objectId为:&+gameScore.getObjectId() + ”,数据在服务端的创建时间为:“ + gameScore.getCreatedAt());
public void onFailure(int code, String arg0) {
// 添加失败
运行以上代码,如果添加成功,你可以在Bmob提供的后台的数据浏览中看到类似这样的结果:objectId: &0c6db13c&, score: 89, playerName: &比目&, isPay: false,createdAt:& 10:32:54&, updatedAt:& 10:32:54&
这里需要注意的是:
如果服务器端不存在GameScore表,那么系统将自动建表,并插入数据。
如果服务器端已经存在GameScore表,和相应的score、playerName、isPay字段,那么你此时添加的数据和数据类型也应该和服务器端的表结构一致,否则会保存数据失败。
每个BmobObject对象都有几个默认的键(数据列)是不需要开发者指定的,objectId是每个保存成功数据的唯一标识符。createdAt和updatedAt代表每个对象(每条数据)在服务器上创建和最后修改的时间。这些键(数据列)的创建和数据内容是由服务器端自主来完成的。因此,使用save和insert方法时,不需要调用setObjectId方法,否则会出现提示:“It is a reserved field: objectId(105)”--表明objectId为系统保留字段,不允许修改。。
更新一个对象也是非常简单。例如:将GameScore表中objectId为0c6db13c的游戏分数修改为77.GameScore gameScore = new GameScore();
gameScore.setScore(77);
gameScore.update(this, &0c6db13c&, new UpdateListener() {
public void onSuccess() {
// TODO Auto-generated method stub
Log.i(&bmob&,&更新成功:&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
Log.i(&bmob&,&更新失败:&+msg);
自V3.4.4版本开始,SDK提供了另一种方法来更新数据,通过调用Bmobobject类中的setValue(key,value)方法,只需要传入key及想要更新的值即可举例,说明如下:public class Person extends BmobObject {
private BmobU
//BmobObject类型
private BankC
//Object类型
//Integer类型
private B //Boolean类型
getter、setter方法
其中BankCard类结构如下:
public class BankCard{
private String cardN
private String bankN
public BankCard(String bankName, String cardNumber){
this.bankName = bankN
this.cardNumber = cardN
getter、setter方法
Person p2=new Person();
//更新BmobObject的值
p2.setValue(&user&, BmobUser.getCurrentUser(this, MyUser.class));
//更新Object对象
p2.setValue(&bankCard&,new BankCard(&农行&, &农行账号&));
//更新Object对象的值
//p2.setValue(&bankCard.bankName&,&建行&);
//更新Integer类型
//p2.setValue(&age&,11);
//更新Boolean类型
//p2.setValue(&gender&, true);
p2.update(this, objectId, new UpdateListener() {
public void onSuccess() {
// TODO Auto-generated method stub
Log.i(&bmob&,&更新成功:&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
Log.i(&bmob&,&更新失败:&+msg);
注意:修改数据只能通过objectId来修改,目前不提供查询条件方式的修改方法。原子计数器
很多应用可能会有计数器功能的需求,比如文章点赞的功能,如果大量用户并发操作,用普通的更新方法操作的话,会存在数据不一致的情况。为此,Bmob提供了原子计数器来保证原子性的修改某一数值字段的值。注意:原子计数器只能对应用于Web后台的Number类型的字段,即JavaBeans数据对象中的Integer对象类型(不要用int类型)。gameScore.increment(&score&); // 分数递增1
gameScore.update(this, updateListener);
您还可以通过increment(key, amount)方法来递增或递减任意幅度的数字gameScore.increment(&score&, 5); // 分数递增5
//gameScore.increment(&score&, -5); // 分数递减5
gameScore.update(this, updateListener);
从服务器删除对象。例如:将GameScore表中objectId为dd8e6aff28的数据删除。GameScore gameScore = new GameScore();
gameScore.setObjectId(&dd8e6aff28&);
gameScore.delete(this, new DeleteListener() {
public void onSuccess() {
// TODO Auto-generated method stub
Log.i(&bmob&,&删除成功&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
Log.i(&bmob&,&删除失败:&+msg);
注意:删除数据只能通过objectId来删除,目前不提供查询条件方式的删除方法。删除字段的值
你可以在一个对象中删除一个字段的值,通过remove操作:GameScore gameScore = new GameScore();
gameScore.setObjectId(&dd8e6aff28&);
gameScore.remove(&score&);
// 删除GameScore对象中的score字段
gameScore.update(this, new UpdateListener() {
public void onSuccess() {
// TODO Auto-generated method stub
Log.i(&bmob&,&删除GameScore对象中的score字段成功&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
Log.i(&bmob&,&删除GameScore对象中的score字段失败:&+msg);
批量数据操作
在BmobObject对象中提供了三种用于批量操作的方法,分别是insertBatch、updateBatch、deleteBatch,批量添加、更新、删除。
insertBatch的使用方式如下:
List&BmobObject& persons = new ArrayList&BmobObject&();
for (int i = 0; i & 3; i++) {
Person person = new Person();
person.setName(&张三 &+i);
person.setAddress(&上海朝阳路&+i+&号&);
person.setGpsAdd(new BmobGeoPoint(112..52065));
person.setUploadTime(new BmobDate(new Date()));
List&String& hobbys = new ArrayList&String&();
hobbys.add(&阅读&);
hobbys.add(&篮球&);
hobbys.add(&唱歌&);
person.setHobby(hobbys);
person.setBankCard(new BankCard(&中国银行&, &545097&+i));
persons.add(person);
new BmobObject().insertBatch(this, persons, new SaveListener() {
public void onSuccess() {
// TODO Auto-generated method stub
toast(&批量添加成功&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
toast(&批量添加失败:&+msg);
updateBatch的使用方式如下:
List&BmobObject& persons = new ArrayList&BmobObject&();
Person p1 = new Person();
p1.setObjectId(&e51d651c22&);
p1.setAge(25);
Person p2 = new Person();
p2.setObjectId(&3f70a922c4&);
p2.setAge(26);
p2.setGender(false);
Person p3 = new Person();
p3.setObjectId(&08fdd55765&);
p3.setAge(27);
persons.add(p1);
persons.add(p2);
persons.add(p3);
new BmobObject().updateBatch(this, persons, new UpdateListener() {
public void onSuccess() {
// TODO Auto-generated method stub
toast(&批量更新成功&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
toast(&批量更新失败:&+msg);
deleteBatch的使用方式如下:
List&BmobObject& persons = new ArrayList&BmobObject&();
Person p1 = new Person();
p1.setObjectId(&38ea274d0c&);
Person p2 = new Person();
p2.setObjectId(&01e29165bc&);
Person p3 = new Person();
p3.setObjectId(&d&);
persons.add(p1);
persons.add(p2);
persons.add(p3);
new BmobObject().deleteBatch(this, persons, new DeleteListener() {
public void onSuccess() {
// TODO Auto-generated method stub
toast(&批量删除成功&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
toast(&批量删除失败:&+msg);
任何一种批量操作每次只支持最大50条记录的操作。
批量操作不支持对User表的操作。
数据的查询可能是每个应用都会频繁使用到的,BmobSDK中提供了BmobQuery类,它提供了多样的方法来实现不同条件的查询,同时它的使用也是非常的简单和方便的。查询单条数据
当我们知道某条数据的objectId时,就可以根据objectId直接获取单条数据对象。例如:查询objectId为a203eba875的人员信息。BmobQuery&GameScore& query = new BmobQuery&GameScore&();
query.getObject(this, &a203eba875&, new GetListener&GameScore&() {
public void onSuccess(GameScore object) {
// TODO Auto-generated method stub
toast(&查询成功:&);
//获得playerName的信息
object.getPlayerName();
//获得数据的objectId信息
object.getObjectId();
//获得createdAt数据创建时间(注意是:createdAt,不是createAt)
object.getCreatedAt();
public void onFailure(int code, String arg0) {
// TODO Auto-generated method stub
toast(&查询失败:&+arg0);
查询多条数据
查询某个数据表中的所有数据是非常简单的查询操作,例如:查询GameScore表中playerName为“比目”的50条数据记录。BmobQuery&GameScore& query = new BmobQuery&GameScore&();
//查询playerName叫“比目”的数据
query.addWhereEqualTo(&playerName&, &比目&);
//返回50条数据,如果不加上这条语句,默认返回10条数据
query.setLimit(50);
//执行查询方法
query.findObjects(this, new FindListener&GameScore&() {
public void onSuccess(List&GameScore& object) {
// TODO Auto-generated method stub
toast(&查询成功:共&+object.size()+&条数据。&);
for (GameScore gameScore : object) {
//获得playerName的信息
gameScore.getPlayerName();
//获得数据的objectId信息
gameScore.getObjectId();
//获得createdAt数据创建时间(注意是:createdAt,不是createAt)
gameScore.getCreatedAt();
public void onError(int code, String msg) {
// TODO Auto-generated method stub
toast(&查询失败:&+msg);
查询的结果不需要进行任何处理,BmobSDK已经为你封装成相应的JavaBean集合了,你直接使用即可。注:通过setLimit方法设置返回的记录数量。更多细节可一节。查询条件
在查询的使用过程中,基于不同条件的查询是非常常见的,BmobQuery同样也支持不同条件的查询。比较查询
如果要查询特定键的特定值,可以使用addWhereEqualTo方法,如果要过滤掉特定键的值可以使用addWhereNotEqualTo方法。比如需要查询playerName不等于“Barbie”的数据时可以这样写:query.addWhereNotEqualTo(&playerName&, &Barbie&);
当然,你可以在你的查询操作中添加多个约束条件,来查询符合要求的数据。query.addWhereNotEqualTo(&playerName&, &Barbie&);
//名字不等于Barbie
query.addWhereGreaterThan(&score&, 60);
//条件:分数大于60岁
各种不同条件的比较查询:// 分数 & 50
query.addWhereLessThan(&score&, 50);
//分数 &= 50
query.addWhereLessThanOrEqualTo(&score&, 50);
//分数 & 50
query.addWhereGreaterThan(&score&, 50);
//分数 &= 50
query.addWhereGreaterThanOrEqualTo(&score&, 50);
如果你想查询匹配几个不同值的数据,如:要查询“Barbie”,“Joe”,“Julia”三个人的成绩时,你可以使用addWhereContainedIn方法来实现。String[] names = {&Barbie&, &Joe&, &Julia&};
query.addWhereContainedIn(&playerName&, Arrays.asList(names));
相反,如果你想查询排除“Barbie”,“Joe”,“Julia”这三个人的其他同学的信息,你可以使用addWhereNotContainedIn方法来实现。String[] names = {&Barbie&, &Joe&, &Julia&};
query.addWhereNotContainedIn(&playerName&, Arrays.asList(names));
时间查询比较特殊,我们需要结合BmobDate这个类来查询某个指定日期时间前后的数据,这里也给出示例供大家参考:比如:如果想查询指定日期之前的数据,则可以使用addWhereLessThan或者addWhereLessThanOrEqualTo(包含当天)来查询。如果想查询指定日期之后的数据,则可以使用addWhereGreaterThan或addWhereGreaterThanOrEqualTo(包含当天)来查询。如果想查询指定时间当天的数据,则需要使用复合与查询来查询,例如,想查询号当天的Person数据,示例代码如下:BmobQuery&Person& query = new BmobQuery&Person&();
List&BmobQuery&Person&& and = new ArrayList&BmobQuery&Person&&();
//大于00:00:00
BmobQuery&Person& q1 = new BmobQuery&Person&();
String start = & 00:00:00&;
SimpleDateFormat sdf = new SimpleDateFormat(&yyyy-MM-dd HH:mm:ss&);
date = sdf.parse(start);
} catch (ParseException e) {
e.printStackTrace();
q1.addWhereGreaterThanOrEqualTo(&createdAt&,new BmobDate(date));
and.add(q1);
//小于23:59:59
BmobQuery&Person& q2 = new BmobQuery&Person&();
String end = & 23:59:59&;
SimpleDateFormat sdf1 = new SimpleDateFormat(&yyyy-MM-dd HH:mm:ss&);
Date date1
date1 = sdf1.parse(end);
} catch (ParseException e) {
e.printStackTrace();
q2.addWhereLessThanOrEqualTo(&createdAt&,new BmobDate(date1));
and.add(q2);
//添加复合与查询
query.and(and);
注:由于createdAt、updatedAt是服务器自动生成的时间,在服务器保存的是精确到微秒值的时间,所以,基于时间类型的比较的值要加1秒。数组查询
对于字段类型为数组的情况,需要查找字段中的数组值包含有xxx的对象,可以使用addWhereContainsAll方法:比如我想查询有阅读和唱歌爱好的人,可以这样:BmobQuery&Person& query = new BmobQuery&Person&();
String [] hobby = {&阅读&,&唱歌&};
query.addWhereContainsAll(&hobby&, Arrays.asList(hobby));
query.findObjects(this, new FindListener&Person&() {
public void onSuccess(List&Person& object) {
// TODO Auto-generated method stub
toast(&查询成功:共& + object.size() + &条数据。&);
public void onError(int code, String msg) {
// TODO Auto-generated method stub
toast(&查询失败:& + code);
对字符串值的模糊查询 比如 查询包含字符串的值,有几种方法。你可以使用任何正确的正则表达式来检索相匹配的值,使用addWhereMatches方法:query.addWhereMatches((&username&, &^[A-Z]\\d&);
还可以使用如下方法://查询username字段的值含有“sm”的数据
query.addWhereContains(&username&, &sm&);
//查询username字段的值是以“sm“字开头的数据
query.whereStartsWith(&username&, &sm&);
// 查询username字段的值是以“ile“字结尾的数据
query.whereEndsWith(&username&, &ile&);
列值是否存在
如果你想查询某个列的值存在,那么可以使用addWhereExists方法://查询username有值的数据
query.addWhereExists(&username&);
如果想查询某个列的值不存在,则可以用addWhereDoesNotExists方法//查询username字段没有值的数据
query.addWhereDoesNotExists(&username&);
有时,在数据比较多的情况下,你希望查询出的符合要求的所有数据能按照多少条为一页来显示,这时可以使用setLimit方法来限制查询结果的数据条数来进行分页。默认情况下,Limit的值为100,最大有效设置值1000(设置的数值超过1000还是视为1000)。query.setLimit(10); // 限制最多10条数据结果作为一页
在数据较多的情况下,在setLimit的基础上分页显示数据是比较合理的解决办法。setSKip方法可以做到跳过查询的前多少条数据来实现分页查询的功能。默认情况下Skip的值为10。query.setSkip(10); // 忽略前10条数据(即第一页数据结果)
大家也可以直接下载我们提供的Demo源码(),查看如何使用分页查询,结合ListView开发下拉刷新查看更多内容的应用。排序
对应数据的排序,如数字或字符串,你可以使用升序或降序的方式来控制查询数据的结果顺序:// 根据score字段升序显示数据
query.order(&score&);
// 根据score字段降序显示数据
query.order(&-score&);
// 多个排序字段可以用(,)号分隔
query.order(&-score,createdAt&);
说明:多个字段排序时,先按第一个字段进行排序,再按第二个字段进行排序,依次进行。复合查询
与查询(and)
有些查询需要使用到复合“与”的查询条件,例如:你想查询出Person表中年龄在6-29岁之间且姓名以&y&或者&e&结尾的人,那么,可以采用and查询,示例代码如下://查询年龄6-29岁之间的人,每一个查询条件都需要New一个BmobQuery对象
//--and条件1
BmobQuery&Person& eq1 = new BmobQuery&Person&();
eq1.addWhereLessThanOrEqualTo(&age&, 29);//年龄&=29
//--and条件2
BmobQuery&Person& eq2 = new BmobQuery&Person&();
eq2.addWhereGreaterThanOrEqualTo(&age&, 6);//年龄&=6
//查询姓名以&y&或者&e&结尾的人--这个需要使用到复合或查询(or)
//--and条件3
BmobQuery&Person& eq3 = new BmobQuery&Person&();
eq3.addWhereEndsWith(&name&, &y&);
BmobQuery&Person& eq4 = new BmobQuery&Person&();
eq4.addWhereEndsWith(&name&, &e&);
List&BmobQuery&Person&& queries = new ArrayList&BmobQuery&Person&&();
queries.add(eq3);
queries.add(eq4);
BmobQuery&Person& mainQuery = new BmobQuery&Person&();
BmobQuery&Person& or = mainQuery.or(queries);
//最后组装完整的and条件
List&BmobQuery&Person&& andQuerys = new ArrayList&BmobQuery&Person&&();
andQuerys.add(eq1);
andQuerys.add(eq2);
andQuerys.add(or);
//查询符合整个and条件的人
BmobQuery&Person& query = new BmobQuery&Person&();
query.and(andQuerys);
query.findObjects(this, new FindListener&Person&() {
public void onSuccess(List&Person& object) {
// TODO Auto-generated method stub
toast(&查询年龄6-29岁之间,姓名以'y'或者'e'结尾的人个数:&+object.size());
public void onError(int code, String msg) {
// TODO Auto-generated method stub
toast(&复合与查询失败:&+code+&,msg:&+msg);
或查询(or)
有些情况,在查询的时候需要使用到复合的“或”的查询条件。例如,你想查出 Person 表中 age 等于 29 或者 age 等于 6 的人,可以这样:BmobQuery&Person& eq1 = new BmobQuery&Person&();
eq1.addWhereEqualTo(&age&, 29);
BmobQuery&Person& eq2 = new BmobQuery&Person&();
eq2.addWhereEqualTo(&age&, 6);
List&BmobQuery&Person&& queries = new ArrayList&BmobQuery&Person&&();
queries.add(eq1);
queries.add(eq2);
BmobQuery&Person& mainQuery = new BmobQuery&Person&();
mainQuery.or(queries);
mainQuery.findObjects(this, new FindListener&Person&() {
public void onSuccess(List&Person& object) {
// TODO Auto-generated method stub
public void onError(int code, String msg) {
// TODO Auto-generated method stub
你还可以在此基础上添加更多的约束条件到新创建的 BmobQuery 对象上,表示一个 and 查询操作。查询结果计数
如果你只是想统计满足查询对象的数量,你并不需要获取所有匹配对象的具体数据信息,可以直接使用count替代findObjects。例如,查询一个特定玩家玩的游戏场数:BmobQuery&GameSauce& query = new BmobQuery&GameSauce&();
query.addWhereEqualTo(&playerName&, &Barbie&);
query.count(this, GameSauce.class, new CountListener() {
public void onSuccess(int count) {
// TODO Auto-generated method stub
toast(&Barbie has played& + count + &games&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
toast(&count failure:&+msg);
查询指定列
有的时候,一张表的数据列比较多,而我们只想查询返回某些列的数据时,我们可以使用BmobQuery对象提供的addQueryKeys方法来实现。如下所示://只返回Person表的objectId这列的值
BmobQuery&Person& bmobQuery = new BmobQuery&Person&();
bmobQuery.addQueryKeys(&objectId&);
bmobQuery.findObjects(this, new FindListener&Person&() {
public void onSuccess(List&Person& object) {
// TODO Auto-generated method stub
toast(&查询成功:共& + object.size() + &条数据。&);
//注意:这里的Person对象中只有指定列的数据。
public void onError(int code, String msg) {
// TODO Auto-generated method stub
toast(&查询失败:& + msg);
指定多列时用,号分隔每列,如:addQueryKeys(&objectId,name,age&);统计查询
从BmobSDKV3.3.6开始,Bmob为开发者提供了以下关键字或其组合的统计查询操作,分别用于计算总和、平均值、最大值、最小值,同时支持分组和过滤条件。 方法名
String[] sumKeys(多个列名)
求某列或多列的和 averageString[] aveKeys(多个列名)求某列或多列的平均值maxString[] maxKeys(多个列名)求某列或多列的最大值minString[] minKeys(多个列名)求某列或多列的最小值groupbyString[] groupKeys(多个列名)分组havingHashMap map(键(String)值(Object)对的形式)分组的过滤条件setHasGroupCountboolean hasCount是否返回每个分组的记录数
注:1、为避免和用户创建的列名称冲突,Bmob约定以上查询返回的字段采用_(关键字)+首字母大写的列名 的格式:例:计算玩家得分表(GameScore)中列名为score的总和,那么返回的结果集会有一个列名为_sumScore,若设置了setHasGroupCount(true),则结果集中会返回_count。2、以上方法可自由组合且与之前的查询语句中的where, order, limit, skip等组合一起使用。3、因为返回格式不固定,故使用findStatistics来专门处理统计查询。统计查询方法
例如,如果要计算所有玩家的得分总和,那么代码如下:BmobQuery&GameScore& query = new BmobQuery&GameScore&();
query.sum(new String[] { &playScore& });
query.findStatistics(this, GameScore.class,new FindStatisticsListener() {
public void onSuccess(Object object) {
JSONArray ary = (JSONArray)
if(ary!=null){//
JSONObject obj = ary.getJSONObject(0);
int sum = obj.getInt(&_sumPlayScore&);//_(关键字)+首字母大写的列名
showToast(&游戏总得分:& + sum);
} catch (JSONException e) {
showToast(&查询成功,无数据&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
showToast(&查询出错:code =& + &,msg = & + msg);
注:sum方法的参数只能查询Number类型的列名(对应Java的Integer类型),即要计算哪个列的值的总和。查询平均值、最大、最小和上面的求和类似,在这里也一并提示下:BmobQuery&GameScore& query = new BmobQuery&GameScore&();
//query.average(new String[]{&playScore&});//查询某列的平均值
query.min(new String[]{&playScore&});//查询最小值
//query.max(new String[]{&playScore&});//查询最大值
query.groupby(new String[]{&createdAt&});
query.findStatistics(this, GameScore.class, new FindStatisticsListener() {
public void onSuccess(Object result) {
// TODO Auto-generated method stub
JSONArray ary = (JSONArray)
if (ary!=null) {
JSONObject obj = ary.getJSONObject(0);
int playscore = obj.getInt(&_avgPlayScore&);
int minscore = obj.getInt(&_minPlayScore&);
int maxscore = obj.getInt(&_maxPlayScore&);
String createDate = obj.getString(&createdAt&);
showToast(&minscore = & + minscore+ &,统计时间 = &+ createDate);
} catch (JSONException e) {
e.printStackTrace();
showToast(&查询成功,无数据&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
showToast(&查询出错:code =& + &,msg = & + msg);
如果你需要对查询结果进行分组,可使用groupby方法,支持根据多个列名进行分组。//我们以创建时间按天和游戏分别统计玩家的得分,并按时间降序
BmobQuery&GameScore& query = new BmobQuery&GameScore&();
query.sum(new String[] { &playScore&, &signScore& });//求多个列的总和
query.groupby(new String[] { &createdAt&, &game& });//按照时间和游戏名进行分组
query.order(&-createdAt&);//降序排列
query.findStatistics(this, GameScore.class,new FindStatisticsListener() {
public void onSuccess(Object object) {
// TODO Auto-generated method stub
JSONArray ary = (JSONArray)
if(ary!=null){
int length = ary.length();
for (int i = 0; i & i++) {
JSONObject obj = ary.getJSONObject(i);
int playscore = obj.getInt(&_sumPlayScore&);
int signscore = obj.getInt(&_sumSignScore&);
String createDate = obj.getString(&createdAt&);
String game = obj.getString(&game&);
showToast(&游戏总得分:& + playscore + &,签到得分:&+ signscore + &,时间 = & + createDate+&,game = &+game);
} catch (JSONException e) {
e.printStackTrace();
showToast(&查询成功,无数据&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
showToast(&查询出错:code =& + &,msg = & + msg);
有时候,我们需要知道分组统计时每个分组有多少条记录,可使用setHasGroupCount(true),如下:// 查询创建时间按天统计所有玩家的得分和每一天有多少条玩家的得分记录,并按时间降序:
BmobQuery&GameScore& query = new BmobQuery&GameScore&();
query.sum(new String[] { &playScore& });
// 统计总得分
query.groupby(new String[] { &createdAt& });// 按照时间分组
query.order(&-createdAt&);
// 降序排列
query.setHasGroupCount(true);
// 统计每一天有多少个玩家的得分记录,默认不返回分组个数
query.findStatistics(this, GameScore.class,new FindStatisticsListener() {
public void onSuccess(Object object) {
// TODO Auto-generated method stub
JSONArray ary = (JSONArray)
if (ary!=null) {
int length = ary.length();
for (int i = 0; i & i++) {
JSONObject obj = ary.getJSONObject(i);
int playscore = obj.getInt(&_sumPlayScore&);
String createDate = obj.getString(&createdAt&);
int count = obj.getInt(&_count&);//setHasGroupCount设置为true时,返回的结果中含有&_count&字段
showToast(&游戏总得分:& + playscore + &,总共统计了&
+ count + &条记录,统计时间 = &+ createDate);
} catch (JSONException e) {
e.printStackTrace();
showToast(&查询成功,无数据&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
showToast(&查询出错:code =& + &,msg = & + msg);
添加过滤条件
如果需要对分组计算后的结果再进行过滤,可使用having来继续过滤部分结果。//我们按游戏名统计所有玩家的总得分,并只返回总得分大于100的记录,并按时间降序
BmobQuery&GameScore& query = new BmobQuery&GameScore&();
query.sum(new String[] {&playScore&});//计算总得分数
query.groupby(new String[] {&game&});//分组条件:按游戏名进行分组
query.order(&-createdAt&);// 降序排列
HashMap&String, Object& map = new HashMap&String, Object&();
JSONObject js = new JSONObject();
js.put(&$gt&, 100);
} catch (JSONException e1) {
map.put(&_sumPlayScore&, js);//过滤条件:总得分数大于100
query.having(map);
query.setLimit(100);
query.findStatistics(this, GameScore.class,new FindStatisticsListener() {
public void onSuccess(Object object) {
// TODO Auto-generated method stub
JSONArray ary = (JSONArray)
if(ary!=null){
int length = ary.length();
for (int i = 0; i & i++) {
JSONObject obj = ary.getJSONObject(i);
int playscore = obj.getInt(&_sumPlayScore&);//过滤条件的key是什么,返回的数据中就有什么
String game = obj.getString(&game&);
//返回的数据中同样包含groupby里面的列名
showToast(&游戏得分:& + playscore + &,游戏名 = &+ game);
} catch (JSONException e) {
e.printStackTrace();
showToast(&查询成功,无数据&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
showToast(&查询出错:code =& + &,msg = & + msg);
缓存查询通常是将查询结果缓存在磁盘上。当用户的设备处于离线状态时,就可以从缓存中获取数据来显示。或者在应用界面刚刚启动,从网络获取数据还未得到结果时,先使用缓存数据来显示。这样可以让用户不必在按下某个按钮后进行枯燥的等待。默认的查询操作是没有启用缓存的,开发者可以使用setCachePolicy方法来启用缓存功能。例如:优先从缓存获取数据,如果获取失败再从网络获取数据。bmobQuery.setCachePolicy(CachePolicy.CACHE_ELSE_NETWORK);
// 先从缓存获取数据,如果没有,再从网络获取。
bmobQuery.findObjects(this, new FindListener&Person&() {
public void onSuccess(List&Person& object) {
// TODO Auto-generated method stub
toast(&查询成功:共&+object.size()+&条数据。&);
public void onError(int code, String msg) {
// TODO Auto-generated method stub
toast(&查询失败:&+msg);
Bmob SDK提供了几种不同的缓存策略,以适应不同应用场景的需求:
IGNORE_CACHE
:只从网络获取数据,且不会将数据缓存在本地,这是默认的缓存策略。
CACHE_ONLY
:只从缓存读取数据,如果缓存没有数据会导致一个BmobException,可以忽略不处理这个BmobException.
NETWORK_ONLY
:只从网络获取数据,同时会在本地缓存数据。
NETWORK_ELSE_CACHE:先从网络读取数据,如果没有,再从缓存中获取。
CACHE_ELSE_NETWORK:先从缓存读取数据,如果没有,再从网络获取。
CACHE_THEN_NETWORK:先从缓存取数据,无论结果如何都会再次从网络获取数据。也就是说会产生2次调用。
建议的做法:第一次进入应用的时候,设置其查询的缓存策略为CACHE_ELSE_NETWORK,当用户执行上拉或者下拉刷新操作时,设置查询的缓存策略为NETWORK_ELSE_CACHE。缓存方法
如果需要操作缓存内容,可以使用BmobQuery提供的方法做如下操作:
检查是否存在当前查询条件的缓存数据
boolean isInCache = query.hasCachedResult(context,Class&?& clazz);
注:缓存和查询条件有关,此方法必须放在所有的查询条件(where、limit、order、skip、include等)都设置完之后,否则会得不到缓存数据。
清除当前查询的缓存数据
query.clearCachedResult(context,Class&?& clazz);
清除所有查询结果的缓存数据
BmobQuery.clearAllCachedResults(this);
设置缓存的最长时间(以毫秒为单位)
query.setMaxCacheAge(TimeUnit.DAYS.toMillis(1));//此表示缓存一天
示例如下:BmobQuery&Person& query
= new BmobQuery&Person&();
query.addWhereEqualTo(&age&, 25);
query.setLimit(10);
query.order(&createdAt&);
//判断是否有缓存,该方法必须放在查询条件(如果有的话)都设置完之后再来调用才有效,就像这里一样。
boolean isCache = query.hasCachedResult(context,Person.class);
if(isCache){--此为举个例子,并不一定按这种方式来设置缓存策略
query.setCachePolicy(CachePolicy.CACHE_ELSE_NETWORK);
// 如果有缓存的话,则设置策略为CACHE_ELSE_NETWORK
query.setCachePolicy(CachePolicy.NETWORK_ELSE_CACHE);
// 如果没有缓存的话,则设置策略为NETWORK_ELSE_CACHE
query.findObjects(this, new FindListener&Person&() {
public void onSuccess(List&Person& object) {
// TODO Auto-generated method stub
Log.i(&smile&,&查询个数:&+object.size())
public void onError(int code, String msg) {
// TODO Auto-generated method stub
Log.i(&smile&,&查询失败:&+object.size())
注:1、只有当缓存查询的条件一模一样时才会获取到缓存到本地的缓存数据。2、设置的默认的最大缓存时长为5小时。BQL查询
Bmob Query Language(简称 BQL) 是 Bmob 自 BmobSDKV3.3.7 版本开始,为查询 API 定制的一套类似 SQL 查询语法的子集和变种,主要目的是降低大家学习 Bmob 查询API 的成本,可以使用传统的 SQL 语法来查询 Bmob 应用内的数据。 具体的 BQL 语法,请参考 。基本BQL查询
可以通过以下方法来进行SQL查询:例如:需要查询所有的游戏得分记录String bql =&select * from GameScore&;//查询所有的游戏得分记录
new BmobQuery&GameScore&().doSQLQuery(context,bql,new SQLQueryListener&GameScore&(){
public void done(BmobQueryResult&GameScore& result, BmobException e) {
if(e ==null){
List&GameScore& list = (List&GameScore&) result.getResults();
if(list!=null && list.size()&0){
Log.i(&smile&, &查询成功,无数据返回&);
Log.i(&smile&, &错误码:&+e.getErrorCode()+&,错误描述:&+e.getMessage());
上面的示例也等价于(此方法自BmobV3.3.8版本提供)://查询所有的游戏得分记录
String bql =&select * from GameScore&;
BmobQuery&GameScore& query=new BmobQuery&GameScore&();
//设置查询的SQL语句
query.setSQL(bql);
query.doSQLQuery(context,new SQLQueryListener&GameScore&(){
public void done(BmobQueryResult&GameScore& result, BmobException e) {
if(e ==null){
List&GameScore& list = (List&GameScore&) result.getResults();
if(list!=null && list.size()&0){
Log.i(&smile&, &查询成功,无数据返回&);
Log.i(&smile&, &错误码:&+e.getErrorCode()+&,错误描述:&+e.getMessage());
如果需要查询个数,则可以这样:String bql = &select count(*),* from GameScore&;//查询GameScore表中总记录数并返回所有记录信息
new BmobQuery&GameScore&().doSQLQuery(context,bql, new SQLQueryListener&GameScore&(){
public void done(BmobQueryResult&GameScore& result, BmobException e) {
// TODO Auto-generated method stub
if(e ==null){
int count = result.getCount();//这里得到符合条件的记录数
List&GameScore& list = (List&GameScore&) result.getResults();
if(list.size()&0){
Log.i(&smile&, &查询成功,无数据&);
Log.i(&smile&, &错误码:&+e.getErrorCode()+&,错误描述:&+e.getMessage());
注:当查询的表为系统表(目前系统表有User、Installation、Role)时,需要带上下划线 _。比如,你想查询的是用户smile的信息,则:select * from _User where username = smile
统计BQL查询
由于统计查询的结果是不定的,故BQL提供了另外一种查询方法来进行统计查询,可以使用doStatisticQuery方法来进行://按照姓名分组求和,并将结果按时间降序排列
String bql = &select sum(playScore) from GameScore group by name order by -createdAt&;
new BmobQuery&GameScore&().doStatisticQuery(context, bql,new StatisticQueryListener(){
public void done(Object result, BmobException e) {
// TODO Auto-generated method stub
if(e ==null){
JSONArray ary = (JSONArray)
if(ary!=null){//开发者需要根据返回结果自行解析数据
showToast(&查询成功,无数据&);
Log.i(&smile&, &错误码:&+e.getErrorCode()+&,错误描述:&+e.getMessage());
占位符查询
在更多的时候,一个查询语句中间会有很多的值是可变值,为此,我们也提供了类似 Java JDBC 里的 PreparedStatement 使用占位符查询的语法结构。普通查询
String bql=&select * from GameScore where player = ? and game = ?&;//查询玩家1的地铁跑酷的GameScore信息
new BmobQuery&GameScore&().doSQLQuery(context, bql,new SQLQueryListener&GameScore&(){
public void done(BmobQueryResult&GameScore& result, BmobException e) {
// TODO Auto-generated method stub
if(e ==null){
List&GameScore& list = (List&GameScore&) result.getResults();
if(list!=null && list.size()&0){
Log.i(&smile&, &查询成功,无数据返回&);
Log.i(&smile&, &错误码:&+e.getErrorCode()+&,错误描述:&+e.getMessage());
},&玩家1&,&地铁跑酷&);
最后的可变参数 玩家1 和 地铁跑酷 会自动替换查询语句中的问号位置(按照问号的先后出现顺序)。上面的示例也等价于如下代码(此方法自BmobV3.3.8版本提供):String bql=&select * from GameScore where player = ? and game = ?&;
BmobQuery&GameScore& query=new BmobQuery&GameScore&();
//设置SQL语句
query.setSQL(bql);
//设置占位符参数
query.setPreparedParams(new Object[]{&玩家1&,&地铁跑酷&});
query.doSQLQuery(context,new SQLQueryListener&GameScore&(){
public void done(BmobQueryResult&GameScore& result, BmobException e) {
// TODO Auto-generated method stub
if(e ==null){
List&GameScore& list = (List&GameScore&) result.getResults();
if(list!=null && list.size()&0){
Log.i(&smile&, &查询成功,无数据返回&);
Log.i(&smile&, &错误码:&+e.getErrorCode()+&,错误描述:&+e.getMessage());
对于包含内置函数的占位符查询,比较特殊,请使用Bmob Query Language 详细指南中的内置函数中列出的形式进行查询操作:举例:我想查询当前用户在日之后,在特定地理位置附近的游戏记录,可以这样:String sql = &select * from GameScore where createdAt & date(?) and player = pointer(?,?) and gps near geopoint(?,?)&;
new BmobQuery&GameScore&().doSQLQuery(this, sql,new SQLQueryListener&GameScore&(){
public void done(BmobQueryResult&GameScore& result, BmobException e) {
// TODO Auto-generated method stub
if(e ==null){
List&GameScore& list = (List&GameScore&) result.getResults();
if(list!=null && list.size()&0){
Log.i(&smile&, &查询成功,无数据返回&);
Log.i(&smile&, &错误码:&+e.getErrorCode()+&,错误描述:&+e.getMessage());
},& 00:00:00&,&_User&,user.getObjectId(),112..52065);
注1、我们更推荐使用占位符语法,理论上会降低 BQL 转换的性能开销;2、最后的可变参数会自动替换查询语句中的问号位置(按照问号的先后出现顺序),有多少个问号,最后的可变参数就应该有多少个;3、同样的,统计查询也支持占位符,只需要将doSQLQuery替换成doStatisticQuery方法即可;4、只有查询条件where``limit子句支持占位符查询,和统计查询有关的group by、order by、having等字句是不支持占位符的。例如:正确查询://按照游戏名进行分组并获取总得分数大于200的统计信息,同时统计各分组的记录数
String bql = &select sum(playScore),count(*) from GameScore group by game having _sumPlayScore&200&;
new BmobQuery&GameScore&().doStatisticQuery(this, bql,new StatisticQueryListener(){
public void done(Object result, BmobException e) {
// TODO Auto-generated method stub
错误查询:String bql = &select sum(playScore),count(*) from GameScore group by ? having ?&;
new BmobQuery&GameScore&().doStatisticQuery(this, bql,new StatisticQueryListener(){
public void done(Object result, BmobException e) {
// TODO Auto-generated method stub
},&game&,&_sumPlayScore&200&);
BQL缓存查询
BQL查询同步支持缓存查询,只需要调用BmobQuery的setCachePolicy方法设置缓存策略即可,建议使用如下方式进行BQL缓存查询:String sql = &select * from GameScore order by playScore,signScore desc&;
BmobQuery&GameScore& query = new BmobQuery&GameScore&();
//设置sql语句
query.setSQL(sql);
//判断此查询本地是否存在缓存数据
boolean isCache = query.hasCachedResult(this,GameScore.class);
if(isCache){
query.setCachePolicy(CachePolicy.CACHE_ELSE_NETWORK);
// 如果有缓存的话,则设置策略为CACHE_ELSE_NETWORK
query.setCachePolicy(CachePolicy.NETWORK_ELSE_CACHE);
// 如果没有缓存的话,则设置策略为NETWORK_ELSE_CACHE
query.doSQLQuery(this,new SQLQueryListener&GameScore&(){
public void done(BmobQueryResult&GameScore& result, BmobException e) {
// TODO Auto-generated method stub
if(e ==null){
Log.i(&smile&, &查询到:&+result.getResults().size()+&符合条件的数据&);
Log.i(&smile&, &错误码:&+e.getErrorCode()+&,错误描述:&+e.getMessage());
注:doSQLQuery目前有三种查询方式进行SQL查询,分别是:1、doSQLQuery(Context context,SQLQueryListener listener)2、doSQLQuery(Context context, String bql, SQLQueryListener listener)----基本BQL查询3、doSQLQuery(Context context, String bql, SQLQueryListener listener,Object... params)----占位符查询只有第一种查询方式才能和query.hasCachedResult(context,class)或者query.clearCachedResult(context,class)并列使用。建议使用第一种查询方式进行BQL缓存查询。数组
对于数组类型数据,BmobSDK提供了3种操作来原子性地修改一个数组字段的值:
add、addAll 在一个数组字段的后面添加一些指定的对象(包装在一个数组内)
addUnique、addAllUnique 只会在原本数组字段中没有这些对象的情形下才会添加入数组,插入数组的位置随机
removeAll 从一个数组字段的值内移除指定数组中的所有对象
举例子:public class Person extends BmobObject {
private List&String&
// 爱好-对应服务端Array类型:String类型的集合
private List&BankCard&
// 银行卡-对应服务端Array类型:Object类型的集合
getter、setter方法
其中BankCard类结构如下:
public class BankCard{
private String cardN
private String bankN
public BankCard(String bankName, String cardNumber){
this.bankName = bankN
this.cardNumber = cardN
getter、setter方法
添加数组数据
给Person对象中的数组类型字段添加数据,有以下两种方式:使用add、addAll添加
Person p = new Person();
p.setObjectId(&d32143db92&);
//添加String类型的数组
p.add(&hobbys&, &唱歌&);
// 添加单个String
//p.addAll(&hobbys&, Arrays.asList(&游泳&, &看书&));
// 添加多个String
//添加Object类型的数组
p.add(&cards&,new BankCard(&工行卡&, &工行卡账号&))
//添加单个Object
List&BankCard& cards =new ArrayList&BankCard&();
for(int i=0;i&2;i++){
cards.add(new BankCard(&建行卡&+i, &建行卡账号&+i));
//p.addAll(&cards&, cards);
//添加多个Object值
p.save(this, new SaveListener() {
public void onSuccess() {
// TODO Auto-generated method stub
Log.i(&bmob&,&保存成功&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
Log.i(&bmob&,&保存失败:&+msg);
注:此类方法不管这些数据之前是否已添加过,都会再次添加。使用addUnique、addAllUnique添加
Person p = new Person();
//添加String类型的数组
p.addUnique(&hobbys&, &唱歌&);
// 添加单个String
//p.addAllUnique(&hobbys&, Arrays.asList(&游泳&, &看书&));
// 添加多个String
//添加Object类型的数组
p.addUnique(&cards&,new BankCard(&工行卡&, &工行卡账号&))
//添加单个Object
List&BankCard& cards =new ArrayList&BankCard&();
for(int i=0;i&2;i++){
cards.add(new BankCard(&建行卡&+i, &建行卡账号&+i));
//p.addAllUnique(&cards&, cards);
//添加多个Object
p.update(this, &d32143db92&,new UpdateListener() {
public void onSuccess() {
// TODO Auto-generated method stub
Log.i(&bmob&,&添加爱好成功&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
Log.i(&bmob&,&添加爱好失败:&+msg);
注: 只有在这些数据之前未添加过的情况下才会被添加。更新数组数据
数组更新比较特殊,自V3.4.4版本开始提供BmobObject的setValue方法来更新数组,例:Person p2 = new Person();
//更新String类型数组中的值
p2.setValue(&hobbys.0&,&爬山&);
//将hobbys中第一个位置的爱好(上面添加成功的唱歌)修改为爬山
//更新Object类型数组中的某个位置的对象值(0对应集合中第一个元素)
p2.setValue(&cards.0&, new BankCard(&中行&, &中行卡号&));
//将cards中第一个位置银行卡修改为指定BankCard对象
//更新Object类型数组中指定对象的指定字段的值
p2.setValue(&cards.0.bankName&, &农行卡&);
//将cards中第一个位置的银行卡名称修改为农行卡
p2.setValue(&cards.1.cardNumber&, &农行卡账号&);
//将cards中第二个位置的银行卡账号修改为农行卡账号
p2.update(this, objectId, new UpdateListener() {
public void onSuccess() {
// TODO Auto-generated method stub
Log.i(&bmob&,&更新成功:& + p2.getUpdatedAt());
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
Log.i(&bmob&,&更新失败:& + msg);
删除数组数据
同理我们也可以使用removeAll从数组字段中移除某些值:Person p = new Person();
p.removeAll(&hobby&, Arrays.asList(&阅读&,&唱歌&,&游泳&));
p.update(this, new UpdateListener() {
public void onSuccess() {
// TODO Auto-generated method stub
Log.i(&bmob&,&从hobby字段中移除阅读、唱歌、游泳成功&);
public void onFailure(int code, String msg) {
// TODO Auto-generated method stub
Log.i(&bmob&,&从hobby字段中移除阅读、唱歌、游泳失败:&+msg);
查询数组数据
对于字段类型为数组的情况,可以以数组字段中包含有xxx的数据为条件进行查询:BmobQuery&Person& query = new BmobQuery&Person&();
String [] hobby = {&阅读&,&唱歌&};
query.addWhereContainsAll(&hobby&, Arrays.asList(hobby));
query.findObjects(this, new FindListener&Person&() {
public void onSuccess(List&Person& object) {
// TODO Auto-generated method stub
Log.i(&bmob&,&查询成功:共& + object.size() + &条数据。&);
public void onError(int code, String msg) {
// TODO Auto-generated method stub
Log.i(&bmob&,&查询失败:& + code);
数据关联性
关联关系描述
在程序设计中,不同类型的数据之间可能存在某种关系。比如:帖子和作者的关系,一篇帖子只属于某个作者,这是一对一的关系。比如:帖子和评论的关系,一条评论只属于某一篇帖子,而一篇帖子对应有很多条评论,这是一对多的关系。比如:学生和课程的关系,一个学生可以选择很多课程,一个课程也可以被很多学生所选择,这是多对多的关系。Bmob提供了Pointer(一对一、一对多)和Relation(多对多)两种数据类型来解决这种业务需求。关联关系案例详解
由于关联关系讲解起来比较复杂,以下用一个简单的案例来说明在Bmob中是如何使用关联关系的。场景:用户发表帖子,同时又可对帖子进行评论留言。在这个场景中涉及到三个表:用户表(_User)、帖子表(Post)、评论表(Comment),以下是各个表的字段:_User字段如下: 字段 类型
含义 objectId
用户ID username
用户名(可以既发帖子又发评论) age
Post字段如下: 字段
类型 objectId
String 帖子ID
String 帖子标题
String 帖子内容
Pointer 帖子作者
Relation 喜欢帖子的读者
Comment字段如下: 字段
类型 objectId
String 评论ID
String 评论内容
Pointer 评论对应的帖子
Pointer 评论该帖子的人
Web端创建关联字段
如果你需要在Web端创建上述表的话,那么当选择的字段类型为Pointer或Relation时,会提示你选择该字段所指向或关联的数据表。如下图所示:创建数据对象
public class MyUser extends BmobUser {
private I//为用户表新增一个age字段,注意其必须为`Integer`类型,而不是int
//自行实现getter和setter方法
1、扩展BmobUser的时,不需要再加上objectId、username、password、createAt、updateAt等系统字段,因为BmobUser中已经实现了,如果再次声明的话,会导致编译性的错误。2、类名可以自定义,这个跟其他表的命名方式有所不同。
public class Post extends BmobObject {
private S//帖子标题
private S// 帖子内容
private MyU//帖子的发布者,这里体现的是一对一的关系,该帖子属于某个用户
private BmobF//帖子图片
private BmobR//多对多关系:用于存储喜欢该帖子的所有用户
//自行实现getter和setter方法
public class Comment

我要回帖

更多关于 ioses文件浏览器 的文章

 

随机推荐