SQLExecuteManager.java 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. package com.yc.database.manager;
  2. import android.annotation.SuppressLint;
  3. import android.database.Cursor;
  4. import android.database.sqlite.SQLiteDatabase;
  5. import android.database.sqlite.SQLiteStatement;
  6. import java.io.Serializable;
  7. import java.util.Date;
  8. import com.yc.database.bean.BindSQL;
  9. import com.yc.database.utils.DBLog;
  10. import com.yc.database.utils.DateUtil;
  11. /**
  12. * <pre>
  13. * @author yangchong
  14. * email : yangchong211@163.com
  15. * time : 2017/8/6
  16. * desc : SQL语句执行器
  17. * revise:
  18. * </pre>
  19. */
  20. public class SQLExecuteManager implements Serializable {
  21. /**
  22. * uid
  23. */
  24. private static final long serialVersionUID = 1L;
  25. /**
  26. * SQLite中的关键字
  27. */
  28. public static final String[] SQLITE_KEYWORDS = { "ABORT", "ACTION",
  29. "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", "ASC",
  30. "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
  31. "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
  32. "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
  33. "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT",
  34. "DEFERRABLE", "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT",
  35. "DROP", "EACH", "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE",
  36. "EXISTS", "EXPLAIN", "FAIL", "FOR", "FOREIGN", "FROM", "FULL",
  37. "GLOB", "GROUP", "HAVING", "IF", "IGNORE", "IMMEDIATE", "IN",
  38. "INDEX", "INDEXED", "INITIALLY", "INNER", "INSERT", "INSTEAD",
  39. "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", "LEFT", "LIKE",
  40. "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", "NULL", "OF",
  41. "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
  42. "PRIMARY", "QUERY", "RAISE", "REFERENCES", "REGEXP", "REINDEX",
  43. "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", "ROLLBACK",
  44. "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", "TEMPORARY",
  45. "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
  46. "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN",
  47. "WHERE" };
  48. /**
  49. * 数据库操作类
  50. */
  51. private SQLiteDatabase mSQLiteDataBase;
  52. public SQLExecuteManager(SQLiteDatabase mSQLiteDataBase) {
  53. super();
  54. this.mSQLiteDataBase = mSQLiteDataBase;
  55. }
  56. /**
  57. * 开启一个事务(事务开始)
  58. * 在事务代码执行完成后,必须要执行successTransaction()将事务标记为成功
  59. * 在代码的最后必须要执行endTransaction()来结束当前事务,如果事务成功则提交事务,否则回滚事务
  60. * <pre>
  61. * db.beginTransaction();
  62. * try {
  63. * ...
  64. * db.setTransactionSuccessful();
  65. * } finally {
  66. * db.endTransaction();
  67. * }
  68. * </pre>
  69. */
  70. public void beginTransaction() {
  71. this.mSQLiteDataBase.beginTransaction();
  72. }
  73. /**
  74. * 标记当前事务成功
  75. */
  76. public void successTransaction() {
  77. this.mSQLiteDataBase.setTransactionSuccessful();
  78. }
  79. /**
  80. * 结束当前事务,当事物被标记成功后,此操作会提交事务,否则会回滚事务
  81. */
  82. public void endTransaction() {
  83. this.mSQLiteDataBase.endTransaction();
  84. }
  85. /**
  86. * 执行指定无返回值的单条SQL语句,如建表、创建数据库等
  87. * @param sql 执行sql
  88. */
  89. public void execSQL(String sql) {
  90. DBLog.debug(sql);
  91. this.mSQLiteDataBase.execSQL(sql);
  92. }
  93. /**
  94. * 插入一条记录,返回该记录的rowId
  95. * @param sql
  96. * @param args
  97. * @return 插入失败返回-1,成功返回rowId
  98. */
  99. public long insert(String sql, Object[] args) {
  100. long rowId = -1;
  101. SQLiteStatement statement = this.mSQLiteDataBase.compileStatement(sql);
  102. try {
  103. if(args != null) {
  104. for(int i = 0; i < args.length; i++) {
  105. bindArgs(statement, i + 1, args[i]);
  106. }
  107. }
  108. rowId = statement.executeInsert();
  109. DBLog.debug(sql, args);
  110. } finally {
  111. statement.close();
  112. }
  113. return rowId;
  114. }
  115. /**
  116. * 根据BindSQL进行插入数据
  117. * @param bindSQL
  118. * @return
  119. * @throws Exception
  120. */
  121. public long insert(BindSQL bindSQL) {
  122. if (bindSQL==null){
  123. return -1;
  124. }
  125. String sql = bindSQL.getSql();
  126. Object[] bindArgs = bindSQL.getBindArgs();
  127. return insert(sql, bindArgs);
  128. }
  129. /**
  130. * 绑定参数
  131. * @param statement
  132. * @param position
  133. * @param args
  134. */
  135. private void bindArgs(SQLiteStatement statement, int position, Object args) {
  136. int type = FieldTypeManager.getValueType(args);
  137. switch(type) {
  138. case FieldTypeManager.VALUE_TYPE_NULL:
  139. statement.bindNull(position);
  140. break;
  141. case FieldTypeManager.BASE_TYPE_BYTE_ARRAY:
  142. statement.bindBlob(position, (byte[])args);
  143. break;
  144. case FieldTypeManager.BASE_TYPE_CHAR:
  145. case FieldTypeManager.BASE_TYPE_STRING:
  146. statement.bindString(position, args.toString());
  147. break;
  148. case FieldTypeManager.BASE_TYPE_DATE:
  149. statement.bindString(position, DateUtil.formatDatetime((Date) args));
  150. break;
  151. case FieldTypeManager.BASE_TYPE_DOUBLE:
  152. case FieldTypeManager.BASE_TYPE_FLOAT:
  153. statement.bindDouble(position, Double.parseDouble(args.toString()));
  154. break;
  155. case FieldTypeManager.BASE_TYPE_INT:
  156. case FieldTypeManager.BASE_TYPE_LONG:
  157. case FieldTypeManager.BASE_TYPE_SHORT:
  158. statement.bindLong(position, Long.parseLong(args.toString()));
  159. break;
  160. case FieldTypeManager.NOT_BASE_TYPE:
  161. throw new IllegalArgumentException("未知参数类型,请检查绑定参数");
  162. }
  163. }
  164. /**
  165. * 删除指定表
  166. * @param tableName
  167. * @throws Exception
  168. */
  169. public void dropTable(String tableName) {
  170. String sql = "DROP TABLE IF EXISTS " + tableName;
  171. execSQL(sql);
  172. }
  173. /**
  174. * 删除,表名不能使用占位符
  175. * @param bindSQL
  176. */
  177. public void delete(BindSQL bindSQL) {
  178. updateOrDelete(bindSQL.getSql(), bindSQL.getBindArgs());
  179. }
  180. /**
  181. * 删除,表名不能使用占位符
  182. * @param sql 删除语句(参数使用占位符)
  183. * @param args 占位符参数
  184. */
  185. @SuppressLint("NewApi")
  186. public void updateOrDelete(String sql, Object[] args) {
  187. SQLiteStatement statement = mSQLiteDataBase.compileStatement(sql);
  188. try {
  189. if(args != null) {
  190. for(int i = 0; i < args.length; i++) {
  191. bindArgs(statement, i + 1, args[i]);
  192. }
  193. }
  194. DBLog.debug(sql, args);
  195. statement.executeUpdateDelete();
  196. } finally {
  197. statement.close();
  198. }
  199. }
  200. /**
  201. * 删除(对于表名需要动态获取的,此方法非常适合)
  202. * @param tableName 要删除的数据表
  203. * @param whereClause where后面的条件句(delete from XXX where XXX),参数使用占位符
  204. * @param whereArgs where子句后面的占位符参数
  205. */
  206. public void delete(String tableName, String whereClause, String[] whereArgs) {
  207. DBLog.debug("{SQL:DELETE FROM " + tableName + " WHERE " + whereClause + ",PARAMS:" + whereArgs + "}");
  208. mSQLiteDataBase.delete(tableName, whereClause, whereArgs);
  209. }
  210. /**
  211. * 更新
  212. * @param bindSQL
  213. */
  214. public void update(BindSQL bindSQL) {
  215. updateOrDelete(bindSQL.getSql(), bindSQL.getBindArgs());
  216. }
  217. /**
  218. * 根据SQL进行查询
  219. * @param sql
  220. * @return
  221. */
  222. public Cursor query(String sql) {
  223. return query(sql, null);
  224. }
  225. /**
  226. * 执行绑定语句
  227. * 运行一个预置的SQL语句,返回带游标的数据集(与query的语句最大的区别 = 防止SQL注入)
  228. * @param sql sql语句
  229. * @param whereArgs 搜索条件
  230. * @return
  231. */
  232. public Cursor query(String sql, String[] whereArgs) {
  233. DBLog.debug("{SQL:" + sql + ",PARAMS:" + whereArgs + "}");
  234. return this.mSQLiteDataBase.rawQuery(sql, whereArgs);
  235. }
  236. /**
  237. * 根据BindSQL查询
  238. * @param bindSQL
  239. * @return
  240. */
  241. public Cursor query(BindSQL bindSQL) {
  242. return query(bindSQL.getSql(), (String[])bindSQL.getBindArgs());
  243. }
  244. @Deprecated
  245. public Cursor query(boolean distinct, String table, String[] columns,
  246. String selection, String[] selectionArgs, String groupBy,
  247. String having, String orderBy, String limit) {
  248. // 查询指定的数据表返回一个带游标的数据集。
  249. // 各参数说明:
  250. // table:表名称
  251. // colums:列名称数组
  252. // selection:条件子句,相当于where
  253. // selectionArgs:条件语句的参数数组
  254. // groupBy:分组
  255. // having:分组条件
  256. // orderBy:排序类
  257. // limit:分页查询的限制
  258. return this.mSQLiteDataBase.query(distinct, table, columns, selection,
  259. selectionArgs, groupBy, having, orderBy, limit);
  260. }
  261. }