parent
2db3579f46
commit
2ef9550d86
@ -0,0 +1,44 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package com.arialyy.aria.core.download; |
||||||
|
|
||||||
|
import com.arialyy.aria.orm.AbsWrapper; |
||||||
|
import com.arialyy.aria.orm.annotation.Many; |
||||||
|
import com.arialyy.aria.orm.annotation.One; |
||||||
|
import com.arialyy.aria.orm.annotation.Wrapper; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by laoyuyu on 2018/3/30. |
||||||
|
*/ |
||||||
|
@Wrapper |
||||||
|
public class DownloadGroupTaskWrapper extends AbsWrapper { |
||||||
|
|
||||||
|
@One |
||||||
|
public DownloadGroupEntity entity; |
||||||
|
|
||||||
|
@Many(parentColumn = "key", entityColumn = "groupName") |
||||||
|
private List<DownloadGroupTaskEntity> taskEntitys; |
||||||
|
|
||||||
|
public DownloadGroupTaskEntity taskEntity; |
||||||
|
|
||||||
|
@Override protected void handleConvert() { |
||||||
|
taskEntity = (taskEntitys == null || taskEntitys.isEmpty()) ? null : taskEntitys.get(0); |
||||||
|
if (taskEntity != null) { |
||||||
|
taskEntity.setEntity(entity); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package com.arialyy.aria.core.download; |
||||||
|
|
||||||
|
import com.arialyy.aria.orm.AbsWrapper; |
||||||
|
import com.arialyy.aria.orm.annotation.Many; |
||||||
|
import com.arialyy.aria.orm.annotation.One; |
||||||
|
import com.arialyy.aria.orm.annotation.Wrapper; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by laoyuyu on 2018/3/30. |
||||||
|
*/ |
||||||
|
@Wrapper |
||||||
|
public class DownloadGroupWrapper extends AbsWrapper { |
||||||
|
|
||||||
|
@One |
||||||
|
public DownloadGroupEntity groupEntity; |
||||||
|
|
||||||
|
@Many(parentColumn = "groupName", entityColumn = "groupName") |
||||||
|
public List<DownloadEntity> subEntity; |
||||||
|
|
||||||
|
@Override protected void handleConvert() { |
||||||
|
if (subEntity != null && !subEntity.isEmpty()) { |
||||||
|
groupEntity.setSubTasks(subEntity); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package com.arialyy.aria.core.download; |
||||||
|
|
||||||
|
import com.arialyy.aria.orm.AbsWrapper; |
||||||
|
import com.arialyy.aria.orm.annotation.Many; |
||||||
|
import com.arialyy.aria.orm.annotation.One; |
||||||
|
import com.arialyy.aria.orm.annotation.Wrapper; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by laoyuyu on 2018/3/30. |
||||||
|
*/ |
||||||
|
@Wrapper |
||||||
|
public class DownloadTaskWrapper extends AbsWrapper { |
||||||
|
|
||||||
|
@One |
||||||
|
public DownloadEntity entity; |
||||||
|
|
||||||
|
@Many(parentColumn = "downloadPath", entityColumn = "key") |
||||||
|
private List<DownloadTaskEntity> taskEntitys = null; |
||||||
|
|
||||||
|
public DownloadTaskEntity taskEntity; |
||||||
|
|
||||||
|
@Override public void handleConvert() { |
||||||
|
taskEntity = (taskEntitys == null || taskEntitys.isEmpty()) ? null : taskEntitys.get(0); |
||||||
|
if (taskEntity != null) { |
||||||
|
taskEntity.entity = entity; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,86 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
package com.arialyy.aria.core.manager; |
|
||||||
|
|
||||||
import com.arialyy.aria.core.AriaManager; |
|
||||||
import com.arialyy.aria.core.inf.AbsTask; |
|
||||||
import com.arialyy.aria.util.ALog; |
|
||||||
import com.arialyy.aria.util.CommonUtil; |
|
||||||
import java.util.Iterator; |
|
||||||
import java.util.Map; |
|
||||||
import java.util.concurrent.ConcurrentHashMap; |
|
||||||
|
|
||||||
/** |
|
||||||
* Created by Aria.Lao on 2017/9/1. |
|
||||||
* 任务管理器 |
|
||||||
*/ |
|
||||||
class TaskManager { |
|
||||||
private static final String TAG = "TaskManager"; |
|
||||||
private static volatile TaskManager INSTANCE = null; |
|
||||||
private Map<String, AbsTask> map = new ConcurrentHashMap<>(); |
|
||||||
|
|
||||||
public static TaskManager getInstance() { |
|
||||||
if (INSTANCE == null) { |
|
||||||
synchronized (TaskManager.class) { |
|
||||||
INSTANCE = new TaskManager(); |
|
||||||
} |
|
||||||
} |
|
||||||
return INSTANCE; |
|
||||||
} |
|
||||||
|
|
||||||
private TaskManager() { |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 管理器添加任务 |
|
||||||
* |
|
||||||
* @param key 任务的key,下载为保存路径,任务组为任务组名,上传为文件上传路径 |
|
||||||
* @param task 任务 |
|
||||||
* @return {@code true}添加成功 |
|
||||||
*/ |
|
||||||
public <T extends AbsTask> boolean addTask(String key, Class<T> clazz, T task) { |
|
||||||
String hash = CommonUtil.keyToHashKey(key); |
|
||||||
if (map.keySet().contains(hash)) { |
|
||||||
ALog.e(TAG, "任务【" + key + "】已存在"); |
|
||||||
return false; |
|
||||||
} |
|
||||||
map.put(CommonUtil.keyToHashKey(key), task); |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 移除任务 |
|
||||||
* |
|
||||||
* @param key 任务的key,下载为保存路径,任务组为任务组名,上传为文件上传路径 |
|
||||||
*/ |
|
||||||
public void removeTask(String key) { |
|
||||||
String hash = CommonUtil.keyToHashKey(key); |
|
||||||
for (Iterator<Map.Entry<String, AbsTask>> iter = map.entrySet().iterator(); iter.hasNext(); ) { |
|
||||||
Map.Entry<String, AbsTask> entry = iter.next(); |
|
||||||
if (entry.getKey().equals(hash)) iter.remove(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 通过key获取任务 |
|
||||||
* |
|
||||||
* @return 如果找不到任务,返回null,否则返回key对应的任务 |
|
||||||
*/ |
|
||||||
public AbsTask getTask(String key) { |
|
||||||
return map.get(CommonUtil.keyToHashKey(key)); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,45 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package com.arialyy.aria.core.upload; |
||||||
|
|
||||||
|
import com.arialyy.aria.orm.AbsWrapper; |
||||||
|
import com.arialyy.aria.orm.annotation.Many; |
||||||
|
import com.arialyy.aria.orm.annotation.One; |
||||||
|
import com.arialyy.aria.orm.annotation.Wrapper; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by laoyuyu on 2018/3/30. |
||||||
|
*/ |
||||||
|
@Wrapper |
||||||
|
public class UploadTaskWrapper extends AbsWrapper { |
||||||
|
|
||||||
|
@One |
||||||
|
public UploadEntity entity; |
||||||
|
|
||||||
|
@Many(parentColumn = "filePath", entityColumn = "key") |
||||||
|
private List<UploadTaskEntity> taskEntitys = null; |
||||||
|
|
||||||
|
public UploadTaskEntity taskEntity; |
||||||
|
|
||||||
|
@Override public void handleConvert() { |
||||||
|
//taskEntity.entity = (tEntity == null || tEntity.isEmpty()) ? null : tEntity.get(0);
|
||||||
|
taskEntity = (taskEntitys == null || taskEntitys.isEmpty()) ? null : taskEntitys.get(0); |
||||||
|
if (taskEntity != null) { |
||||||
|
taskEntity.entity = entity; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,162 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package com.arialyy.aria.orm; |
||||||
|
|
||||||
|
import android.database.Cursor; |
||||||
|
import android.database.sqlite.SQLiteDatabase; |
||||||
|
import android.support.v4.util.LruCache; |
||||||
|
import com.arialyy.aria.util.ALog; |
||||||
|
import com.arialyy.aria.util.CommonUtil; |
||||||
|
import java.lang.reflect.Field; |
||||||
|
import java.net.URLEncoder; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by laoyuyu on 2018/3/22. |
||||||
|
*/ |
||||||
|
abstract class AbsDelegate { |
||||||
|
static final String TAG = "AbsDelegate"; |
||||||
|
static final int CREATE_TABLE = 0; |
||||||
|
static final int TABLE_EXISTS = 1; |
||||||
|
static final int INSERT_DATA = 2; |
||||||
|
static final int MODIFY_DATA = 3; |
||||||
|
static final int FIND_DATA = 4; |
||||||
|
static final int FIND_ALL_DATA = 5; |
||||||
|
static final int DEL_DATA = 6; |
||||||
|
static final int ROW_ID = 7; |
||||||
|
static final int RELATION = 8; |
||||||
|
static final int DROP_TABLE = 9; |
||||||
|
|
||||||
|
static LruCache<String, DbEntity> mDataCache = new LruCache<>(1024); |
||||||
|
|
||||||
|
/** |
||||||
|
* 打印数据库日志 |
||||||
|
* |
||||||
|
* @param type {@link DelegateWrapper} |
||||||
|
*/ |
||||||
|
static void print(int type, String sql) { |
||||||
|
if (!ALog.DEBUG) { |
||||||
|
return; |
||||||
|
} |
||||||
|
String str = ""; |
||||||
|
switch (type) { |
||||||
|
case CREATE_TABLE: |
||||||
|
str = "创建表 >>>> "; |
||||||
|
break; |
||||||
|
case TABLE_EXISTS: |
||||||
|
str = "表是否存在 >>>> "; |
||||||
|
break; |
||||||
|
case INSERT_DATA: |
||||||
|
str = "插入数据 >>>> "; |
||||||
|
break; |
||||||
|
case MODIFY_DATA: |
||||||
|
str = "修改数据 >>>> "; |
||||||
|
break; |
||||||
|
case FIND_DATA: |
||||||
|
str = "查询一行数据 >>>> "; |
||||||
|
break; |
||||||
|
case FIND_ALL_DATA: |
||||||
|
str = "遍历整个数据库 >>>> "; |
||||||
|
break; |
||||||
|
case ROW_ID: |
||||||
|
str = "查询RowId >>> "; |
||||||
|
break; |
||||||
|
case RELATION: |
||||||
|
str = "查询关联表 >>> "; |
||||||
|
break; |
||||||
|
case DROP_TABLE: |
||||||
|
str = "删除表 >>> "; |
||||||
|
break; |
||||||
|
} |
||||||
|
ALog.d(TAG, str.concat(sql)); |
||||||
|
} |
||||||
|
|
||||||
|
String getCacheKey(DbEntity dbEntity) { |
||||||
|
return dbEntity.getClass().getName() + "_" + dbEntity.rowID; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查list参数是否合法,list只能是{@code List<String>} |
||||||
|
* |
||||||
|
* @return {@code true} 合法 |
||||||
|
*/ |
||||||
|
boolean checkList(Field list) { |
||||||
|
Class t = CommonUtil.getListParamType(list); |
||||||
|
if (t != null && t == String.class) { |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
ALog.d(TAG, "map参数错误,支持List<String>的参数字段"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查map参数是否合法,map只能是{@code Map<String, String>} |
||||||
|
* |
||||||
|
* @return {@code true} 合法 |
||||||
|
*/ |
||||||
|
boolean checkMap(Field map) { |
||||||
|
Class[] ts = CommonUtil.getMapParamType(map); |
||||||
|
if (ts != null |
||||||
|
&& ts[0] != null |
||||||
|
&& ts[1] != null |
||||||
|
&& ts[0] == String.class |
||||||
|
&& ts[1] == String.class) { |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
ALog.d(TAG, "map参数错误,支持Map<String,String>的参数字段"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 为了防止特殊字符串导致存储失败,需要使用URL编码保存的字符串 |
||||||
|
* |
||||||
|
* @param value 需要保存的内容 |
||||||
|
* @return 转换后的内容 |
||||||
|
*/ |
||||||
|
String convertValue(String value) { |
||||||
|
if (value.contains("'")) { |
||||||
|
return URLEncoder.encode(value); |
||||||
|
} |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
void closeCursor(Cursor cursor) { |
||||||
|
if (cursor != null && !cursor.isClosed()) { |
||||||
|
try { |
||||||
|
cursor.close(); |
||||||
|
} catch (android.database.SQLException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void close(SQLiteDatabase db) { |
||||||
|
//if (db != null && db.isOpen()) db.close();
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查数据库是否关闭,已经关闭的话,打开数据库 |
||||||
|
* |
||||||
|
* @return 返回数据库 |
||||||
|
*/ |
||||||
|
SQLiteDatabase checkDb(SQLiteDatabase db) { |
||||||
|
if (db == null || !db.isOpen()) { |
||||||
|
db = SqlHelper.INSTANCE.getWritableDatabase(); |
||||||
|
} |
||||||
|
return db; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package com.arialyy.aria.orm; |
||||||
|
|
||||||
|
import com.arialyy.aria.orm.annotation.Foreign; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by laoyuyu on 2018/3/22. |
||||||
|
* on update 或 on delete 都可跟不同action功能 |
||||||
|
* |
||||||
|
* @see <a href="https://sqlite.org/foreignkeys.html"></a> |
||||||
|
* {@link Foreign#onDelete()}、{@link Foreign#onUpdate()} |
||||||
|
*/ |
||||||
|
public enum ActionPolicy { |
||||||
|
|
||||||
|
/** |
||||||
|
* 如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作 |
||||||
|
*/ |
||||||
|
NO_ACTION("NO ACTION"), |
||||||
|
|
||||||
|
/** |
||||||
|
* 和NO ACTION 作用一致,和NO ACTION的区别是: |
||||||
|
* 主表update/delete执行时,马上就触发约束; |
||||||
|
* 而NO ACTION 是执行完成语句后才触发约束, |
||||||
|
*/ |
||||||
|
RESTRICT("RESTRICT"), |
||||||
|
|
||||||
|
/** |
||||||
|
* 在父表上update/delete记录时,将子表上匹配记录的列设为null (要注意子表的外键列不能为not null) |
||||||
|
*/ |
||||||
|
SET_NULL("SET NULL"), |
||||||
|
|
||||||
|
/** |
||||||
|
* 父表有变更时,子表将外键列设置成一个默认的值,default配置的值 |
||||||
|
*/ |
||||||
|
SET_DEFAULT("SET DEFAULT"), |
||||||
|
|
||||||
|
/** |
||||||
|
* 在父表上update/delete记录时,同步update/delete掉子表的匹配记录 |
||||||
|
*/ |
||||||
|
CASCADE("CASCADE"); |
||||||
|
|
||||||
|
String function; |
||||||
|
|
||||||
|
ActionPolicy(String function) { |
||||||
|
this.function = function; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,110 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package com.arialyy.aria.orm; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.ContextWrapper; |
||||||
|
import android.database.DatabaseErrorHandler; |
||||||
|
import android.database.sqlite.SQLiteDatabase; |
||||||
|
import android.os.Environment; |
||||||
|
import java.io.File; |
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* 保存在sd卡的数据库使用的Context |
||||||
|
*/ |
||||||
|
class DatabaseContext extends ContextWrapper { |
||||||
|
public DatabaseContext(Context context) { |
||||||
|
super(context); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获得数据库路径,如果不存在,则创建对象对象 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public File getDatabasePath(String name) { |
||||||
|
//判断是否存在sd卡
|
||||||
|
boolean sdExist = android.os.Environment.MEDIA_MOUNTED.equals( |
||||||
|
android.os.Environment.getExternalStorageState()); |
||||||
|
if (!sdExist) { |
||||||
|
return null; |
||||||
|
} else { |
||||||
|
//获取sd卡路径
|
||||||
|
File file = getBaseContext().getExternalFilesDir(null); |
||||||
|
String dbDir; |
||||||
|
if (file != null) { |
||||||
|
dbDir = file.getPath() + "/"; |
||||||
|
} else { |
||||||
|
dbDir = Environment.getExternalStorageDirectory().getPath() |
||||||
|
+ "/Android/data/" |
||||||
|
+ getBaseContext().getPackageName() |
||||||
|
+ "/files/"; |
||||||
|
} |
||||||
|
|
||||||
|
dbDir += "DB";//数据库所在目录
|
||||||
|
String dbPath = dbDir + "/" + name;//数据库路径
|
||||||
|
//判断目录是否存在,不存在则创建该目录
|
||||||
|
File dirFile = new File(dbDir); |
||||||
|
if (!dirFile.exists()) { |
||||||
|
dirFile.mkdirs(); |
||||||
|
} |
||||||
|
|
||||||
|
//数据库文件是否创建成功
|
||||||
|
boolean isFileCreateSuccess = false; |
||||||
|
//判断文件是否存在,不存在则创建该文件
|
||||||
|
File dbFile = new File(dbPath); |
||||||
|
if (!dbFile.exists()) { |
||||||
|
try { |
||||||
|
isFileCreateSuccess = dbFile.createNewFile();//创建文件
|
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
isFileCreateSuccess = true; |
||||||
|
} |
||||||
|
|
||||||
|
//返回数据库文件对象
|
||||||
|
if (isFileCreateSuccess) { |
||||||
|
return dbFile; |
||||||
|
} else { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 重载这个方法,是用来打开SD卡上的数据库的,android 2.3及以下会调用这个方法。 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public SQLiteDatabase openOrCreateDatabase(String name, int mode, |
||||||
|
SQLiteDatabase.CursorFactory factory) { |
||||||
|
return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Android 4.0会调用此方法获取数据库。 |
||||||
|
* |
||||||
|
* @see android.content.ContextWrapper#openOrCreateDatabase(java.lang.String, int, |
||||||
|
* android.database.sqlite.SQLiteDatabase.CursorFactory, |
||||||
|
* android.database.DatabaseErrorHandler) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public SQLiteDatabase openOrCreateDatabase(String name, int mode, |
||||||
|
SQLiteDatabase.CursorFactory factory, |
||||||
|
DatabaseErrorHandler errorHandler) { |
||||||
|
return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null); |
||||||
|
} |
||||||
|
} |
@ -1,249 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package com.arialyy.aria.orm; |
|
||||||
|
|
||||||
import android.app.Application; |
|
||||||
import android.content.Context; |
|
||||||
import android.database.Cursor; |
|
||||||
import android.database.sqlite.SQLiteDatabase; |
|
||||||
import android.support.annotation.NonNull; |
|
||||||
import com.arialyy.aria.core.AriaManager; |
|
||||||
import com.arialyy.aria.util.ALog; |
|
||||||
import com.arialyy.aria.util.CheckUtil; |
|
||||||
import com.arialyy.aria.util.CommonUtil; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
/** |
|
||||||
* Created by lyy on 2015/2/11. |
|
||||||
* 数据库操作工具 |
|
||||||
*/ |
|
||||||
public class DbUtil { |
|
||||||
private static final String TAG = "DbUtil"; |
|
||||||
private volatile static DbUtil INSTANCE = null; |
|
||||||
private int ROW_ID = 7; |
|
||||||
private SQLiteDatabase mDb; |
|
||||||
private SqlHelper mHelper; |
|
||||||
|
|
||||||
private DbUtil() { |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
private DbUtil(Context context) { |
|
||||||
mHelper = SqlHelper.init(context.getApplicationContext()); |
|
||||||
} |
|
||||||
|
|
||||||
public static DbUtil init(Context context) { |
|
||||||
if (context instanceof Application) { |
|
||||||
synchronized (AriaManager.LOCK) { |
|
||||||
if (INSTANCE == null) { |
|
||||||
INSTANCE = new DbUtil(context); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return INSTANCE; |
|
||||||
} |
|
||||||
|
|
||||||
protected static DbUtil getInstance() { |
|
||||||
if (INSTANCE == null) { |
|
||||||
throw new NullPointerException("请在Application中调用init进行数据库工具注册注册"); |
|
||||||
} |
|
||||||
return INSTANCE; |
|
||||||
} |
|
||||||
|
|
||||||
///**
|
|
||||||
// * 关键字模糊检索全文
|
|
||||||
// *
|
|
||||||
// * @param column 需要查找的列
|
|
||||||
// * @param mathSql 关键字语法,exsimple “white OR green”、“blue AND red”、“white NOT green”
|
|
||||||
// */
|
|
||||||
//public <T extends DbEntity> List<T> searchData(Class<T> clazz, String column, String mathSql) {
|
|
||||||
// checkDb();
|
|
||||||
// return SqlHelper.searchData(mDb, clazz, column, mathSql);
|
|
||||||
//}
|
|
||||||
|
|
||||||
/** |
|
||||||
* 检查某个字段的值是否存在 |
|
||||||
* |
|
||||||
* @param expression 字段和值"url=xxx" |
|
||||||
* @return {@code true}该字段的对应的value已存在 |
|
||||||
*/ |
|
||||||
synchronized boolean checkDataExist(Class clazz, String... expression) { |
|
||||||
checkDb(); |
|
||||||
return SqlHelper.checkDataExist(mDb, clazz, expression); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 清空表数据 |
|
||||||
*/ |
|
||||||
synchronized <T extends DbEntity> void clean(Class<T> clazz) { |
|
||||||
checkDb(); |
|
||||||
String tableName = CommonUtil.getClassName(clazz); |
|
||||||
if (tableExists(clazz)) { |
|
||||||
String sql = "DELETE FROM " + tableName; |
|
||||||
exeSql(sql); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 执行sql语句 |
|
||||||
*/ |
|
||||||
void exeSql(String sql) { |
|
||||||
mDb.execSQL(sql); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 删除某条数据 |
|
||||||
*/ |
|
||||||
synchronized <T extends DbEntity> void delData(Class<T> clazz, String... expression) { |
|
||||||
CheckUtil.checkSqlExpression(expression); |
|
||||||
checkDb(); |
|
||||||
SqlHelper.delData(mDb, clazz, expression); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 修改某行数据 |
|
||||||
*/ |
|
||||||
synchronized void modifyData(DbEntity dbEntity) { |
|
||||||
checkDb(); |
|
||||||
SqlHelper.modifyData(mDb, dbEntity); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 遍历所有数据 |
|
||||||
*/ |
|
||||||
synchronized <T extends DbEntity> List<T> findAllData(Class<T> clazz) { |
|
||||||
checkDb(); |
|
||||||
return SqlHelper.findAllData(mDb, clazz); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 条件查寻数据 |
|
||||||
*/ |
|
||||||
synchronized <T extends DbEntity> List<T> findData(Class<T> clazz, String... expression) { |
|
||||||
checkDb(); |
|
||||||
return SqlHelper.findData(mDb, clazz, expression); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 通过rowId判断数据是否存在 |
|
||||||
*/ |
|
||||||
synchronized <T extends DbEntity> boolean isExist(Class<T> clazz, int rowId) { |
|
||||||
checkDb(); |
|
||||||
String sql = "SELECT rowid FROM " + CommonUtil.getClassName(clazz) + " WHERE rowid=" + rowId; |
|
||||||
Cursor cursor = mDb.rawQuery(sql, null); |
|
||||||
boolean isExist = cursor.getCount() > 0; |
|
||||||
cursor.close(); |
|
||||||
return isExist; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 条件查寻数据 |
|
||||||
*/ |
|
||||||
@Deprecated synchronized <T extends DbEntity> List<T> findData(Class<T> clazz, |
|
||||||
@NonNull String[] wheres, @NonNull String[] values) { |
|
||||||
checkDb(); |
|
||||||
return SqlHelper.findData(mDb, clazz, wheres, values); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 插入数据 |
|
||||||
*/ |
|
||||||
synchronized void insertData(DbEntity dbEntity) { |
|
||||||
checkDb(); |
|
||||||
SqlHelper.insertData(mDb, dbEntity); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 查找某张表是否存在 |
|
||||||
*/ |
|
||||||
synchronized boolean tableExists(Class clazz) { |
|
||||||
checkDb(); |
|
||||||
return SqlHelper.tableExists(mDb, clazz); |
|
||||||
} |
|
||||||
|
|
||||||
synchronized void createTable(Class clazz, String tableName) { |
|
||||||
checkDb(); |
|
||||||
SqlHelper.createTable(mDb, clazz, tableName); |
|
||||||
} |
|
||||||
|
|
||||||
private void checkDb() { |
|
||||||
if (mDb == null || !mDb.isOpen()) { |
|
||||||
mDb = mHelper.getReadableDatabase(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 创建表 |
|
||||||
*/ |
|
||||||
private synchronized void createTable(Class clazz) { |
|
||||||
createTable(clazz, null); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 关闭数据库 |
|
||||||
*/ |
|
||||||
private synchronized void close() { |
|
||||||
if (mDb != null) { |
|
||||||
mDb.close(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取所在行Id |
|
||||||
*/ |
|
||||||
synchronized int[] getRowId(Class clazz) { |
|
||||||
checkDb(); |
|
||||||
Cursor cursor = mDb.rawQuery("SELECT rowid, * FROM " + CommonUtil.getClassName(clazz), null); |
|
||||||
int[] ids = new int[cursor.getCount()]; |
|
||||||
int i = 0; |
|
||||||
while (cursor.moveToNext()) { |
|
||||||
ids[i] = cursor.getInt(cursor.getColumnIndex("rowid")); |
|
||||||
i++; |
|
||||||
} |
|
||||||
cursor.close(); |
|
||||||
close(); |
|
||||||
return ids; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取行Id |
|
||||||
*/ |
|
||||||
synchronized int getRowId(Class clazz, Object[] wheres, Object[] values) { |
|
||||||
checkDb(); |
|
||||||
if (wheres.length <= 0 || values.length <= 0) { |
|
||||||
ALog.e(TAG, "请输入删除条件"); |
|
||||||
return -1; |
|
||||||
} else if (wheres.length != values.length) { |
|
||||||
ALog.e(TAG, "groupName 和 vaule 长度不相等"); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
StringBuilder sb = new StringBuilder(); |
|
||||||
sb.append("SELECT rowid FROM ").append(CommonUtil.getClassName(clazz)).append(" WHERE "); |
|
||||||
int i = 0; |
|
||||||
for (Object where : wheres) { |
|
||||||
sb.append(where).append("=").append("'").append(values[i]).append("'"); |
|
||||||
sb.append(i >= wheres.length - 1 ? "" : ","); |
|
||||||
i++; |
|
||||||
} |
|
||||||
SqlHelper.print(ROW_ID, sb.toString()); |
|
||||||
Cursor c = mDb.rawQuery(sb.toString(), null); |
|
||||||
int id = c.getColumnIndex("rowid"); |
|
||||||
c.close(); |
|
||||||
close(); |
|
||||||
return id; |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,221 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package com.arialyy.aria.orm; |
||||||
|
|
||||||
|
import android.database.Cursor; |
||||||
|
import android.database.sqlite.SQLiteDatabase; |
||||||
|
import android.text.TextUtils; |
||||||
|
import com.arialyy.aria.orm.annotation.Default; |
||||||
|
import com.arialyy.aria.orm.annotation.Foreign; |
||||||
|
import com.arialyy.aria.orm.annotation.Primary; |
||||||
|
import com.arialyy.aria.util.CheckUtil; |
||||||
|
import com.arialyy.aria.util.CommonUtil; |
||||||
|
import java.lang.reflect.Field; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by laoyuyu on 2018/3/22. |
||||||
|
* 通用委托,创建表,检查字段 |
||||||
|
*/ |
||||||
|
class DelegateCommon extends AbsDelegate { |
||||||
|
private DelegateCommon() { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除指定的表 |
||||||
|
*/ |
||||||
|
void dropTable(SQLiteDatabase db, String tableName) { |
||||||
|
db = checkDb(db); |
||||||
|
String deleteSQL = "DROP TABLE IF EXISTS ".concat(tableName); |
||||||
|
print(DROP_TABLE, deleteSQL); |
||||||
|
//db.beginTransaction();
|
||||||
|
db.execSQL(deleteSQL); |
||||||
|
//db.setTransactionSuccessful();
|
||||||
|
//db.endTransaction();
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 清空表数据 |
||||||
|
*/ |
||||||
|
<T extends DbEntity> void clean(SQLiteDatabase db, Class<T> clazz) { |
||||||
|
db = checkDb(db); |
||||||
|
String tableName = CommonUtil.getClassName(clazz); |
||||||
|
if (tableExists(db, clazz)) { |
||||||
|
String sql = "DELETE FROM " + tableName; |
||||||
|
db.execSQL(sql); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 查找表是否存在 |
||||||
|
* |
||||||
|
* @param clazz 数据库实体 |
||||||
|
* @return true,该数据库实体对应的表存在;false,不存在 |
||||||
|
*/ |
||||||
|
boolean tableExists(SQLiteDatabase db, Class clazz) { |
||||||
|
return tableExists(db, CommonUtil.getClassName(clazz)); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean tableExists(SQLiteDatabase db, String tableName) { |
||||||
|
db = checkDb(db); |
||||||
|
Cursor cursor = null; |
||||||
|
try { |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
sb.append("SELECT COUNT(*) AS c FROM sqlite_master WHERE type='table' AND name='"); |
||||||
|
sb.append(tableName); |
||||||
|
sb.append("'"); |
||||||
|
print(TABLE_EXISTS, sb.toString()); |
||||||
|
cursor = db.rawQuery(sb.toString(), null); |
||||||
|
if (cursor != null && cursor.moveToNext()) { |
||||||
|
int count = cursor.getInt(0); |
||||||
|
if (count > 0) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} finally { |
||||||
|
closeCursor(cursor); |
||||||
|
close(db); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查某个字段的值是否存在 |
||||||
|
* |
||||||
|
* @param expression 字段和值"url=xxx" |
||||||
|
* @return {@code true}该字段的对应的value已存在 |
||||||
|
*/ |
||||||
|
boolean checkDataExist(SQLiteDatabase db, Class clazz, String... expression) { |
||||||
|
db = checkDb(db); |
||||||
|
CheckUtil.checkSqlExpression(expression); |
||||||
|
String sql = |
||||||
|
"SELECT rowid, * FROM " + CommonUtil.getClassName(clazz) + " WHERE " + expression[0] + " "; |
||||||
|
sql = sql.replace("?", "%s"); |
||||||
|
Object[] params = new String[expression.length - 1]; |
||||||
|
for (int i = 0, len = params.length; i < len; i++) { |
||||||
|
params[i] = "'" + expression[i + 1] + "'"; |
||||||
|
} |
||||||
|
sql = String.format(sql, params); |
||||||
|
print(FIND_DATA, sql); |
||||||
|
Cursor cursor = db.rawQuery(sql, null); |
||||||
|
final boolean isExist = cursor.getCount() > 0; |
||||||
|
closeCursor(cursor); |
||||||
|
close(db); |
||||||
|
return isExist; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建表 |
||||||
|
* |
||||||
|
* @param clazz 数据库实体 |
||||||
|
*/ |
||||||
|
void createTable(SQLiteDatabase db, Class clazz) { |
||||||
|
db = checkDb(db); |
||||||
|
List<Field> fields = CommonUtil.getAllFields(clazz); |
||||||
|
if (fields != null && fields.size() > 0) { |
||||||
|
//外键Map,在Sqlite3中foreign修饰的字段必须放在最后
|
||||||
|
final List<Field> foreignArray = new ArrayList<>(); |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
sb.append("CREATE TABLE ") |
||||||
|
.append(CommonUtil.getClassName(clazz)) |
||||||
|
.append(" ("); |
||||||
|
for (Field field : fields) { |
||||||
|
field.setAccessible(true); |
||||||
|
if (SqlUtil.isIgnore(field)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
Class<?> type = field.getType(); |
||||||
|
sb.append(field.getName()); |
||||||
|
if (type == String.class || type.isEnum()) { |
||||||
|
sb.append(" VARCHAR"); |
||||||
|
} else if (type == int.class || type == Integer.class) { |
||||||
|
sb.append(" INTEGER"); |
||||||
|
} else if (type == float.class || type == Float.class) { |
||||||
|
sb.append(" FLOAT"); |
||||||
|
} else if (type == double.class || type == Double.class) { |
||||||
|
sb.append(" DOUBLE"); |
||||||
|
} else if (type == long.class || type == Long.class) { |
||||||
|
sb.append(" BIGINT"); |
||||||
|
} else if (type == boolean.class || type == Boolean.class) { |
||||||
|
sb.append(" BOOLEAN"); |
||||||
|
} else if (type == java.util.Date.class || type == java.sql.Date.class) { |
||||||
|
sb.append(" DATA"); |
||||||
|
} else if (type == byte.class || type == Byte.class) { |
||||||
|
sb.append(" BLOB"); |
||||||
|
} else if (type == Map.class || type == List.class) { |
||||||
|
sb.append(" TEXT"); |
||||||
|
} else { |
||||||
|
continue; |
||||||
|
} |
||||||
|
if (SqlUtil.isPrimary(field)) { |
||||||
|
Primary pk = field.getAnnotation(Primary.class); |
||||||
|
sb.append(" PRIMARY KEY"); |
||||||
|
if (pk.autoincrement() && (type == int.class || type == Integer.class)) { |
||||||
|
sb.append(" AUTOINCREMENT"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (SqlUtil.isForeign(field)) { |
||||||
|
foreignArray.add(field); |
||||||
|
} |
||||||
|
|
||||||
|
if (SqlUtil.isNoNull(field)) { |
||||||
|
sb.append(" NOT NULL"); |
||||||
|
} |
||||||
|
|
||||||
|
if (SqlUtil.isDefault(field)) { |
||||||
|
Default d = field.getAnnotation(Default.class); |
||||||
|
if (!TextUtils.isEmpty(d.value())) { |
||||||
|
sb.append(" DEFAULT ").append("'").append(d.value()).append("'"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
sb.append(","); |
||||||
|
} |
||||||
|
|
||||||
|
for (Field field : foreignArray) { |
||||||
|
Foreign foreign = field.getAnnotation(Foreign.class); |
||||||
|
sb.append("FOREIGN KEY (") |
||||||
|
.append(field.getName()) |
||||||
|
.append(") REFERENCES ") |
||||||
|
.append(CommonUtil.getClassName(foreign.parent())) |
||||||
|
.append("(") |
||||||
|
.append(foreign.column()) |
||||||
|
.append(")"); |
||||||
|
ActionPolicy update = foreign.onUpdate(); |
||||||
|
ActionPolicy delete = foreign.onDelete(); |
||||||
|
if (update != ActionPolicy.NO_ACTION) { |
||||||
|
sb.append(" ON UPDATE ").append(update.function); |
||||||
|
} |
||||||
|
|
||||||
|
if (delete != ActionPolicy.NO_ACTION) { |
||||||
|
sb.append(" ON DELETE ").append(update.function); |
||||||
|
} |
||||||
|
sb.append(","); |
||||||
|
} |
||||||
|
|
||||||
|
String str = sb.toString(); |
||||||
|
str = str.substring(0, str.length() - 1) + ");"; |
||||||
|
print(CREATE_TABLE, str); |
||||||
|
db.execSQL(str); |
||||||
|
} |
||||||
|
close(db); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,512 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package com.arialyy.aria.orm; |
||||||
|
|
||||||
|
import android.annotation.TargetApi; |
||||||
|
import android.database.Cursor; |
||||||
|
import android.database.sqlite.SQLiteDatabase; |
||||||
|
import android.os.Build; |
||||||
|
import android.text.TextUtils; |
||||||
|
import com.arialyy.aria.orm.annotation.Many; |
||||||
|
import com.arialyy.aria.orm.annotation.One; |
||||||
|
import com.arialyy.aria.orm.annotation.Wrapper; |
||||||
|
import com.arialyy.aria.util.ALog; |
||||||
|
import com.arialyy.aria.util.CheckUtil; |
||||||
|
import com.arialyy.aria.util.CommonUtil; |
||||||
|
import java.lang.reflect.Field; |
||||||
|
import java.net.URLDecoder; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Set; |
||||||
|
import java.util.WeakHashMap; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by laoyuyu on 2018/3/22. |
||||||
|
* 查询数据 |
||||||
|
*/ |
||||||
|
class DelegateFind extends AbsDelegate { |
||||||
|
private final String PARENT_COLUMN_ALIAS = "p"; |
||||||
|
private final String CHILD_COLUMN_ALIAS = "c"; |
||||||
|
|
||||||
|
private DelegateFind() { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 查找一对多的关联数据 |
||||||
|
* 如果查找不到数据或实体没有被{@link Wrapper}注解,将返回null |
||||||
|
* 如果实体中没有{@link One}或{@link Many}注解,将返回null |
||||||
|
* 如果实体中有多个{@link One}或{@link Many}注解,将返回nul |
||||||
|
*/ |
||||||
|
<T extends AbsWrapper> List<T> findRelationData(SQLiteDatabase db, Class<T> clazz, |
||||||
|
String... expression) { |
||||||
|
db = checkDb(db); |
||||||
|
|
||||||
|
if (SqlUtil.isWrapper(clazz)) { |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
Field[] fields = clazz.getDeclaredFields(); |
||||||
|
Field one = null, many = null; |
||||||
|
boolean hasOne = false, hasMany = false; |
||||||
|
for (Field field : fields) { |
||||||
|
if (SqlUtil.isOne(field)) { |
||||||
|
if (hasOne) { |
||||||
|
ALog.w(TAG, "查询数据失败,实体中有多个@One 注解"); |
||||||
|
return null; |
||||||
|
} |
||||||
|
hasOne = true; |
||||||
|
one = field; |
||||||
|
} |
||||||
|
if (SqlUtil.isMany(field)) { |
||||||
|
if (hasMany) { |
||||||
|
ALog.w(TAG, "查询数据失败,实体中有多个@Many 注解"); |
||||||
|
return null; |
||||||
|
} |
||||||
|
hasMany = true; |
||||||
|
many = field; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (one == null || many == null) { |
||||||
|
ALog.w(TAG, "查询数据失败,实体中没有@One或@Many注解"); |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
if (many.getType() != List.class) { |
||||||
|
ALog.w(TAG, "查询数据失败,@Many注解的字段必须是List"); |
||||||
|
return null; |
||||||
|
} |
||||||
|
try { |
||||||
|
Many m = many.getAnnotation(Many.class); |
||||||
|
Class parentClazz = Class.forName(one.getType().getName()); |
||||||
|
Class childClazz = Class.forName(CommonUtil.getListParamType(many).getName()); |
||||||
|
final String pTableName = parentClazz.getSimpleName(); |
||||||
|
final String cTableName = childClazz.getSimpleName(); |
||||||
|
List<Field> pColumn = SqlUtil.getAllNotIgnoreField(parentClazz); |
||||||
|
List<Field> cColumn = SqlUtil.getAllNotIgnoreField(childClazz); |
||||||
|
List<String> pColumnAlias = new ArrayList<>(); |
||||||
|
List<String> cColumnAlias = new ArrayList<>(); |
||||||
|
StringBuilder pSb = new StringBuilder(); |
||||||
|
StringBuilder cSb = new StringBuilder(); |
||||||
|
|
||||||
|
if (pColumn != null) { |
||||||
|
pSb.append(pTableName.concat(".rowid AS ").concat(PARENT_COLUMN_ALIAS).concat("rowid,")); |
||||||
|
for (Field f : pColumn) { |
||||||
|
String temp = PARENT_COLUMN_ALIAS.concat(f.getName()); |
||||||
|
pColumnAlias.add(temp); |
||||||
|
pSb.append(pTableName.concat(".").concat(f.getName())) |
||||||
|
.append(" AS ") |
||||||
|
.append(temp) |
||||||
|
.append(","); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (cColumn != null) { |
||||||
|
pSb.append(cTableName.concat(".rowid AS ").concat(CHILD_COLUMN_ALIAS).concat("rowid,")); |
||||||
|
for (Field f : cColumn) { |
||||||
|
String temp = CHILD_COLUMN_ALIAS.concat(f.getName()); |
||||||
|
cColumnAlias.add(temp); |
||||||
|
cSb.append(cTableName.concat(".").concat(f.getName())) |
||||||
|
.append(" AS ") |
||||||
|
.append(temp) |
||||||
|
.append(","); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
String pColumnAlia = pSb.toString(); |
||||||
|
String cColumnAlia = cSb.toString(); |
||||||
|
if (!TextUtils.isEmpty(pColumnAlia)) { |
||||||
|
pColumnAlia = pColumnAlia.substring(0, pColumnAlia.length() - 1); |
||||||
|
} |
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(cColumnAlia)) { |
||||||
|
cColumnAlia = cColumnAlia.substring(0, cColumnAlia.length() - 1); |
||||||
|
} |
||||||
|
|
||||||
|
sb.append("SELECT "); |
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(pColumnAlia)) { |
||||||
|
sb.append(pColumnAlia).append(","); |
||||||
|
} |
||||||
|
if (!TextUtils.isEmpty(cColumnAlia)) { |
||||||
|
sb.append(cColumnAlia); |
||||||
|
} |
||||||
|
if (TextUtils.isEmpty(pColumnAlia) && TextUtils.isEmpty(cColumnAlia)) { |
||||||
|
sb.append(" * "); |
||||||
|
} |
||||||
|
|
||||||
|
sb.append(" FROM ") |
||||||
|
.append(pTableName) |
||||||
|
.append(" INNER JOIN ") |
||||||
|
.append(cTableName) |
||||||
|
.append(" ON ") |
||||||
|
.append(pTableName.concat(".").concat(m.parentColumn())) |
||||||
|
.append(" = ") |
||||||
|
.append(cTableName.concat(".").concat(m.entityColumn())); |
||||||
|
String sql; |
||||||
|
if (expression != null && expression.length > 0) { |
||||||
|
CheckUtil.checkSqlExpression(expression); |
||||||
|
sb.append(" WHERE ").append(expression[0]).append(" "); |
||||||
|
sql = sb.toString(); |
||||||
|
sql = sql.replace("?", "%s"); |
||||||
|
Object[] params = new String[expression.length - 1]; |
||||||
|
for (int i = 0, len = params.length; i < len; i++) { |
||||||
|
params[i] = "'" + convertValue(expression[i + 1]) + "'"; |
||||||
|
} |
||||||
|
sql = String.format(sql, params); |
||||||
|
} else { |
||||||
|
sql = sb.toString(); |
||||||
|
} |
||||||
|
print(RELATION, sql); |
||||||
|
Cursor cursor = db.rawQuery(sql, null); |
||||||
|
List<T> data = |
||||||
|
(List<T>) newInstanceEntity(clazz, parentClazz, childClazz, cursor, pColumn, cColumn, |
||||||
|
pColumnAlias, cColumnAlias); |
||||||
|
closeCursor(cursor); |
||||||
|
close(db); |
||||||
|
return data; |
||||||
|
} catch (ClassNotFoundException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
ALog.w(TAG, "查询数据失败,实体类没有使用@Wrapper 注解"); |
||||||
|
return null; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建关联查询的数据 |
||||||
|
* |
||||||
|
* @param pColumn 父表的所有字段 |
||||||
|
* @param cColumn 字表的所有字段 |
||||||
|
* @param pColumnAlias 关联查询父表别名 |
||||||
|
* @param cColumnAlias 关联查询子表别名 |
||||||
|
*/ |
||||||
|
private <T extends AbsWrapper, P extends DbEntity, C extends DbEntity> List<T> newInstanceEntity( |
||||||
|
Class<T> clazz, Class<P> parent, |
||||||
|
Class<C> child, |
||||||
|
Cursor cursor, |
||||||
|
List<Field> pColumn, List<Field> cColumn, |
||||||
|
List<String> pColumnAlias, List<String> cColumnAlias) { |
||||||
|
try { |
||||||
|
String parentPrimary = ""; //父表主键别名
|
||||||
|
for (Field f : pColumn) { |
||||||
|
if (SqlUtil.isPrimary(f)) { |
||||||
|
parentPrimary = PARENT_COLUMN_ALIAS.concat(f.getName()); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
List<T> wrappers = new ArrayList<>(); |
||||||
|
Map<Object, P> tempParent = new WeakHashMap<>(); // 所有父表元素,key为父表主键的值
|
||||||
|
Map<Object, List<C>> tempChild = new WeakHashMap<>(); // 所有的字表元素,key为父表主键的值
|
||||||
|
|
||||||
|
Object old = null; |
||||||
|
while (cursor.moveToNext()) { |
||||||
|
//创建父实体
|
||||||
|
Object ppValue = setPPValue(parentPrimary, cursor); |
||||||
|
if (old == null || ppValue != old) { //当主键不同时,表示是不同的父表数据
|
||||||
|
old = ppValue; |
||||||
|
if (tempParent.get(old) == null) { |
||||||
|
P pEntity = parent.newInstance(); |
||||||
|
String pPrimaryName = ""; |
||||||
|
for (int i = 0, len = pColumnAlias.size(); i < len; i++) { |
||||||
|
Field pField = pColumn.get(i); |
||||||
|
pField.setAccessible(true); |
||||||
|
Class<?> type = pField.getType(); |
||||||
|
int column = cursor.getColumnIndex(pColumnAlias.get(i)); |
||||||
|
if (column == -1) continue; |
||||||
|
setFieldValue(type, pField, column, cursor, pEntity); |
||||||
|
|
||||||
|
if (SqlUtil.isPrimary(pField) && (type == int.class || type == Integer.class)) { |
||||||
|
pPrimaryName = pField.getName(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//当设置了主键,而且主键的类型为integer时,查询RowID等于主键
|
||||||
|
pEntity.rowID = cursor.getInt( |
||||||
|
cursor.getColumnIndex( |
||||||
|
TextUtils.isEmpty(pPrimaryName) ? PARENT_COLUMN_ALIAS.concat("rowid") |
||||||
|
: pPrimaryName)); |
||||||
|
|
||||||
|
tempParent.put(ppValue, pEntity); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 创建子实体
|
||||||
|
C cEntity = child.newInstance(); |
||||||
|
String cPrimaryName = ""; |
||||||
|
for (int i = 0, len = cColumnAlias.size(); i < len; i++) { |
||||||
|
Field cField = cColumn.get(i); |
||||||
|
cField.setAccessible(true); |
||||||
|
Class<?> type = cField.getType(); |
||||||
|
|
||||||
|
int column = cursor.getColumnIndex(cColumnAlias.get(i)); |
||||||
|
if (column == -1) continue; |
||||||
|
setFieldValue(type, cField, column, cursor, cEntity); |
||||||
|
|
||||||
|
if (SqlUtil.isPrimary(cField) && (type == int.class || type == Integer.class)) { |
||||||
|
cPrimaryName = cField.getName(); |
||||||
|
} |
||||||
|
} |
||||||
|
//当设置了主键,而且主键的类型为integer时,查询RowID等于主键
|
||||||
|
cEntity.rowID = cursor.getInt( |
||||||
|
cursor.getColumnIndex( |
||||||
|
TextUtils.isEmpty(cPrimaryName) ? CHILD_COLUMN_ALIAS.concat("rowid") |
||||||
|
: cPrimaryName)); |
||||||
|
if (tempChild.get(old) == null) { |
||||||
|
tempChild.put(old, new ArrayList<C>()); |
||||||
|
} |
||||||
|
tempChild.get(old).add(cEntity); |
||||||
|
} |
||||||
|
|
||||||
|
List<Field> wFields = SqlUtil.getAllNotIgnoreField(clazz); |
||||||
|
if (wFields != null && !wFields.isEmpty()) { |
||||||
|
Set<Object> pKeys = tempParent.keySet(); |
||||||
|
for (Object pk : pKeys) { |
||||||
|
T wrapper = clazz.newInstance(); |
||||||
|
P p = tempParent.get(pk); |
||||||
|
boolean isPSet = false, isCSet = false; |
||||||
|
for (Field f : wFields) { |
||||||
|
if (!isPSet && f.getAnnotation(One.class) != null) { |
||||||
|
f.set(wrapper, p); |
||||||
|
isPSet = true; |
||||||
|
} |
||||||
|
if (!isCSet && f.getAnnotation(Many.class) != null) { |
||||||
|
f.set(wrapper, tempChild.get(pk)); |
||||||
|
isCSet = true; |
||||||
|
} |
||||||
|
} |
||||||
|
wrapper.handleConvert(); //处理下转换
|
||||||
|
wrappers.add(wrapper); |
||||||
|
} |
||||||
|
} |
||||||
|
return wrappers; |
||||||
|
} catch (InstantiationException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} catch (IllegalAccessException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取父表主键数据 |
||||||
|
* |
||||||
|
* @param parentPrimary 父表主键别名 |
||||||
|
*/ |
||||||
|
@TargetApi(Build.VERSION_CODES.HONEYCOMB) private Object setPPValue(String parentPrimary, |
||||||
|
Cursor cursor) { |
||||||
|
Object ppValue = null; |
||||||
|
int ppColumn = cursor.getColumnIndex(parentPrimary); //父表主键所在的列
|
||||||
|
int type = cursor.getType(ppColumn); |
||||||
|
switch (type) { |
||||||
|
case Cursor.FIELD_TYPE_INTEGER: |
||||||
|
ppValue = cursor.getLong(ppColumn); |
||||||
|
break; |
||||||
|
case Cursor.FIELD_TYPE_FLOAT: |
||||||
|
ppValue = cursor.getFloat(ppColumn); |
||||||
|
break; |
||||||
|
case Cursor.FIELD_TYPE_STRING: |
||||||
|
ppValue = cursor.getString(ppColumn); |
||||||
|
break; |
||||||
|
} |
||||||
|
return ppValue; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 条件查寻数据 |
||||||
|
*/ |
||||||
|
<T extends DbEntity> List<T> findData(SQLiteDatabase db, Class<T> clazz, String... expression) { |
||||||
|
db = checkDb(db); |
||||||
|
CheckUtil.checkSqlExpression(expression); |
||||||
|
String sql = |
||||||
|
"SELECT rowid, * FROM " + CommonUtil.getClassName(clazz) + " WHERE " + expression[0] + " "; |
||||||
|
sql = sql.replace("?", "%s"); |
||||||
|
Object[] params = new String[expression.length - 1]; |
||||||
|
for (int i = 0, len = params.length; i < len; i++) { |
||||||
|
params[i] = "'" + convertValue(expression[i + 1]) + "'"; |
||||||
|
} |
||||||
|
sql = String.format(sql, params); |
||||||
|
print(FIND_DATA, sql); |
||||||
|
Cursor cursor = db.rawQuery(sql, null); |
||||||
|
List<T> data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null; |
||||||
|
closeCursor(cursor); |
||||||
|
close(db); |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 查找表的所有数据 |
||||||
|
*/ |
||||||
|
<T extends DbEntity> List<T> findAllData(SQLiteDatabase db, Class<T> clazz) { |
||||||
|
db = checkDb(db); |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
sb.append("SELECT rowid, * FROM ").append(CommonUtil.getClassName(clazz)); |
||||||
|
print(FIND_ALL_DATA, sb.toString()); |
||||||
|
Cursor cursor = db.rawQuery(sb.toString(), null); |
||||||
|
List<T> data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null; |
||||||
|
closeCursor(cursor); |
||||||
|
close(db); |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据数据游标创建一个具体的对象 |
||||||
|
*/ |
||||||
|
private <T extends DbEntity> List<T> newInstanceEntity(Class<T> clazz, Cursor cursor) { |
||||||
|
List<Field> fields = CommonUtil.getAllFields(clazz); |
||||||
|
List<T> entitys = new ArrayList<>(); |
||||||
|
if (fields != null && fields.size() > 0) { |
||||||
|
try { |
||||||
|
while (cursor.moveToNext()) { |
||||||
|
T entity = clazz.newInstance(); |
||||||
|
String primaryName = ""; |
||||||
|
for (Field field : fields) { |
||||||
|
field.setAccessible(true); |
||||||
|
if (SqlUtil.isIgnore(field)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
Class<?> type = field.getType(); |
||||||
|
if (SqlUtil.isPrimary(field) && (type == int.class || type == Integer.class)) { |
||||||
|
primaryName = field.getName(); |
||||||
|
} |
||||||
|
|
||||||
|
int column = cursor.getColumnIndex(field.getName()); |
||||||
|
if (column == -1) continue; |
||||||
|
setFieldValue(type, field, column, cursor, entity); |
||||||
|
} |
||||||
|
//当设置了主键,而且主键的类型为integer时,查询RowID等于主键
|
||||||
|
entity.rowID = cursor.getInt( |
||||||
|
cursor.getColumnIndex(TextUtils.isEmpty(primaryName) ? "rowid" : primaryName)); |
||||||
|
mDataCache.put(getCacheKey(entity), entity); |
||||||
|
entitys.add(entity); |
||||||
|
} |
||||||
|
closeCursor(cursor); |
||||||
|
} catch (InstantiationException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} catch (IllegalAccessException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
return entitys; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置字段的值 |
||||||
|
* |
||||||
|
* @throws IllegalAccessException |
||||||
|
*/ |
||||||
|
private void setFieldValue(Class type, Field field, int column, Cursor cursor, Object entity) |
||||||
|
throws IllegalAccessException { |
||||||
|
if (type == String.class) { |
||||||
|
String temp = cursor.getString(column); |
||||||
|
if (!TextUtils.isEmpty(temp)) { |
||||||
|
field.set(entity, URLDecoder.decode(temp)); |
||||||
|
} |
||||||
|
} else if (type == int.class || type == Integer.class) { |
||||||
|
field.setInt(entity, cursor.getInt(column)); |
||||||
|
} else if (type == float.class || type == Float.class) { |
||||||
|
field.setFloat(entity, cursor.getFloat(column)); |
||||||
|
} else if (type == double.class || type == Double.class) { |
||||||
|
field.setDouble(entity, cursor.getDouble(column)); |
||||||
|
} else if (type == long.class || type == Long.class) { |
||||||
|
field.setLong(entity, cursor.getLong(column)); |
||||||
|
} else if (type == boolean.class || type == Boolean.class) { |
||||||
|
String temp = cursor.getString(column); |
||||||
|
if (TextUtils.isEmpty(temp)) { |
||||||
|
field.setBoolean(entity, false); |
||||||
|
} else { |
||||||
|
field.setBoolean(entity, !temp.equalsIgnoreCase("false")); |
||||||
|
} |
||||||
|
} else if (type == java.util.Date.class || type == java.sql.Date.class) { |
||||||
|
field.set(entity, new Date(cursor.getString(column))); |
||||||
|
} else if (type == byte[].class) { |
||||||
|
field.set(entity, cursor.getBlob(column)); |
||||||
|
} else if (type == Map.class) { |
||||||
|
String temp = cursor.getString(column); |
||||||
|
if (!TextUtils.isEmpty(temp)) { |
||||||
|
field.set(entity, SqlUtil.str2Map(temp)); |
||||||
|
} |
||||||
|
} else if (type == List.class) { |
||||||
|
String value = cursor.getString(column); |
||||||
|
if (!TextUtils.isEmpty(value)) { |
||||||
|
field.set(entity, SqlUtil.str2List(value, field)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取所在行Id |
||||||
|
*/ |
||||||
|
int[] getRowId(SQLiteDatabase db, Class clazz) { |
||||||
|
db = checkDb(db); |
||||||
|
Cursor cursor = db.rawQuery("SELECT rowid, * FROM " + CommonUtil.getClassName(clazz), null); |
||||||
|
int[] ids = new int[cursor.getCount()]; |
||||||
|
int i = 0; |
||||||
|
while (cursor.moveToNext()) { |
||||||
|
ids[i] = cursor.getInt(cursor.getColumnIndex("rowid")); |
||||||
|
i++; |
||||||
|
} |
||||||
|
cursor.close(); |
||||||
|
close(db); |
||||||
|
return ids; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取行Id |
||||||
|
*/ |
||||||
|
int getRowId(SQLiteDatabase db, Class clazz, Object[] wheres, Object[] values) { |
||||||
|
db = checkDb(db); |
||||||
|
if (wheres.length <= 0 || values.length <= 0) { |
||||||
|
ALog.e(TAG, "请输入删除条件"); |
||||||
|
return -1; |
||||||
|
} else if (wheres.length != values.length) { |
||||||
|
ALog.e(TAG, "groupName 和 vaule 长度不相等"); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
sb.append("SELECT rowid FROM ").append(CommonUtil.getClassName(clazz)).append(" WHERE "); |
||||||
|
int i = 0; |
||||||
|
for (Object where : wheres) { |
||||||
|
sb.append(where).append("=").append("'").append(values[i]).append("'"); |
||||||
|
sb.append(i >= wheres.length - 1 ? "" : ","); |
||||||
|
i++; |
||||||
|
} |
||||||
|
print(ROW_ID, sb.toString()); |
||||||
|
Cursor c = db.rawQuery(sb.toString(), null); |
||||||
|
int id = c.getColumnIndex("rowid"); |
||||||
|
c.close(); |
||||||
|
close(db); |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 通过rowId判断数据是否存在 |
||||||
|
*/ |
||||||
|
<T extends DbEntity> boolean itemExist(SQLiteDatabase db, Class<T> clazz, |
||||||
|
int rowId) { |
||||||
|
db = checkDb(db); |
||||||
|
String sql = "SELECT rowid FROM " + CommonUtil.getClassName(clazz) + " WHERE rowid=" + rowId; |
||||||
|
print(ROW_ID, sql); |
||||||
|
Cursor cursor = db.rawQuery(sql, null); |
||||||
|
boolean isExist = cursor.getCount() > 0; |
||||||
|
cursor.close(); |
||||||
|
return isExist; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package com.arialyy.aria.orm; |
||||||
|
|
||||||
|
import android.util.SparseArray; |
||||||
|
import java.lang.reflect.Constructor; |
||||||
|
import java.lang.reflect.InvocationTargetException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by laoyuyu on 2018/3/22. |
||||||
|
* Delegate管理器 |
||||||
|
*/ |
||||||
|
class DelegateManager { |
||||||
|
private final String TAG = "ModuleFactory"; |
||||||
|
|
||||||
|
private SparseArray<AbsDelegate> mDelegates = new SparseArray<>(); |
||||||
|
private static volatile DelegateManager INSTANCE = null; |
||||||
|
|
||||||
|
private DelegateManager() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
static DelegateManager getInstance() { |
||||||
|
if (INSTANCE == null) { |
||||||
|
synchronized (DelegateManager.class) { |
||||||
|
INSTANCE = new DelegateManager(); |
||||||
|
} |
||||||
|
} |
||||||
|
return INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取Module |
||||||
|
*/ |
||||||
|
<M extends AbsDelegate> M getDelegate(Class<M> clazz) { |
||||||
|
M delegate = (M) mDelegates.get(clazz.hashCode()); |
||||||
|
try { |
||||||
|
if (delegate == null) { |
||||||
|
Constructor c = clazz.getDeclaredConstructor(); |
||||||
|
c.setAccessible(true); |
||||||
|
delegate = (M) c.newInstance(); |
||||||
|
mDelegates.put(clazz.hashCode(), delegate); |
||||||
|
return delegate; |
||||||
|
} |
||||||
|
} catch (InstantiationException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} catch (IllegalAccessException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} catch (NoSuchMethodException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} catch (InvocationTargetException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
return delegate; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,186 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package com.arialyy.aria.orm; |
||||||
|
|
||||||
|
import android.database.sqlite.SQLiteDatabase; |
||||||
|
import android.text.TextUtils; |
||||||
|
import com.arialyy.aria.orm.annotation.Primary; |
||||||
|
import com.arialyy.aria.util.CheckUtil; |
||||||
|
import com.arialyy.aria.util.CommonUtil; |
||||||
|
import java.lang.reflect.Field; |
||||||
|
import java.lang.reflect.Type; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by laoyuyu on 2018/3/22. |
||||||
|
* 增加数据、更新数据 |
||||||
|
*/ |
||||||
|
class DelegateUpdate extends AbsDelegate { |
||||||
|
private DelegateUpdate() { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除某条数据 |
||||||
|
*/ |
||||||
|
<T extends DbEntity> void delData(SQLiteDatabase db, Class<T> clazz, String... expression) { |
||||||
|
db = checkDb(db); |
||||||
|
CheckUtil.checkSqlExpression(expression); |
||||||
|
|
||||||
|
String sql = "DELETE FROM " + CommonUtil.getClassName(clazz) + " WHERE " + expression[0] + " "; |
||||||
|
sql = sql.replace("?", "%s"); |
||||||
|
Object[] params = new String[expression.length - 1]; |
||||||
|
for (int i = 0, len = params.length; i < len; i++) { |
||||||
|
params[i] = "'" + expression[i + 1] + "'"; |
||||||
|
} |
||||||
|
sql = String.format(sql, params); |
||||||
|
print(DEL_DATA, sql); |
||||||
|
db.execSQL(sql); |
||||||
|
close(db); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 修改某行数据 |
||||||
|
*/ |
||||||
|
void modifyData(SQLiteDatabase db, DbEntity dbEntity) { |
||||||
|
db = checkDb(db); |
||||||
|
Class<?> clazz = dbEntity.getClass(); |
||||||
|
List<Field> fields = CommonUtil.getAllFields(clazz); |
||||||
|
DbEntity cacheEntity = mDataCache.get(getCacheKey(dbEntity)); |
||||||
|
if (fields != null && fields.size() > 0) { |
||||||
|
StringBuilder sql = new StringBuilder(); |
||||||
|
StringBuilder prams = new StringBuilder(); |
||||||
|
sql.append("UPDATE ").append(CommonUtil.getClassName(dbEntity)).append(" SET "); |
||||||
|
int i = 0; |
||||||
|
try { |
||||||
|
for (Field field : fields) { |
||||||
|
field.setAccessible(true); |
||||||
|
if (isIgnore(dbEntity, field)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
if (cacheEntity != null |
||||||
|
&& field.get(dbEntity) == field.get(cacheEntity) |
||||||
|
&& !field.getName().equals("state")) { //在LruCache中 state字段总是不能重新赋值...
|
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
String value; |
||||||
|
prams.append(i > 0 ? ", " : ""); |
||||||
|
prams.append(field.getName()).append("='"); |
||||||
|
Type type = field.getType(); |
||||||
|
if (type == Map.class && checkMap(field)) { |
||||||
|
value = SqlUtil.map2Str((Map<String, String>) field.get(dbEntity)); |
||||||
|
} else if (type == List.class && checkList(field)) { |
||||||
|
value = SqlUtil.list2Str(dbEntity, field); |
||||||
|
} else { |
||||||
|
Object obj = field.get(dbEntity); |
||||||
|
value = obj == null ? "" : convertValue(obj.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
prams.append(TextUtils.isEmpty(value) ? "" : value); |
||||||
|
prams.append("'"); |
||||||
|
i++; |
||||||
|
} |
||||||
|
} catch (IllegalAccessException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
if (!TextUtils.isEmpty(prams.toString())) { |
||||||
|
sql.append(prams.toString()); |
||||||
|
sql.append(" where rowid=").append(dbEntity.rowID); |
||||||
|
print(MODIFY_DATA, sql.toString()); |
||||||
|
db.execSQL(sql.toString()); |
||||||
|
} |
||||||
|
} |
||||||
|
mDataCache.put(getCacheKey(dbEntity), dbEntity); |
||||||
|
close(db); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 插入数据 |
||||||
|
*/ |
||||||
|
void insertData(SQLiteDatabase db, DbEntity dbEntity) { |
||||||
|
db = checkDb(db); |
||||||
|
Class<?> clazz = dbEntity.getClass(); |
||||||
|
List<Field> fields = CommonUtil.getAllFields(clazz); |
||||||
|
if (fields != null && fields.size() > 0) { |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
sb.append("INSERT INTO ").append(CommonUtil.getClassName(dbEntity)).append("("); |
||||||
|
int i = 0; |
||||||
|
try { |
||||||
|
for (Field field : fields) { |
||||||
|
field.setAccessible(true); |
||||||
|
if (isIgnore(dbEntity, field)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
sb.append(i > 0 ? ", " : ""); |
||||||
|
sb.append(field.getName()); |
||||||
|
i++; |
||||||
|
} |
||||||
|
sb.append(") VALUES ("); |
||||||
|
i = 0; |
||||||
|
for (Field field : fields) { |
||||||
|
field.setAccessible(true); |
||||||
|
if (isIgnore(dbEntity, field)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
sb.append(i > 0 ? ", " : ""); |
||||||
|
sb.append("'"); |
||||||
|
Type type = field.getType(); |
||||||
|
if (type == Map.class && checkMap(field)) { |
||||||
|
sb.append(SqlUtil.map2Str((Map<String, String>) field.get(dbEntity))); |
||||||
|
} else if (type == List.class && checkList(field)) { |
||||||
|
sb.append(SqlUtil.list2Str(dbEntity, field)); |
||||||
|
} else { |
||||||
|
Object obj = field.get(dbEntity); |
||||||
|
if (obj != null) { |
||||||
|
sb.append(convertValue(field.get(dbEntity).toString())); |
||||||
|
} |
||||||
|
} |
||||||
|
sb.append("'"); |
||||||
|
i++; |
||||||
|
} |
||||||
|
} catch (IllegalAccessException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
sb.append(")"); |
||||||
|
print(INSERT_DATA, sb.toString()); |
||||||
|
db.execSQL(sb.toString()); |
||||||
|
} |
||||||
|
close(db); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@code true}自动增长的主键和需要忽略的字段 |
||||||
|
*/ |
||||||
|
private boolean isIgnore(Object obj, Field field) throws IllegalAccessException { |
||||||
|
if (SqlUtil.isIgnore(field)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
if (SqlUtil.isPrimary(field)) { //忽略自动增长的主键
|
||||||
|
Primary p = field.getAnnotation(Primary.class); |
||||||
|
if (p.autoincrement()) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
if (SqlUtil.isForeign(field)) { //忽略外键为null的字段
|
||||||
|
Object value = field.get(obj); |
||||||
|
if (value == null || (value instanceof String && TextUtils.isEmpty(String.valueOf(value)))) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,155 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.arialyy.aria.orm; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.database.sqlite.SQLiteDatabase; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by lyy on 2015/2/11. |
||||||
|
* 数据库操作工具 |
||||||
|
*/ |
||||||
|
public class DelegateWrapper { |
||||||
|
private static final String TAG = "DelegateWrapper"; |
||||||
|
private volatile static DelegateWrapper INSTANCE = null; |
||||||
|
|
||||||
|
private SQLiteDatabase mDb; |
||||||
|
private DelegateManager mDManager; |
||||||
|
|
||||||
|
private DelegateWrapper() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private DelegateWrapper(Context context) { |
||||||
|
SqlHelper helper = SqlHelper.init(context.getApplicationContext()); |
||||||
|
mDb = helper.getWritableDatabase(); |
||||||
|
mDManager = DelegateManager.getInstance(); |
||||||
|
} |
||||||
|
|
||||||
|
public static void init(Context context) { |
||||||
|
synchronized (DelegateWrapper.class) { |
||||||
|
if (INSTANCE == null) { |
||||||
|
INSTANCE = new DelegateWrapper(context); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static DelegateWrapper getInstance() { |
||||||
|
if (INSTANCE == null) { |
||||||
|
throw new NullPointerException("请在Application中调用init进行数据库工具注册注册"); |
||||||
|
} |
||||||
|
return INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 查询关联表数据 |
||||||
|
* |
||||||
|
* @param expression 查询条件 |
||||||
|
*/ |
||||||
|
<T extends AbsWrapper> List<T> findRelationData(Class<T> clazz, String... expression) { |
||||||
|
return mDManager.getDelegate(DelegateFind.class).findRelationData(mDb, clazz, expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查某个字段的值是否存在 |
||||||
|
* |
||||||
|
* @param expression 字段和值"url=xxx" |
||||||
|
* @return {@code true}该字段的对应的value已存在 |
||||||
|
*/ |
||||||
|
boolean checkDataExist(Class clazz, String... expression) { |
||||||
|
return mDManager.getDelegate(DelegateCommon.class) |
||||||
|
.checkDataExist(mDb, clazz, expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 清空表数据 |
||||||
|
*/ |
||||||
|
<T extends DbEntity> void clean(Class<T> clazz) { |
||||||
|
mDManager.getDelegate(DelegateCommon.class).clean(mDb, clazz); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 执行sql语句 |
||||||
|
*/ |
||||||
|
void exeSql(String sql) { |
||||||
|
mDb.execSQL(sql); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除某条数据 |
||||||
|
*/ |
||||||
|
<T extends DbEntity> void delData(Class<T> clazz, String... expression) { |
||||||
|
mDManager.getDelegate(DelegateUpdate.class).delData(mDb, clazz, expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 修改某行数据 |
||||||
|
*/ |
||||||
|
void modifyData(DbEntity dbEntity) { |
||||||
|
mDManager.getDelegate(DelegateUpdate.class).modifyData(mDb, dbEntity); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 遍历所有数据 |
||||||
|
*/ |
||||||
|
<T extends DbEntity> List<T> findAllData(Class<T> clazz) { |
||||||
|
return mDManager.getDelegate(DelegateFind.class).findAllData(mDb, clazz); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 条件查寻数据 |
||||||
|
*/ |
||||||
|
<T extends DbEntity> List<T> findData(Class<T> clazz, String... expression) { |
||||||
|
return mDManager.getDelegate(DelegateFind.class).findData(mDb, clazz, expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 通过rowId判断数据是否存在 |
||||||
|
*/ |
||||||
|
<T extends DbEntity> boolean isExist(Class<T> clazz, int rowId) { |
||||||
|
return mDManager.getDelegate(DelegateFind.class).itemExist(mDb, clazz, rowId); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 插入数据 |
||||||
|
*/ |
||||||
|
void insertData(DbEntity dbEntity) { |
||||||
|
mDManager.getDelegate(DelegateUpdate.class).insertData(mDb, dbEntity); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 查找某张表是否存在 |
||||||
|
*/ |
||||||
|
boolean tableExists(Class clazz) { |
||||||
|
return mDManager.getDelegate(DelegateCommon.class).tableExists(mDb, clazz); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取所在行Id |
||||||
|
*/ |
||||||
|
int[] getRowId(Class clazz) { |
||||||
|
return mDManager.getDelegate(DelegateFind.class).getRowId(mDb, clazz); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取行Id |
||||||
|
*/ |
||||||
|
int getRowId(Class clazz, Object[] wheres, Object[] values) { |
||||||
|
return mDManager.getDelegate(DelegateFind.class).getRowId(mDb, clazz, wheres, values); |
||||||
|
} |
||||||
|
} |
@ -1,32 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
package com.arialyy.aria.orm; |
|
||||||
|
|
||||||
import java.lang.annotation.ElementType; |
|
||||||
import java.lang.annotation.Retention; |
|
||||||
import java.lang.annotation.RetentionPolicy; |
|
||||||
import java.lang.annotation.Target; |
|
||||||
|
|
||||||
/** |
|
||||||
* Created by AriaL on 2017/7/4. |
|
||||||
* 基本类型的List,只能用于常见的数据类型,如果是一对多的复杂数据结构,需要使用{@link OneToMany} |
|
||||||
*/ |
|
||||||
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface NormalList { |
|
||||||
/** |
|
||||||
* 数据类型 |
|
||||||
*/ |
|
||||||
Class clazz(); |
|
||||||
} |
|
@ -0,0 +1,50 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package com.arialyy.aria.orm.annotation; |
||||||
|
|
||||||
|
import com.arialyy.aria.orm.ActionPolicy; |
||||||
|
import com.arialyy.aria.orm.DbEntity; |
||||||
|
import java.lang.annotation.ElementType; |
||||||
|
import java.lang.annotation.Retention; |
||||||
|
import java.lang.annotation.RetentionPolicy; |
||||||
|
import java.lang.annotation.Target; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by AriaL on 2017/7/4. |
||||||
|
* 外键约束 |
||||||
|
*/ |
||||||
|
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Foreign { |
||||||
|
|
||||||
|
/** |
||||||
|
* 关联的表 |
||||||
|
*/ |
||||||
|
Class<? extends DbEntity> parent(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 父表对应的列名 |
||||||
|
*/ |
||||||
|
String column(); |
||||||
|
|
||||||
|
/** |
||||||
|
* ON UPDATE 约束 |
||||||
|
*/ |
||||||
|
ActionPolicy onUpdate() default ActionPolicy.NO_ACTION; |
||||||
|
|
||||||
|
/** |
||||||
|
* ON DELETE 约束 |
||||||
|
*/ |
||||||
|
ActionPolicy onDelete() default ActionPolicy.NO_ACTION; |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.arialyy.aria.orm.annotation; |
||||||
|
|
||||||
|
import java.lang.annotation.ElementType; |
||||||
|
import java.lang.annotation.Retention; |
||||||
|
import java.lang.annotation.RetentionPolicy; |
||||||
|
import java.lang.annotation.Target; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by lyy on 2015/11/2. |
||||||
|
* 设置表名,如果不是使用该注解,默认为类名 |
||||||
|
*/ |
||||||
|
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Table { |
||||||
|
String tableName(); |
||||||
|
} |
Loading…
Reference in new issue