待解决:1.自处理复杂的sql语句
2.xutils自定义类型的属性
Xutils 数据库存储自定义类型和自定义数据类型集合 - 简书 (jianshu.com)
(1条消息) xUtils系列之DbUtils-保存自定义类型_轻度强迫症患者的博客-CSDN博客
(1条消息) xUtils 3 中,如何存储自定义实体类字段类型_WymanWong的博客-CSDN博客
buil.gradle
中添加如下内容:implementation 'org.xutils:xutils:3.9.0'
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
x.Ext.init(this);//注册Xutils
//x.Ext.setDebug(false); // 是否输出debug日志,开启debug会影响性能,暂时未用到
//自定义特殊类型的转换器,
//ColumnConverterFactory.registerColumnConverter(GeometryField.class, new GeometryColumnConverter());
initDBManager();//数据库模块使用的,自定义的一个用来初始化数据库的函数
//数据库初始化
private void initDBManager() {
//data/data/com.iot.gis/databases/gis_report.db
File dbFile = this.getDatabasePath("gis_report.db");
//getDatabasePath函数是用来获取右侧手机路径:/data/user/0/应用包名/databases/参数名 下的文件
boolean dbFileOk = copyDb(dbFile);
//因为项目需要自带数据,所以就把数据都放到一个SQLite的数据库文件中了,之后把db文件放到了assets文件夹下面。
//copyDb函数然后判断手机路径下是否有db文件,如果没有,就把assets下的db文件数据,复制到对应目录下,如果有,则表示已经复制过了,就不需要创建了。
if (!dbFileOk) {
Logger.eTag(TAG, ResUtils.getString(R.string.db_file_not_exists));
return;
}
DbManager.DaoConfig daoConfig = new DbManager.DaoConfig()
.setDbName("gis_report.db")//设置数据库名称
.setDbVersion(1)//设置数据库版本
.setAllowTransaction(true)//设置是否允许事务,默认true
.setDbDir(dbFile.getParentFile())// 不设置dbDir时, 默认存储在app的私有目录.
.setDbOpenListener( new DbManager.DbOpenListener() {//设置数据库打开的监听
@Override
public void onDbOpened(DbManager db) {
//开启数据库支持多线程操作,提升性能,对写入加速提升巨大
db.getDatabase().enableWriteAheadLogging();
}
}
)
//下面这2个暂时还没用到
/* .setTableCreateListener( new DbManager.TableCreateListener(){//设置表创建的监听
@Override
public void onTableCreated(DbManager db, TableEntity<?> table) {
Log.i("JAVA", "onTableCreated:" + table.getName());
}
})
.setDbUpgradeListener(new DbManager.DbUpgradeListener() {//设置数据库更新的监听
@Override
public void onUpgrade(DbManager db, int oldVersion, int newVersion) {
}
})*/
;
try {
db = x.getDb(daoConfig);
//gisDB = new GISDbManager(db);//gisDB是学长创建的用来查询复杂的sql语句的,里面还包含了事务
Logger.iTag(TAG, db.getDatabase().getPath());
} catch (DbException e) {
Logger.eTag(TAG, e);
}
}
private boolean copyDb(File dbFileTargetPath) {
try {
if (!dbFileTargetPath.exists()) { //判断该文件是否存在于手机中
InputStream dbFileIS = this.getAssets().open("gis_report.db");
//以数据流的形式获取左侧AS中assets文件夹中对应文件名的内容
return FileIOUtils.writeFileFromIS(dbFileTargetPath, dbFileIS);
//将读取的输入流写入文件
}
} catch (IOException e) {
Logger.eTag(TAG, e);
return false;
}
return true;
}
import org.xutils.db.annotation.Column;
import org.xutils.db.annotation.Table;
//数据库中表的实体类
@Table(name = "Common_Using_rock_soil_sample") //确定表名
public class SampleModel {
//样本ID
@Column(name = "sample_id", isId = true, autoGen = false)//isId为true代表为主键,autoGen为true代表自增,不写autoGen这个属性,默认是自增长的属性
//@Column(name = "sample_id",property ="NOT NULL")//添加约束条件,这里不能为空。
//如果普通属性没有加上@Column标签,生成表中的字段就不会包含该属性
public long sample_id;
//项目ID
@Column(name = "project_id")//name是用来设置列名的
public long project_id;
//样本编号
@Column(name = "sample_code")
public String sample_code;
//样本类型
@Column(name = "sample_type")
public String sample_type;
//动作关联ID
@Column(name = "action_relation_id")
public long action_relation_id;
//版本号
@Column(name = "sync_version_number")
public long sync_version_number;
//备注
@Column(name = "remark")
public String remark;
//野外名称
@Column(name = "field_name")
public String field_name;
//勘调对象ID
@Column(name = "survey_target_id")
public long survey_target_id;
public SampleModel() {//必须要有无参构造,否则创建表不成功
}
//有参构造方法和相关set、get方法根据自己的需求来,使用AS快捷键创建会方便很多
}
//插入
public static void insertSamples(List<SampleModel> sampleModels) {
for (SampleModel sampleModel : sampleModels) {
try {
GISApplication.db.saveOrUpdate(sampleModel); //更新保存单个样例***主要用saveOrUpdate
} catch (DbException e) {
Log.e("eee", "samplemodel");
}
}
try {
GISApplication.db.save(sampleModels);//保存实体类或实体类的List到数据库
//db.replace(list);保存或更新实体类或实体类的List到数据库, 根据id和其他唯一索引判断数据是否存在
//db.saveOrUpdate(list);保存或更新实体类或实体类的List到数据库, 根据id对应的数据是否存在.
//db.saveBindingId(list);保存实体类或实体类的List到数据库,如果该类型的id是自动生成的, 则保存完后会给id赋值.
/**
* 1.如果在你建表的时候你的主键设置成自增长,那么你在插入数据的时候直接调replace方法就可以了,
* 但是saveOrUpdate只能达到插入的效果,达不到更新原有数据的效果.
* 2.如果在你建表的时候你的主键设置成不是自增长,replace方法当然可以插入,saveOrUpdate方法既可以插入也可以达到更新的效果
*/
} catch (DbException e) {
Log.e("eee", "samplemodels");
}
}
//查询
public static List<SampleModel> selectSamples() {
try {
SampleModel sampleModel1 = GISApplication.db.findById(SampleModel.class, 2);//根据主键来查找表里的数据
SampleModel sampleModel2 = GISApplication.db.findFirst(SampleModel.class);//返回当前表的第一条数据
//查询所有数据
List<SampleModel> all = GISApplication.db.findAll(SampleModel.class);
//按条件查找,查询年龄大于15的
List<DbModel> dbModelAll = GISApplication.db
.findDbModelAll(new SqlInfo("select * from student where age > 15"));//findDbModelFirst
for (int i = 0; i < dbModelAll.size(); i++) {
DbModel dbModel = dbModelAll.get(i);
String name = dbModel.getString("name");
Log.i("tag", "查询的数据: name=" + name);
}
//第二种条件查找,我用的这种
List<SampleModel> all1 = GISApplication.db.selector(SampleModel.class)//***主要用这种查询条件
.where("age", ">", 14)
.and("age", "<", 16)
.findAll();//.findFirst();.count();
/**List<DbModel> list = db.selector(Child.class) //复杂的参考样例
.where("age", "<", 18)
.groupBy("parentId")
.having(WhereBuilder.b("COUNT(parentId)", ">", 1))
.select("parentId, COUNT(parentId) as childNum")
.findAll();**/
//和上面那种应该是等价的
WhereBuilder b = WhereBuilder.b();
b.and("id",">",2); //构造修改的条件
b.and("id","<",4);
List<SampleModel> all2 = GISApplication.db.selector(SampleModel.class)
.where(b).findAll();
//第三种
List<SampleModel> all3 = GISApplication.db.selector(SampleModel.class)
.expr("age>14 and age<17").findAll();
if (all1 == null) {
all1 = new ArrayList<>();
}
return all1;
} catch (DbException e) {
return new ArrayList<>();
}
}
//删除
public static void deleteSamples() {
try {
//第一种,根据主键来删除
GISApplication.db.deleteById(SampleModel.class,5);//删除主键为5的值
//第二种方法,找到符合条件的第一条数据 .findAll()就是找所有符合条件的了
SampleModel student = GISApplication.db.selector(SampleModel.class)
.where("name", "=", "学生11").findFirst();
GISApplication.db.delete(student);//先找到,再删除 ,需要判断为不为空
//第三种,删除那name=学生9 且 sex=女 的数据
GISApplication.db.delete(SampleModel.class, WhereBuilder
.b("name","=" ,"学生9")
.and("sex","=","女"));
//第二种写法,添加删除条件:
WhereBuilder b = WhereBuilder.b();
b.and("id",">",2); //构造修改的条件
b.and("id","<",4);
GISApplication.db.delete(SampleModel.class, b);
//第四种,删除所有数据,但是表还在
GISApplication.db.delete(SampleModel.class);
//db.dropTable(Student.class);删除表
//db.dropDb();删除数据库
} catch (DbException e) {
e.printStackTrace();
}
}
数据传输他这里有同步请求和异步请求,同步请求需要自己单独再开一个线程,我这里认为如果你需要同时传多个数据对应多个接受数据的时候,把这几个同步传输,然后放到一个子线程中。
new Thread(new Runnable() {
@Override
public void run() {
///相关传输数据的函数
getActivity().runOnUiThread(new Thread(() -> {
}));
}
}).start();
///下面这种是用lamdba表达式
new Thread(() -> {
///相关传输数据的函数
postData();
getActivity().runOnUiThread(new Thread(() -> {
}));
}).start();
public void postData(String POST_Url){
RequestParams params = new RequestParams(POST_Url); //POST_Url为post上传的 地址+函数名称
JSONObject js_request = new JSONObject();//服务器需要传参的json对象
js_request.put("geom", "XXX");//根据实际需求添加相应键值对,put是一个一个添加的
Map<String, Object> attrs=new HashMap<>();
attrs.put("eguid", "1");
attrs.put("survey_target_id", 2);
js_request.putAll(attrs); //添加一群键值对
params.setAsJsonContent(true); //以json形式提交body参数
//params.setAsJsonArrayContent(true); //以json array形式提交body参数
params.setBodyContent(js_request.toString());//设置body参数中的内容
try {
String data = x.http().postSync(params, String.class); //JSONObject.class
//data
} catch (Throwable throwable) {
//处理报错
}
}
//参考地址:http://42.192.6.203:9904/api/EntityAttributeTable/postBo?<{"delete_flag":0,"sync_version_number":21}>
public void getData(String GET_Url){
RequestParams params2 = new RequestParams(GET_Url); //GET_Url为get下载的 地址+函数名称
params2.addQueryStringParameter("work_point_id", 1);
params2.addQueryStringParameter("p", 2);//这个可以添加多个,通过类的反射机制,自动用for循环添加类的各个属性
//下面这2个参数可能主要还是为了实现断点下载,虽然好像暂时没用到?
params2.setAutoResume(true);//设置是否在下载是自动断点续传,默认的也是为true,可以不设置
params2.setCancelFast(true); 是否可以被立即停止
try {
String data = x.http().getSync(params2, String.class);
//data是获取到的数据,如果是json数据,可以采用对应的方法转换成对应的类
} catch (Throwable throwable) {
//报错,进行处理
}
}
//参考地址:http://42.192.6.200:9900/api/EntityAttributeTable/getBou?id=1&name="2"
public void postFile(String POST_Url,String path){
RequestParams params = new RequestParams(POST_Url); //POST_Url为post上传的 地址+函数名称
//传输文件
params.setMultipart(true);
params.addBodyParameter("file", new File(path)); //适用于POST请求方式;添加到Body体的参数。
params.setAutoRename(true);//文件的自动命名,服务器端设置的重复的文件名会覆盖掉
try {
File data = x.http().postSync(params, File.class);
//Log.e("eee2", data.toString());
//如果是请求json,使用String.class,如果下载文件,使用File.class。这里上传的感觉用String也可以?
} catch (Throwable throwable) {
//报错处理
}
}
//参考地址:http://42.192.6.200:9900/api/EntityAttributeTable/PostFile?<file=/storage/emulated/0/YingHe/sketchPhoto/2022-03-30_092143.png>
public void getFile(String GET_Url,String path){ //path是要保存到手机中的地址,参考:/storage/emulated/0/Pictures/1/224.jpg
RequestParams params2 = new RequestParams(GET_Url); //GET_Url为get下载的 地址+Photos+文件名
params2.setMultipart(true);//传输文件,使用multipart表单
params2.setSaveFilePath(path);//设置下载文件时文件保存的路径和文件名
try {
File data = x.http().getSync(params2, File.class);
//Log.e("eee2", data.getAbsolutePath());
} catch (Throwable throwable) {
//报错,进行处理
}
}
//参考地址:http://42.192.6.203:9904/Photos/2022-03-30_092143.png?
public void postFileName(){
RequestParams requestParams = new RequestParams(POST_FileName);
Log.e("eee1","eee1");
requestParams.addBodyParameter("TableName", "eee");
requestParams.addBodyParameter("ProjectId", 2);
requestParams.addBodyParameter("photoFileName", "223.png");
requestParams.setAutoResume(true);
requestParams.setCancelFast(true);
try {
String data = x.http().postSync(requestParams, String.class);
Log.e("eee2",data);
}catch (Throwable throwable) {
throwable.printStackTrace();
Log.e("eee3","eee3");
}
}
/**
JSONObject jsonObject;
try {
jsonObject = x.http().getSync(params, JSONObject.class);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
**/
暂时还不太会
参考网址:
GitHub - wyouflf/xUtils3: Android orm, bitmap, http, view inject...
Android Xutils3 完全解析 - 上七旗娃儿 - 博客园 (cnblogs.com)
(1条消息) XUtils3的使用(Get,Post,断点下载,上传文件,数据库,bitmap的下载与缓存)_Dawn仧的博客-CSDN博客_xutils3上传bitmap
xUtils使用详细介绍 - favour - 博客园 (cnblogs.com)
Android xUtils3.0使用手册(一)- 基础功能使用 - 大西瓜3721 - 博客园 (cnblogs.com)
Android使用xUtils3.0实现文件上传_Android_萬仟网 (10qianwan.com)
xUtils 3.0 post使用详解 - 丶贰九 - 博客园 (cnblogs.com)
xUtils3 注解模块 - Vitality - 博客园 (cnblogs.com)
public void postData()
{
JSONObject js_request = new JSONObject();//服务器需要传参的json对象
js_request.put("key", "value");//根据实际需求添加相应键值对
js_request.put("key1", "value1");
js_request.put("key2", "value2");
RequestParams params = new RequestParams("http://www.baidu.com");
params.setAsJsonContent(true);
params.setBodyContent(js_request.toString());
//params.addBodyParameter("pageNo","1");
//params.addBodyParameter("pageSize","20");
//post这里改成request就一样
x.http().post(params, new Callback.CacheCallback<String>() {//发起传参为json的post请求,
// Callback.CacheCallback<String>的泛型为后台返回数据的类型,
// 根据实际需求更改
@Override
public boolean onCache(String result) {
return false;
}
@Override
public void onSuccess(String result) {
//此处请求成功后的逻辑
Log.e("eee2",result);
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
Log.i("tag", "请求异常");
}
@Override
public void onCancelled(CancelledException cex) {
Log.i("tag", "取消请求的回调方法");
}
@Override
public void onFinished() {
Log.i("tag", "请求完成,并不一定是请求成功,断开了连接就会执行该方法");
}
});
}
public void get(){
RequestParams params = new RequestParams(url);
params.addQueryStringParameter("username","abc");
params.addQueryStringParameter("password","123");
Callback.Cancelable cancelable = x.http().get(params, new Callback.CommonCallback<string>() {
@Override
public void onSuccess(String result) {
Log.i("JAVA", "onSuccess result:" + result);
}
//请求异常后的回调方法
@Override
public void onError(Throwable ex, boolean isOnCallback) {
}
//主动调用取消请求的回调方法
@Override
public void onCancelled(CancelledException cex) {
}
@Override
public void onFinished() {
}
});
}
public void posfile(){
String path="/mnt/sdcard/Download/icon.jpg";
RequestParams params = new RequestParams("地址");
params.setMultipart(true);
params.addBodyParameter("file",new File(path));//设置上传的文件路径
x.http().post(params, new Callback.CommonCallback<String>() {
@Override
public void onSuccess(String result) {
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
}
@Override
public void onCancelled(CancelledException cex) {
}
@Override
public void onFinished() {
}
});
}
public void getfile(){
RequestParams params = new RequestParams(url);
//自定义保存路径,Environment.getExternalStorageDirectory():SD卡的根目录
params.setSaveFilePath(Environment.getExternalStorageDirectory()+"/myapp/");
//自动为文件命名
params.setAutoRename(true);
x.http().get(params, new Callback.ProgressCallback<file>() {
@Override
public void onSuccess(File result) {
//apk下载完成后,调用系统的安装方法
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(result), "application/vnd.android.package-archive");
getActivity().startActivity(intent);
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
}
@Override
public void onCancelled(CancelledException cex) {
}
@Override
public void onFinished() {
}
//网络请求之前回调
@Override
public void onWaiting() {
}
//网络请求开始的时候回调
@Override
public void onStarted() {
}
//下载的时候不断回调的方法
@Override
public void onLoading(long total, long current, boolean isDownloading) {
//当前进度和文件总大小
Log.i("JAVA","current:"+ current +",total:"+total);
}
});
}
//使用缓存
public void cache(){
RequestParams params = new RequestParams(url);
params.setCacheMaxAge(1000*60); //为请求添加缓存时间
Callback.Cancelable cancelable = x.http().get(params, new Callback.CacheCallback<string>() {
@Override
public void onSuccess(String result) {
Log.i("JAVA","onSuccess:"+result);
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
}
@Override
public void onCancelled(CancelledException cex) {
}
@Override
public void onFinished() {
}
//result:缓存内容
@Override
public boolean onCache(String result) {
//在setCacheMaxAge设置范围(上面设置的是60秒)内,如果再次调用GET请求,
//返回true:缓存内容被返回,相信本地缓存,返回false:缓存内容被返回,不相信本地缓存,仍然会请求网络
Log.i("JAVA","cache:"+result);
return true;
}
});
}
断点下载:
pulblic void duan(){
//设置请求参数
RequestParams params = new RequestParams(pathApk);
params.setAutoResume(true);//设置是否在下载是自动断点续传
params.setAutoRename(false);//设置是否根据头信息自动命名文件
params.setSaveFilePath("/sdcard/xutils/xUtils_1.avi");
params.setExecutor(new PriorityExecutor(2, true));//自定义线程池,有效的值范围[1, 3], 设置为3时, 可能阻塞图片加载.
params.setCancelFast(true);//是否可以被立即停止.
//下面的回调都是在主线程中运行的,这里设置的带进度的回调
cancelable = x.http().get(params, new Callback.ProgressCallback<File>() {
@Override
public void onCancelled(CancelledException arg0) {
Log.i("tag", "取消"+Thread.currentThread().getName());
}
@Override
public void onError(Throwable arg0, boolean arg1) {
Log.i("tag", "onError: 失败"+Thread.currentThread().getName());
progressDialog.dismiss();
}
@Override
public void onFinished() {
Log.i("tag", "完成,每次取消下载也会执行该方法"+Thread.currentThread().getName());
progressDialog.dismiss();
}
@Override
public void onSuccess(File arg0) {
Log.i("tag", "下载成功的时候执行"+Thread.currentThread().getName());
}
@Override
public void onLoading(long total, long current, boolean isDownloading) {
if (isDownloading) {
progressDialog.setProgress((int) (current*100/total));
Log.i("tag", "下载中,会不断的进行回调:"+Thread.currentThread().getName());
}
}
@Override
public void onStarted() {
Log.i("tag", "开始下载的时候执行"+Thread.currentThread().getName());
progressDialog.show();
}
@Override
public void onWaiting() {
Log.i("tag", "等待,在onStarted方法之前执行"+Thread.currentThread().getName());
}
});
}
添加到请求body体的参数, 只有POST, PUT, PATCH, DELETE请求支持.
暂未使用,用时百度。
暂未使用,用时百度。