├── demo ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── styles.xml │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── dimens.xml │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── values-w820dp │ │ │ │ └── dimens.xml │ │ │ └── layout │ │ │ │ └── activity_main.xml │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── yedaxia │ │ │ └── github │ │ │ └── io │ │ │ └── test │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── yedaxia │ │ └── github │ │ └── io │ │ └── test │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── library ├── .gitignore ├── src │ ├── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── io │ │ │ └── github │ │ │ └── yedaxia │ │ │ └── sqliteutils │ │ │ ├── DaoFactory.java │ │ │ ├── PagingList.java │ │ │ ├── DBTransaction.java │ │ │ ├── DateUtils.java │ │ │ ├── ColumnInfo.java │ │ │ ├── Table.java │ │ │ ├── IBaseDao.java │ │ │ ├── ResultSet.java │ │ │ ├── GenericDao.java │ │ │ ├── SqlHelper.java │ │ │ └── DbSqlite.java │ ├── test │ │ └── java │ │ │ └── io │ │ │ └── github │ │ │ └── yedaxia │ │ │ └── sqliteutils │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── io │ │ └── github │ │ └── yedaxia │ │ └── sqliteutils │ │ └── ExampleInstrumentedTest.java ├── build.gradle ├── proguard-rules.pro └── bintrayUpload.gradle ├── settings.gradle ├── .idea ├── copyright │ └── profiles_settings.xml ├── vcs.xml ├── modules.xml ├── runConfigurations.xml ├── gradle.xml ├── compiler.xml └── misc.xml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── gradle.properties ├── gradlew.bat ├── README.md └── gradlew /demo/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /library/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':demo', ':library' 2 | -------------------------------------------------------------------------------- /demo/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /demo/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | SQLiteUtils 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeDaxia/SQLiteUtils/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeDaxia/SQLiteUtils/HEAD/demo/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeDaxia/SQLiteUtils/HEAD/demo/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeDaxia/SQLiteUtils/HEAD/demo/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeDaxia/SQLiteUtils/HEAD/demo/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YeDaxia/SQLiteUtils/HEAD/demo/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /demo/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /demo/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Dec 28 10:00:20 PST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 7 | -------------------------------------------------------------------------------- /library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /demo/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /demo/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /demo/src/test/java/yedaxia/github/io/test/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package yedaxia.github.io.test; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /library/src/test/java/io/github/yedaxia/sqliteutils/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package io.github.yedaxia.sqliteutils; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.1" 6 | defaultConfig { 7 | minSdkVersion 6 8 | targetSdkVersion 25 9 | versionCode 1 10 | versionName "1.0" 11 | } 12 | buildTypes { 13 | release { 14 | minifyEnabled false 15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 16 | } 17 | } 18 | } 19 | 20 | apply from: "bintrayUpload.gradle" -------------------------------------------------------------------------------- /library/src/main/java/io/github/yedaxia/sqliteutils/DaoFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.yedaxia.sqliteutils; 2 | 3 | 4 | /** 5 | * use this factory to create your sqlite data access object 6 | * @author Darcy yeguozhong@yeah.net 7 | */ 8 | public class DaoFactory { 9 | 10 | /** 11 | * call this method to new a GenericDao 12 | * @param db 13 | * @param modelClazz 14 | * @return 15 | */ 16 | @SuppressWarnings("unchecked") 17 | public static IBaseDao createGenericDao(DbSqlite db, Class modelClazz){ 18 | return new GenericDao(db,modelClazz); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /demo/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\user\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /library/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\user\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /demo/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.1" 6 | defaultConfig { 7 | applicationId "io.github.yedaxia.sqliteutils" 8 | minSdkVersion 6 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | } 26 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /library/src/main/java/io/github/yedaxia/sqliteutils/PagingList.java: -------------------------------------------------------------------------------- 1 | package io.github.yedaxia.sqliteutils; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * A List For Paging QueryResult 7 | * @author Darcy 8 | * 9 | * @param 10 | */ 11 | public class PagingList extends ArrayList{ 12 | 13 | private static final long serialVersionUID = 5526933443772285251L; 14 | 15 | private int mTotalSize; 16 | 17 | /** 18 | * return total size of your query condition 19 | * @return 20 | */ 21 | public int getTotalSize(){ 22 | return mTotalSize; 23 | } 24 | 25 | /** 26 | * return size of this paing query 27 | */ 28 | public int size() { 29 | return super.size(); 30 | } 31 | 32 | void setTotalSize(int totalSize){ 33 | this.mTotalSize = totalSize; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /demo/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 18 | 19 | -------------------------------------------------------------------------------- /library/src/main/java/io/github/yedaxia/sqliteutils/DBTransaction.java: -------------------------------------------------------------------------------- 1 | package io.github.yedaxia.sqliteutils; 2 | 3 | import android.database.sqlite.SQLiteDatabase; 4 | 5 | /** 6 | * 7 | * a transction support class 8 | * 9 | * @author Darcy yeguozhong@yeah.net 10 | */ 11 | public class DBTransaction { 12 | 13 | private DBTransaction() { 14 | } 15 | 16 | /** 17 | * executes sqls in a transction 18 | */ 19 | public static void transact(DbSqlite db, DBTransactionInterface transctionInterface){ 20 | if(transctionInterface!=null){ 21 | SQLiteDatabase sqliteDb = db.getSQLiteDatabase(); 22 | sqliteDb.beginTransaction(); 23 | try{ 24 | transctionInterface.onTransact(); 25 | sqliteDb.setTransactionSuccessful(); 26 | }finally{ 27 | sqliteDb.endTransaction(); 28 | } 29 | } 30 | } 31 | 32 | public interface DBTransactionInterface{ 33 | void onTransact(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /demo/src/androidTest/java/yedaxia/github/io/test/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package yedaxia.github.io.test; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("io.github.yedaxia.sqliteutils", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/java/io/github/yedaxia/sqliteutils/DateUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.yedaxia.sqliteutils; 2 | 3 | import java.text.DateFormat; 4 | import java.text.ParseException; 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | import java.util.Locale; 8 | 9 | class DateUtils { 10 | 11 | private final static DateFormat DF_SSS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS",Locale.getDefault()); 12 | private final static DateFormat DF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault()); 13 | 14 | private DateUtils(){} 15 | 16 | static Date parseStr2Date(String str){ 17 | try { 18 | if(str.endsWith(".SSS")){ 19 | return DF_SSS.parse(str); 20 | }else{ 21 | return DF.parse(str); 22 | } 23 | } catch (ParseException e) { 24 | e.printStackTrace(); 25 | return null; 26 | } 27 | } 28 | 29 | static String formatDate2Str(Date date){ 30 | return DF_SSS.format(date); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /library/src/androidTest/java/io/github/yedaxia/sqliteutils/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package io.github.yedaxia.sqliteutils; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("yedaxia.github.io.library.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/java/io/github/yedaxia/sqliteutils/ColumnInfo.java: -------------------------------------------------------------------------------- 1 | package io.github.yedaxia.sqliteutils; 2 | 3 | /** 4 | * @author Darcy 5 | */ 6 | class ColumnInfo { 7 | 8 | private boolean isPrimaryKey = false; 9 | 10 | private boolean isNull = true; 11 | 12 | private String name; 13 | 14 | private String type; 15 | 16 | private String defaultValue = "null"; 17 | 18 | private boolean isUnique = false; 19 | 20 | public boolean isPrimaryKey() { 21 | return isPrimaryKey; 22 | } 23 | 24 | public void setPrimaryKey(boolean isPrimaryKey) { 25 | this.isPrimaryKey = isPrimaryKey; 26 | } 27 | 28 | public boolean isNull() { 29 | return isNull; 30 | } 31 | 32 | public void setNull(boolean isNull) { 33 | this.isNull = isNull; 34 | } 35 | 36 | public String getName() { 37 | return name; 38 | } 39 | 40 | public void setName(String name) { 41 | this.name = name; 42 | } 43 | 44 | public String getType() { 45 | return type; 46 | } 47 | 48 | public void setType(String type) { 49 | this.type = type; 50 | } 51 | 52 | public boolean isUnique() { 53 | return isUnique; 54 | } 55 | 56 | public void setUnique(boolean isUnique) { 57 | this.isUnique = isUnique; 58 | } 59 | 60 | public String getDefaultValue() { 61 | return defaultValue; 62 | } 63 | 64 | public void setDefaultValue(String defaultValue) { 65 | this.defaultValue = defaultValue; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /library/src/main/java/io/github/yedaxia/sqliteutils/Table.java: -------------------------------------------------------------------------------- 1 | package io.github.yedaxia.sqliteutils; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * model annotation corresponding to table 10 | * 11 | * @author Darcy 12 | */ 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Target(ElementType.TYPE) 15 | public @interface Table { 16 | 17 | /** 18 | * table name 19 | * @return 20 | */ 21 | public String name(); 22 | 23 | /** 24 | * table version, if this value diff from the previous one, it will update this table 25 | * @return 26 | */ 27 | public int version() default 1; 28 | 29 | /** 30 | * model field annotation corresponding to table column 31 | * @author Darcy 32 | */ 33 | @Retention(RetentionPolicy.RUNTIME) 34 | @Target(ElementType.FIELD) 35 | public @interface Column { 36 | 37 | public static final String TYPE_INTEGER = "INTEGER"; 38 | public static final String TYPE_LONG = "NUMERIC"; 39 | public static final String TYPE_STRING = "TEXT"; 40 | public static final String TYPE_TIMESTAMP ="TEXT"; 41 | public static final String TYPE_BOOLEAN = "INTEGER"; 42 | public static final String TYPE_FLOAT = "REAL"; 43 | public static final String TYPE_DOUBLE = "REAL"; 44 | public static final String TYPE_BLOB = "BLOB"; 45 | 46 | public static final class DEFAULT_VALUE{ 47 | public static final String TRUE = "1"; 48 | public static final String FALSE = "0"; 49 | public static final String CURRENT_TIMESTAMP = "(datetime(CURRENT_TIMESTAMP,'localtime'))"; 50 | } 51 | 52 | public String name(); 53 | 54 | public String type(); 55 | 56 | public String defaultValue()default "null"; 57 | 58 | public boolean isPrimaryKey()default false; 59 | 60 | public boolean isNull()default true; 61 | 62 | public boolean isUnique()default false; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About SQLiteUtils 2 | 一个简单的基于Android的Sqlite数据库的操作封装,它有如下的好处: 3 | 4 | - 便捷地创建表和增添表字段 5 | - 通过操作对象来insert或者update表记录 6 | - 支持多种查询方式,支持分页查询 7 | - 支持事务 8 | 9 | # Quick Start: 10 | 11 | 1. 定义表对应的对象,对于基本类型,请使用对象类型来声明类成员,如int用Integer。以免在update的时候出现意想不到的情况。 12 | ```java 13 | @Table(name="t_user") 14 | public class UserModel { 15 | @Table.Column(name="user_id",type=Column.TYPE_INTEGER,isPrimaryKey=true) 16 | public Integer userId; 17 | 18 | @Table.Column(name="user_name",type=Column.TYPE_STRING,isNull=false) 19 | public String userName; 20 | 21 | @Table.Column(name="born_date",type=Column.TYPE_TIMESTAMP) 22 | public Date bornDate; 23 | 24 | @Table.Column(name="pictrue",type=Column.TYPE_BLOB) 25 | public byte[] pictrue; 26 | 27 | @Table.Column(name="is_login",type=Column.TYPE_BOOLEAN) 28 | public Boolean isLogin; 29 | 30 | @Table.Column(name="weight",type=Column.TYPE_DOUBLE) 31 | public Double weight; 32 | } 33 | ``` 34 | 2. 增删查改: 35 | 初始化对象: 36 | ```java 37 | SQLiteDatabase db = context.openOrCreateDatabase("test.db", Context.MODE_PRIVATE, null); 38 | DbSqlite dbSqlite = new DbSqlite(db); 39 | IBaseDao userDAO = DaoFactory.createGenericDao(dbSqlite, UserModel.class); 40 | ``` 41 | 创建Table: 42 | ```java 43 | userDAO.createTable(); 44 | ``` 45 | insert 一条记录: 46 | ```java 47 | UserModel user = new UserModel(); 48 | user.userName = "darcy"; 49 | user.isLogin = true; 50 | user.weight = 60.5; 51 | user.bornDate = new Date(); 52 | byte[] picture = {0x1,0x2,0x3,0x4}; 53 | user.pictrue = picture; 54 | userDAO.insert(user); 55 | ``` 56 | update 记录: 57 | ```java 58 | UserModel user = new UserModel(); 59 | user.weight = 88.0; 60 | userDAO.update(user, "user_name=?", "darcy"); 61 | ``` 62 | 查询结果: 63 | ```java 64 | //单条结果查询 65 | UserModel user = userDAO.queryFirstRecord("user_name=?", "darcy"); 66 | 67 | //一般查询 68 | List userList = userDAO.query("user_name=? and weight > ?", "darcy" , "60"); 69 | 70 | //分页查询 71 | PagingList pagingList = userDAO.pagingQuery(null, null, 1, 3); 72 | ``` 73 | 事务支持: 74 | ```java 75 | DBTransaction.transact(mDb, new DBTransaction.DBTransactionInterface() { 76 | @Override 77 | public void onTransact() { 78 | // to do 79 | } 80 | }; 81 | ``` 82 | 更新表[只支持添加字段]: 83 | ```java 84 | @Table(name="t_user" , version=2) //修改表版本 85 | public class UserModel { 86 | //members above... 87 | 88 | //new columns 89 | 90 | @Table.Column(name="new_column_1",type=Column.TYPE_INTEGER) 91 | public Integer newColumn; 92 | 93 | @Table.Column(name="new_column_2",type=Column.TYPE_INTEGER) 94 | public Integer newColumn2; 95 | } 96 | 97 | userDAO.updateTable(); 98 | ``` 99 | # License 100 | 101 | Copyright 2016 yedaxia 102 | 103 | Licensed under the Apache License, Version 2.0 (the "License"); 104 | you may not use this file except in compliance with the License. 105 | You may obtain a copy of the License at 106 | 107 | http://www.apache.org/licenses/LICENSE-2.0 108 | 109 | Unless required by applicable law or agreed to in writing, software 110 | distributed under the License is distributed on an "AS IS" BASIS, 111 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 112 | See the License for the specific language governing permissions and 113 | limitations under the License. 114 | -------------------------------------------------------------------------------- /library/bintrayUpload.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.jfrog.bintray' 2 | apply plugin: 'maven-publish' 3 | // This is the library version used when deploying the artifact 4 | 5 | group = "io.github.yedaxia.sqliteutils" // Maven Group ID for the artifact,一般填你唯一的包名 6 | version = "1.0.0" 7 | 8 | def siteUrl = 'https://github.com/YeDaxia/SQLiteUtils' // 项目的主页 9 | def gitUrl = 'https://github.com/YeDaxia/SQLiteUtils.git' // Git仓库的url 10 | 11 | task makeJar(type: Jar) { 12 | //指定生成的jar名 13 | baseName 'sqliteutils' 14 | //从哪里打包class文件 15 | from('build\\intermediates\\classes\\release\\io\\github\\yedaxia\\sqliteutils\\') 16 | //打包到jar后的目录结构 17 | into('io/github/yedaxia/sqliteutils/') 18 | //去掉不需要打包的目录和文件 19 | exclude('test/', 'BuildConfig.class', 'R.class') 20 | //去掉R$开头的文件 21 | exclude{ it.name.startsWith('R$');} 22 | } 23 | 24 | task sourcesJar(type: Jar) { 25 | from android.sourceSets.main.java.srcDirs 26 | classifier = 'sources' 27 | baseName 'sqliteutils' 28 | } 29 | 30 | task javadoc(type: Javadoc) { 31 | source = android.sourceSets.main.java.srcDirs 32 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 33 | } 34 | 35 | task javadocJar(type: Jar, dependsOn: javadoc) { 36 | baseName 'sqliteutils' 37 | classifier = 'javadoc' 38 | from javadoc.destinationDir 39 | } 40 | 41 | artifacts { 42 | archives javadocJar 43 | archives sourcesJar 44 | archives makeJar 45 | } 46 | 47 | // Create the pom configuration: 48 | def pomConfig = { 49 | licenses { 50 | license { 51 | name "The Apache Software License, Version 2.0" 52 | url "http://www.apache.org/licenses/LICENSE-2.0.txt" 53 | distribution "repo" 54 | } 55 | } 56 | developers { 57 | developer { 58 | id "yedaxia" 59 | name "yeguozhong" 60 | email "guozhong.yale@gmail.com" 61 | } 62 | } 63 | } 64 | 65 | // Create the publication with the pom configuration: 66 | publishing { 67 | publications { 68 | MyPublication(MavenPublication) { 69 | artifact sourcesJar 70 | artifact javadocJar 71 | groupId 'io.github.yedaxia' 72 | artifactId 'sqliteutils' 73 | version '1.0.0' 74 | pom.withXml { 75 | def root = asNode() 76 | root.appendNode('description', 'A Simple SQLite Operations Encapsulations For Android') 77 | root.appendNode('name', 'SqliteUtils') 78 | root.appendNode('url', 'https://github.com/YeDaxia/SQLiteUtils') 79 | root.children().last() + pomConfig 80 | } 81 | } 82 | } 83 | } 84 | 85 | Properties properties = new Properties() 86 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 87 | bintray { 88 | user = properties.getProperty("bintray.user") 89 | key = properties.getProperty("bintray.apikey") 90 | configurations = ['archives'] 91 | publications = ['MyPublication'] 92 | pkg { 93 | repo = "maven" 94 | name = "SqliteUtils" //发布到JCenter上的项目名字 95 | userOrg = "darcye" 96 | websiteUrl = siteUrl 97 | vcsUrl = gitUrl 98 | licenses = ["Apache-2.0"] 99 | publish = true 100 | } 101 | } 102 | javadoc { //jav doc采用utf-8编码否则会报“GBK的不可映射字符”错误 103 | options{ 104 | encoding "UTF-8" 105 | charSet 'UTF-8' 106 | } 107 | } -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /library/src/main/java/io/github/yedaxia/sqliteutils/IBaseDao.java: -------------------------------------------------------------------------------- 1 | package io.github.yedaxia.sqliteutils; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * the interface below is mostly design to handle a single table itself, 7 | * but if you want to do more complicated operations with more than one table,please try {@link #execQuerySQL(String, String...)} or {@link DbSqlite} 8 | * 9 | * @author Darcy 10 | * 11 | * @param 12 | */ 13 | public interface IBaseDao { 14 | 15 | /** 16 | * create table 17 | */ 18 | void createTable(); 19 | 20 | /** 21 | * update table, it just support add columns to table, it will check table's version if it need to update or not. 22 | */ 23 | void updateTable(); 24 | 25 | /** 26 | * delete table 27 | */ 28 | void deleteTable(); 29 | 30 | /** 31 | * insert an object 32 | * 33 | * @param model the model to insert 34 | * @return the row ID of the newly inserted row, or -1 if an error occurred 35 | */ 36 | long insert(T model); 37 | 38 | /** 39 | * batch insert 40 | * 41 | * @param dataList 42 | * @return 43 | */ 44 | boolean batchInsert(List dataList); 45 | 46 | /** 47 | * update an object by the condition you set 48 | * 49 | * @param model the model to update 50 | * @param whereClause the optional WHERE clause to apply when updating. Passing null will update all rows. 51 | * @param whereArgs You may include ?s in the where clause, which will be replaced by the values from whereArgs. The values will be bound as Strings. 52 | * @return the number of rows affected , or -1 if an error occurred 53 | */ 54 | int update(T model, String whereClause, String... whereArgs); 55 | 56 | /** 57 | * delete by condition 58 | * 59 | * @param whereClause whereClause the optional WHERE clause to apply when deleting. Passing null will delete all rows. 60 | * @param whereArgs whereArgs You may include ?s in the where clause, which will be replaced by the values from whereArgs. The values will be bound as Strings. 61 | * @return the number of rows affected if a whereClause is passed in, 0 otherwise 62 | */ 63 | int delete(String whereClause, String... whereArgs); 64 | 65 | 66 | /** 67 | * delete all records 68 | * @return success return true, else return false 69 | */ 70 | boolean deleteAll(); 71 | 72 | /** 73 | * get all records in this table 74 | * @return 75 | */ 76 | List queryAll(); 77 | 78 | /** 79 | * query by condition, it will contain all columns 80 | * 81 | * @param selection 82 | * @param selectionArgs 83 | * @return if exceptions happen or no match records, then return null 84 | */ 85 | List query(String selection, String[] selectionArgs); 86 | 87 | /** 88 | * query by condition 89 | * @param columns 90 | * @param selection 91 | * @param orderBy 92 | * @param selectionArgs 93 | * @return if exceptions happen or no match records, then return null 94 | */ 95 | List query(String[] columns, String selection, String[] selectionArgs, 96 | String orderBy); 97 | 98 | /** 99 | * query by condition 100 | * @param columns 101 | * @param selection A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table. 102 | * @param groupBy A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped. 103 | * @param having A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used. 104 | * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered. 105 | * @param selectionArgs You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings. 106 | * @return if exceptions happen or no match records, then return null 107 | */ 108 | List query(String[] columns, String selection, String[] selectionArgs, 109 | String groupBy, String having, String orderBy); 110 | 111 | 112 | /** 113 | * query table's records by paging 114 | * @param selection 115 | * @param selectionArgs 116 | * @return 117 | */ 118 | PagingList pagingQuery(String selection, String[] selectionArgs, int page, int pageSize); 119 | 120 | /** 121 | * query table's records by paging 122 | * @param columns 123 | * @param selection 124 | * @param selectionArgs 125 | * @return 126 | */ 127 | PagingList pagingQuery(String[] columns, String selection, String[] selectionArgs, String orderBy, int page, int pageSize); 128 | 129 | /** 130 | * query table's records by paging 131 | * @param columns 132 | * @param selection 133 | * @param selectionArgs 134 | * @param groupBy 135 | * @param having 136 | * @param orderBy 137 | * @param page first page is 1 138 | * @param pageSize 139 | * @return 140 | */ 141 | PagingList pagingQuery(String[] columns, String selection, String[] selectionArgs, 142 | String groupBy, String having, String orderBy, int page, int pageSize); 143 | 144 | /** 145 | * if your query condition have only one record, this is helpful. 146 | * 147 | * @return the first row of the result,or null. 148 | */ 149 | T queryFirstRecord(String selection, String... selectionArgs); 150 | 151 | /** 152 | * if your query condition have only one record, this is helpful. 153 | * @param columns 154 | * @param selection 155 | * @param selectionArgs 156 | * @return 157 | */ 158 | T queryFirstRecord(String[] columns, String selection, String... selectionArgs); 159 | 160 | /** 161 | * execute raw sql with query 162 | * @param sql sql the SQL query. The SQL string must not be ; terminated 163 | * @param bindArgs You may include ?s in where clause in the query, which will be replaced by the values from selectionArgs. The values will be bound as Strings. 164 | * @return return result as List or null 165 | */ 166 | List execQuerySQL(String sql, String... bindArgs); 167 | } 168 | -------------------------------------------------------------------------------- /library/src/main/java/io/github/yedaxia/sqliteutils/ResultSet.java: -------------------------------------------------------------------------------- 1 | package io.github.yedaxia.sqliteutils; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | import java.util.Date; 6 | import java.util.LinkedHashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | /** 11 | * 12 | * a key value set which corresponds to a row of query results 13 | * 14 | * @author Darcy yeguozhong@yeah.net 15 | */ 16 | public class ResultSet implements Serializable { 17 | 18 | private static final long serialVersionUID = 2510654675439416448L; 19 | 20 | private Map nameValueMap = new LinkedHashMap(); 21 | 22 | private Map indexValueMap = new LinkedHashMap(); 23 | 24 | private List columnNameList = new ArrayList(); 25 | 26 | private int index = 0; 27 | 28 | /** 29 | * set column value 30 | * 31 | * @param columnName the table column name 32 | * @param columnValue 33 | */ 34 | void setValue(String columnName, Object columnValue) { 35 | columnName = columnName.toLowerCase(); 36 | columnNameList.add(columnName); 37 | nameValueMap.put(columnName, columnValue); 38 | indexValueMap.put(index++, columnValue); 39 | } 40 | 41 | /** 42 | * change value by index in this result set 43 | * 44 | * @param index 45 | * @param value 46 | */ 47 | public void changeValue(int index, Object value) { 48 | if (indexValueMap.containsKey(index)) { 49 | indexValueMap.put(index, value); 50 | nameValueMap.put(columnNameList.get(index), value); 51 | } 52 | } 53 | 54 | /** 55 | * get value by column name 56 | * 57 | * @param columnName 58 | * @return return the value of this column 59 | */ 60 | public Object getValue(String columnName) { 61 | return nameValueMap.get(columnName.toLowerCase()); 62 | } 63 | 64 | /** 65 | * get boolean type value 66 | * 67 | * @param columnName 68 | * @return if the value is a "1" or "true" , return true; or is a "null" or "0" or "false", return false. 69 | * @exception ClassCastException 70 | */ 71 | public boolean getBooleanValue(String columnName) { 72 | Object value = getValue(columnName); 73 | if(value == null) 74 | return false; 75 | String strVal = value.toString().toLowerCase(); 76 | if(strVal.equals("true") || strVal.equals("1")){ 77 | return true; 78 | }else if(strVal.equals("false") || strVal.equals("0")){ 79 | return false; 80 | } 81 | throw new ClassCastException(String.format("invalid boolean value : %s ", value)); 82 | } 83 | 84 | /** 85 | * 86 | * get long type value 87 | * 88 | * @param columnName 89 | */ 90 | public long getLongValue(String columnName) { 91 | return (long) getDoubleValue(columnName); 92 | } 93 | 94 | /** 95 | * 96 | * get int type value 97 | * 98 | * @param columnName 99 | */ 100 | public int getIntValue(String columnName) { 101 | return (int) getLongValue(columnName); 102 | } 103 | 104 | /** 105 | * 106 | * get short type value 107 | * 108 | * @param columnName 109 | */ 110 | public short getShortValue(String columnName) { 111 | return (short) getIntValue(columnName); 112 | } 113 | 114 | /** 115 | * 116 | * get float type vlue 117 | * 118 | * @param columnName 119 | */ 120 | public float getFloatValue(String columnName) { 121 | return (float) getDoubleValue(columnName); 122 | } 123 | 124 | /** 125 | * get double type value 126 | * 127 | * @param columnName 128 | * @return null return 0 129 | * @exception ClassCastException 130 | */ 131 | public double getDoubleValue(String columnName) { 132 | Object value = getValue(columnName); 133 | if(value == null){ 134 | return 0; 135 | }else if (value instanceof Double) { 136 | return (Double) value; 137 | } else if (value instanceof Float) { 138 | return (Float) value; 139 | } else if (value instanceof Long) { 140 | return (Long) value; 141 | } else if (value instanceof Integer) { 142 | return (Integer) value; 143 | } else if (value instanceof Short) { 144 | return (Short) value; 145 | } else if (value instanceof String) { 146 | if (isNum((String) value)) { 147 | return Double.parseDouble((String) value); 148 | } 149 | } 150 | throw new ClassCastException(String.format("invalid number %s ", value)); 151 | } 152 | 153 | /** 154 | * 155 | * get String type value 156 | * 157 | * @param columnName 158 | */ 159 | public String getStringValue(String columnName) { 160 | Object value = getValue(columnName); 161 | if(value != null){ 162 | return value.toString(); 163 | }else{ 164 | return null; 165 | } 166 | } 167 | 168 | /** 169 | * get Date type value 170 | * @param columnName 171 | * @return 172 | */ 173 | public Date getDateValue(String columnName){ 174 | String value = getStringValue(columnName); 175 | return value == null ? null : DateUtils.parseStr2Date(value); 176 | } 177 | 178 | /** 179 | * get byte[] type value 180 | * @param columnName 181 | * @return 182 | */ 183 | public byte[] getBlobValue(String columnName){ 184 | return (byte[])getValue(columnName); 185 | } 186 | 187 | /** 188 | * get value by index 189 | * 190 | * @param columnIndex 191 | * @return 192 | */ 193 | public Object getValue(int columnIndex) { 194 | return indexValueMap.get(columnIndex); 195 | } 196 | 197 | /** 198 | * the size of columns 199 | * @return 200 | */ 201 | public int getSize() { 202 | return nameValueMap.size(); 203 | } 204 | 205 | /** 206 | * no result 207 | * @return 208 | */ 209 | public boolean isEmpty() { 210 | return nameValueMap.isEmpty(); 211 | } 212 | 213 | /** 214 | * get column name by its index 215 | * @param columnNum 216 | * @return 217 | */ 218 | public String getColumnName(int columnNum){ 219 | return columnNameList.get(columnNum); 220 | } 221 | 222 | /** 223 | * get index of this column name 224 | * @param columnName 225 | * @return if the column name didn't exsits, return -1 226 | */ 227 | public int indexOfColumnName(String columnName){ 228 | return columnNameList.indexOf(columnName.toLowerCase()); 229 | } 230 | 231 | @Override 232 | public String toString() { 233 | return "Result [nameValueMap=" + nameValueMap + "]"; 234 | } 235 | 236 | /** 237 | * is this str a valid number 238 | * 239 | * @param str 240 | */ 241 | private boolean isNum(String str) { 242 | return !str.equals("")&&str.matches("^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$"); 243 | } 244 | 245 | } 246 | -------------------------------------------------------------------------------- /library/src/main/java/io/github/yedaxia/sqliteutils/GenericDao.java: -------------------------------------------------------------------------------- 1 | package io.github.yedaxia.sqliteutils; 2 | 3 | import android.content.ContentValues; 4 | import android.content.Context; 5 | import android.content.SharedPreferences; 6 | 7 | import java.util.ArrayList; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | 13 | /** 14 | * an implement of IBaseDao 15 | * @author Darcy 16 | * @param 17 | * 18 | */ 19 | class GenericDao implements IBaseDao { 20 | 21 | private static final String PREFS_TABLE_VERSION = "prefs_table_versioins"; 22 | 23 | private Class modelClazz; 24 | 25 | private String mTableName; 26 | 27 | private DbSqlite mDb; 28 | 29 | public GenericDao(DbSqlite db, Class modelClazz) { 30 | this.mDb = db; 31 | this.modelClazz = modelClazz; 32 | mTableName = SqlHelper.getTableName(modelClazz); 33 | } 34 | 35 | @Override 36 | public void createTable() { 37 | String createTableSQL = SqlHelper.getCreateTableSQL(modelClazz); 38 | mDb.execSQL(createTableSQL); 39 | } 40 | 41 | @Override 42 | public void updateTable(){ 43 | final int newTableVersion = SqlHelper.getTableVersion(modelClazz); 44 | final int curTableVersion = getCurTableVersion(); 45 | if(newTableVersion != curTableVersion){ 46 | DBTransaction.transact(mDb, new DBTransaction.DBTransactionInterface() { 47 | public void onTransact() { 48 | List rs = mDb.query("sqlite_master", new String[]{"sql"}, "type=? AND name=?", new String[]{"table",mTableName}); 49 | String curTableSql = rs.get(0).getStringValue("sql"); 50 | Map curColumns = getTableColumnsInfo(curTableSql); 51 | List newColumnInfos = SqlHelper.getTableColumnInfos(modelClazz); 52 | int newColumnSize = newColumnInfos.size(); 53 | ColumnInfo newColumnInfo; 54 | String newColumnName; 55 | String sql; 56 | for(int index = 0; index < newColumnSize ; ++index){ 57 | newColumnInfo = newColumnInfos.get(index); 58 | newColumnName = newColumnInfo.getName().toLowerCase(); 59 | if(curColumns.containsKey(newColumnName)){ 60 | curColumns.put(newColumnName, false); 61 | }else{ 62 | sql = SqlHelper.getAddColumnSql(mTableName, newColumnInfo); 63 | mDb.execSQL(sql); 64 | } 65 | } 66 | saveTableVersion(newTableVersion); 67 | } 68 | }); 69 | } 70 | } 71 | 72 | @Override 73 | public void deleteTable() { 74 | String dropTableSql = String.format("DROP TABLE %s", mTableName); 75 | mDb.execSQL(dropTableSql); 76 | } 77 | 78 | @Override 79 | public long insert(T model) { 80 | ContentValues contentValues = new ContentValues(); 81 | SqlHelper.parseModelToContentValues(model, contentValues); 82 | return mDb.insert(mTableName, contentValues); 83 | } 84 | 85 | @Override 86 | public boolean batchInsert(List dataList) { 87 | List listVal = new ArrayList(); 88 | for (T model : dataList) { 89 | ContentValues contentValues = new ContentValues(); 90 | SqlHelper.parseModelToContentValues(model, contentValues); 91 | listVal.add(contentValues); 92 | } 93 | return mDb.batchInsert(mTableName, listVal); 94 | } 95 | 96 | @Override 97 | public int update(T model, String whereClause, String... whereArgs) { 98 | ContentValues contentValues = new ContentValues(); 99 | SqlHelper.parseModelToContentValues(model, contentValues); 100 | return mDb.update(mTableName, contentValues, whereClause, whereArgs); 101 | } 102 | 103 | @Override 104 | public int delete(String whereClause, String... whereArgs) { 105 | return mDb.delete(mTableName, whereClause, whereArgs); 106 | } 107 | 108 | @Override 109 | public List query(String selection, String[] selectionArgs) { 110 | return query(null, selection, selectionArgs, null); 111 | } 112 | 113 | @Override 114 | public List query(String[] columns, String selection,String[] selectionArgs, 115 | String orderBy) { 116 | return query(columns, selection, selectionArgs, null, null, orderBy); 117 | } 118 | 119 | @Override 120 | public List query(String[] columns, String selection,String[] selectionArgs, 121 | String groupBy, String having, String orderBy) { 122 | List queryList = mDb.query(mTableName, columns, selection, selectionArgs, groupBy, having, orderBy); 123 | if(queryList == null || queryList.isEmpty()){ 124 | return null; 125 | } 126 | List resultList = new ArrayList(); 127 | SqlHelper.parseResultSetListToModelList(queryList, resultList, modelClazz); 128 | return resultList; 129 | } 130 | 131 | @Override 132 | public List execQuerySQL(String sql, String... bindArgs){ 133 | return mDb.execQuerySQL(sql, bindArgs); 134 | } 135 | 136 | @Override 137 | public boolean deleteAll() { 138 | return delete("1") == 1; 139 | } 140 | 141 | @Override 142 | public T queryFirstRecord(String selection, String... selectionArgs) { 143 | List resultList = query(selection, selectionArgs); 144 | if(resultList!=null && !resultList.isEmpty()){ 145 | return resultList.get(0); 146 | }else{ 147 | return null; 148 | } 149 | } 150 | 151 | @Override 152 | public T queryFirstRecord(String[] columns, String selection,String... selectionArgs) { 153 | List resultList = query(columns,selection,selectionArgs,null); 154 | if(resultList!=null && !resultList.isEmpty()){ 155 | return resultList.get(0); 156 | }else{ 157 | return null; 158 | } 159 | } 160 | 161 | @Override 162 | public List queryAll() { 163 | return query(null, null); 164 | } 165 | 166 | 167 | @Override 168 | public PagingList pagingQuery(String[] columns, String selection, 169 | String[] selectionArgs, String groupBy, String having, 170 | String orderBy, int page, int pageSize) { 171 | if(orderBy == null){ 172 | orderBy = SqlHelper.getPrimaryKey(modelClazz); 173 | } 174 | 175 | PagingList queryList = mDb.pagingQuery(mTableName, columns, selection, selectionArgs, 176 | groupBy, having, orderBy, page, pageSize); 177 | 178 | if(queryList == null){ 179 | return null; 180 | } 181 | 182 | PagingList resultList = new PagingList(); 183 | resultList.setTotalSize(queryList.getTotalSize()); 184 | SqlHelper.parseResultSetListToModelList(queryList, resultList, modelClazz); 185 | return resultList; 186 | } 187 | 188 | @Override 189 | public PagingList pagingQuery(String selection, String[] selectionArgs, int page, int pageSize) { 190 | return pagingQuery(null, selection, selectionArgs, null,page,pageSize); 191 | } 192 | 193 | @Override 194 | public PagingList pagingQuery(String[] columns, String selection, 195 | String[] selectionArgs, String orderBy, int page, int pageSize) { 196 | return pagingQuery(columns, selection, selectionArgs, null, null, orderBy, page, pageSize); 197 | } 198 | 199 | /** 200 | * get current table version 201 | * @return 202 | */ 203 | private int getCurTableVersion(){ 204 | Context ctx = mDb.getContext(); 205 | SharedPreferences tableVersions = ctx.getSharedPreferences(PREFS_TABLE_VERSION, Context.MODE_PRIVATE); 206 | return tableVersions.getInt(mTableName, 1); 207 | } 208 | 209 | /** 210 | * save table version 211 | * @param t_version 212 | */ 213 | private void saveTableVersion(int t_version){ 214 | Context ctx = mDb.getContext(); 215 | SharedPreferences tableVersions = ctx.getSharedPreferences(PREFS_TABLE_VERSION, Context.MODE_PRIVATE); 216 | SharedPreferences.Editor editor = tableVersions.edit(); 217 | editor.putInt(mTableName, t_version); 218 | editor.commit(); 219 | } 220 | 221 | /** 222 | * get table columns in createSql 223 | * @param createSql 224 | * @return map, key is column name, value default true means need to delete 225 | */ 226 | private Map getTableColumnsInfo(String createSql){ 227 | String subSql = createSql.substring(createSql.indexOf('(') + 1, createSql.lastIndexOf(')')); 228 | String[] columnInfos = subSql.split(","); 229 | Map tableInfo = new HashMap(); 230 | 231 | String columnName; 232 | String columnInfo; 233 | for(int i = 0; i < columnInfos.length ; ++i){ 234 | columnInfo = columnInfos[i].trim(); 235 | columnName = columnInfo.substring(0, columnInfo.indexOf(' ')); 236 | tableInfo.put(columnName.toLowerCase(), true); 237 | } 238 | 239 | return tableInfo; 240 | } 241 | 242 | } 243 | -------------------------------------------------------------------------------- /library/src/main/java/io/github/yedaxia/sqliteutils/SqlHelper.java: -------------------------------------------------------------------------------- 1 | package io.github.yedaxia.sqliteutils; 2 | 3 | import android.content.ContentValues; 4 | 5 | import java.lang.reflect.Field; 6 | import java.util.ArrayList; 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | import io.github.yedaxia.sqliteutils.Table.Column; 11 | 12 | 13 | /** 14 | * 15 | * @author Darcy yeguozhong@yeah.net 16 | */ 17 | class SqlHelper { 18 | 19 | /** 20 | * according to the Class annotations to genarate sql of create table 21 | * @return sql to create table 22 | */ 23 | public static String getCreateTableSQL(Class clazz) { 24 | StringBuilder sqlBuidler = new StringBuilder(); 25 | Table table = clazz.getAnnotation(Table.class); 26 | sqlBuidler.append("CREATE TABLE IF NOT EXISTS "); 27 | sqlBuidler.append(table.name()); 28 | sqlBuidler.append("("); 29 | Field[] fields = clazz.getDeclaredFields(); 30 | for (Field field : fields) { 31 | if (field.isAccessible() == false) 32 | field.setAccessible(true); 33 | Table.Column column = field.getAnnotation(Table.Column.class); 34 | if (column == null) 35 | continue; 36 | sqlBuidler.append(column.name() + " "); 37 | sqlBuidler.append(column.type() + " "); 38 | if (!column.isNull()) { 39 | sqlBuidler.append(" NOT NULL "); 40 | } 41 | if (column.isPrimaryKey()) { 42 | sqlBuidler.append(" PRIMARY KEY "); 43 | } 44 | 45 | if(column.isUnique()){ 46 | sqlBuidler.append(" UNIQUE "); 47 | } 48 | 49 | if (!column.defaultValue().equals("null")) { 50 | sqlBuidler.append(" DEFAULT " + column.defaultValue()); 51 | } 52 | sqlBuidler.append(","); 53 | } 54 | sqlBuidler.deleteCharAt(sqlBuidler.lastIndexOf(",")); 55 | sqlBuidler.append(")"); 56 | return sqlBuidler.toString(); 57 | } 58 | 59 | /** 60 | * get table name 61 | * 62 | * @return 63 | */ 64 | public static String getTableName(Class clazz) { 65 | Table table = clazz.getAnnotation(Table.class); 66 | return table.name(); 67 | } 68 | 69 | /** 70 | * return table version 71 | * @param clazz 72 | * @return 73 | */ 74 | public static int getTableVersion(Class clazz){ 75 | Table table = clazz.getAnnotation(Table.class); 76 | return table.version(); 77 | } 78 | 79 | /** 80 | * return info about table's all columns 81 | * @param clazz 82 | * @return 83 | */ 84 | public static List getTableColumnInfos(Class clazz){ 85 | Field[] fields = clazz.getDeclaredFields(); 86 | List columnInfos = new ArrayList(); 87 | for (Field field : fields) { 88 | if (field.isAccessible() == false) 89 | field.setAccessible(true); 90 | Table.Column column = field.getAnnotation(Table.Column.class); 91 | if (column == null) 92 | continue; 93 | 94 | ColumnInfo columnInfo = new ColumnInfo(); 95 | columnInfo.setName(column.name()); 96 | columnInfo.setType(column.type()); 97 | columnInfo.setNull(column.isNull()); 98 | columnInfo.setPrimaryKey(column.isPrimaryKey()); 99 | columnInfo.setUnique(column.isUnique()); 100 | columnInfo.setDefaultValue(column.defaultValue()); 101 | columnInfos.add(columnInfo); 102 | } 103 | return columnInfos; 104 | } 105 | 106 | /** 107 | * return sql of add a columm to table 108 | * @param table 109 | * @param columnInfo 110 | * @return 111 | */ 112 | public static String getAddColumnSql(String table ,ColumnInfo columnInfo){ 113 | StringBuilder sbSql = new StringBuilder(); 114 | sbSql.append(String.format("ALTER TABLE %s ADD %s %s ", table, columnInfo.getName(),columnInfo.getType())); 115 | if (!columnInfo.isNull()) { 116 | sbSql.append(" NOT NULL "); 117 | } 118 | if (columnInfo.isPrimaryKey()) { 119 | sbSql.append(" PRIMARY KEY "); 120 | } 121 | 122 | if(columnInfo.isUnique()){ 123 | sbSql.append(" UNIQUE "); 124 | } 125 | 126 | if (!columnInfo.getDefaultValue().equals("null")) { 127 | sbSql.append(" DEFAULT " + columnInfo.getDefaultValue()); 128 | } 129 | 130 | sbSql.append(";"); 131 | 132 | return sbSql.toString(); 133 | } 134 | 135 | /** 136 | * get primary key 137 | * 138 | * @param clazz 139 | * @return 140 | */ 141 | public static String getPrimaryKey(Class clazz){ 142 | Field[] fields = clazz.getDeclaredFields(); 143 | for (Field field : fields) { 144 | if (field.isAccessible() == false) 145 | field.setAccessible(true); 146 | Table.Column column = field.getAnnotation(Column.class); 147 | if (column == null) 148 | continue; 149 | if (column.isPrimaryKey()) { 150 | return column.name(); 151 | } 152 | } 153 | return null; 154 | } 155 | 156 | /** 157 | * use reflection to parse model's value to contentValues 158 | * @param model 159 | */ 160 | public static void parseModelToContentValues(Object model, 161 | ContentValues contentValues) { 162 | if (contentValues.size() > 0) 163 | contentValues.clear(); 164 | 165 | Class clazz = model.getClass(); 166 | Field[] fields = clazz.getDeclaredFields(); 167 | 168 | Class fieldType = null; 169 | Object fieldVal = null; 170 | 171 | for (Field field : fields) { 172 | try { 173 | if (field.isAccessible() == false) 174 | field.setAccessible(true); 175 | Column column = field.getAnnotation(Column.class); 176 | fieldType = field.getType(); 177 | fieldVal = field.get(model); 178 | if (column == null || fieldVal == null) 179 | continue; 180 | 181 | if (fieldType.equals(int.class)) { 182 | contentValues.put(column.name(), field.getInt(model)); 183 | } else if (fieldType.equals(Integer.class)) { 184 | contentValues.put(column.name(), (Integer) field.get(model)); 185 | } else if (fieldType.equals(short.class)) { 186 | contentValues.put(column.name(), field.getShort(model)); 187 | } else if (fieldType.equals(Short.class)) { 188 | contentValues.put(column.name(), (Short) field.get(model)); 189 | } else if (fieldType.equals(long.class)) { 190 | contentValues.put(column.name(), field.getLong(model)); 191 | } else if (fieldType.equals(Long.class)) { 192 | contentValues.put(column.name(), (Long) field.get(model)); 193 | } else if (fieldType.equals(float.class)) { 194 | contentValues.put(column.name(), field.getFloat(model)); 195 | } else if (fieldType.equals(Float.class)) { 196 | contentValues.put(column.name(), (Float) field.get(model)); 197 | } else if (fieldType.equals(double.class)) { 198 | contentValues.put(column.name(), field.getDouble(model)); 199 | } else if (fieldType.equals(Double.class)) { 200 | contentValues.put(column.name(), (Double) field.get(model)); 201 | } else if (fieldType.equals(boolean.class)) { 202 | if (field.getBoolean(model) == true) { 203 | contentValues.put(column.name(), "1"); 204 | } else { 205 | contentValues.put(column.name(), "0"); 206 | } 207 | } else if (fieldType.equals(Boolean.class)) { 208 | if ((Boolean) field.get(model) == true) { 209 | contentValues.put(column.name(), "1"); 210 | } else { 211 | contentValues.put(column.name(), "0"); 212 | } 213 | } else if (fieldType.equals(String.class)) { 214 | contentValues.put(column.name(), (String) field.get(model)); 215 | } else if (fieldType.equals(byte[].class)) { 216 | contentValues.put(column.name(), (byte[]) field.get(model)); 217 | } else if(fieldType.equals(Date.class)){ 218 | Date date = (Date)field.get(model); 219 | contentValues.put(column.name(),DateUtils.formatDate2Str(date)); 220 | } 221 | } catch (IllegalArgumentException e) { 222 | e.printStackTrace(); 223 | } catch (IllegalAccessException e) { 224 | e.printStackTrace(); 225 | } 226 | } 227 | } 228 | 229 | /** 230 | * use reflection to parse queryResult's value into model 231 | * @param queryResult 232 | * @param model 233 | */ 234 | public static void parseResultSetToModel(ResultSet queryResult, 235 | Object model) { 236 | Class clazz = model.getClass(); 237 | Field[] fields = clazz.getDeclaredFields(); 238 | 239 | Object fieldVal = null; 240 | Class fieldType = null; 241 | try { 242 | for (Field field : fields) { 243 | if (field.isAccessible() == false) 244 | field.setAccessible(true); 245 | Column column = field.getAnnotation(Column.class); 246 | if (column == null) 247 | continue; 248 | String columnName = column.name(); 249 | fieldVal = queryResult.getValue(columnName); 250 | fieldType = field.getType(); 251 | if (fieldVal != null) { 252 | if (fieldType.equals(fieldVal.getClass())) { 253 | field.set(model, fieldVal); 254 | } else if (fieldType.equals(short.class)) { 255 | field.setShort(model,queryResult.getShortValue(columnName)); 256 | } else if (fieldType.equals(Short.class)) { 257 | field.set(model, (Short) queryResult.getShortValue(columnName)); 258 | } else if (fieldType.equals(int.class)) { 259 | field.setInt(model,queryResult.getIntValue(columnName)); 260 | } else if (fieldType.equals(Integer.class)) { 261 | field.set(model, (Integer) queryResult.getIntValue(columnName)); 262 | } else if (fieldType.equals(long.class)) { 263 | field.setLong(model, 264 | queryResult.getLongValue(columnName)); 265 | } else if (fieldType.equals(Long.class)) { 266 | field.set(model, (Long) queryResult 267 | .getLongValue(columnName)); 268 | } else if (fieldType.equals(float.class)) { 269 | field.setFloat(model, 270 | queryResult.getFloatValue(columnName)); 271 | } else if (fieldType.equals(Float.class)) { 272 | field.set(model, (Float) queryResult 273 | .getFloatValue(columnName)); 274 | } else if (fieldType.equals(double.class)) { 275 | field.setDouble(model, 276 | queryResult.getDoubleValue(columnName)); 277 | } else if (fieldType.equals(Double.class)) { 278 | field.set(model, (Double) queryResult 279 | .getDoubleValue(columnName)); 280 | } else if (fieldType.equals(boolean.class)) { 281 | field.setBoolean(model, 282 | queryResult.getBooleanValue(columnName)); 283 | } else if (fieldType.equals(Boolean.class)) { 284 | field.set(model, (Boolean) queryResult 285 | .getBooleanValue(columnName)); 286 | } else if (fieldType.equals(String.class)) { 287 | field.set(model,queryResult.getStringValue(columnName)); 288 | } else if(fieldType.equals(Date.class)){ 289 | field.set(model, queryResult.getDateValue(columnName)); 290 | } 291 | } 292 | } 293 | } catch (IllegalAccessException e) { 294 | e.printStackTrace(); 295 | } 296 | } 297 | 298 | /** 299 | * 300 | * @param queryResultList 301 | * @param mList 302 | * @param mdlType 303 | */ 304 | @SuppressWarnings({ "unchecked", "rawtypes" }) 305 | public static void parseResultSetListToModelList( 306 | List queryResultList, List mList, Class mdlType) { 307 | try { 308 | if (queryResultList == null || queryResultList.isEmpty()) 309 | return; 310 | for (ResultSet queryResult : queryResultList) { 311 | Object model = mdlType.newInstance(); 312 | parseResultSetToModel(queryResult, model); 313 | mList.add(model); 314 | } 315 | } catch (IllegalAccessException ex) { 316 | ex.printStackTrace(); 317 | } catch (InstantiationException e) { 318 | e.printStackTrace(); 319 | } 320 | } 321 | 322 | } 323 | -------------------------------------------------------------------------------- /library/src/main/java/io/github/yedaxia/sqliteutils/DbSqlite.java: -------------------------------------------------------------------------------- 1 | package io.github.yedaxia.sqliteutils; 2 | 3 | import android.content.ContentValues; 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.database.SQLException; 7 | import android.database.sqlite.SQLiteDatabase; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | /** 13 | * a simple class to encapsulate the db operations, remember : 14 | * don't forget to {@link #closeDB()} when you don't need to connect to database. 15 | * @author Darcy yeguozhong@yeah.net 16 | * 17 | */ 18 | public class DbSqlite { 19 | 20 | private Context mContext; 21 | 22 | private SQLiteDatabase mSQLiteDatabase; 23 | 24 | private String dbPath; 25 | 26 | /** 27 | * constructor would create or open the database 28 | * @param context 29 | * @param dbPath the path of db file 30 | */ 31 | public DbSqlite(Context context,String dbPath) { 32 | this.mContext = context; 33 | this.dbPath = dbPath; 34 | openDB(); 35 | } 36 | 37 | public DbSqlite(Context context, SQLiteDatabase db){ 38 | this.mContext = context; 39 | this.mSQLiteDatabase = db; 40 | this.dbPath = db.getPath(); 41 | openDB(); 42 | } 43 | 44 | public SQLiteDatabase getSQLiteDatabase(){ 45 | return mSQLiteDatabase; 46 | } 47 | 48 | Context getContext(){ 49 | return mContext; 50 | } 51 | 52 | /** 53 | * update a record 54 | * 55 | * @param table the table to update in 56 | * @param values a map from column names to new column values. null is a valid value that will be translated to NULL. 57 | * @param whereClause the optional WHERE clause to apply when updating. Passing null will update all rows. 58 | * @param whereArgs You may include ?s in the where clause, which will be replaced by the values from whereArgs. The values will be bound as Strings. 59 | * @return the number of rows affected , or -1 if an error occurred 60 | */ 61 | public int update(String table, ContentValues values,String whereClause, String[] whereArgs) { 62 | try { 63 | openDB(); 64 | return mSQLiteDatabase.update(table, values, whereClause, whereArgs); 65 | } catch (Exception ex) { 66 | ex.printStackTrace(); 67 | return -1; 68 | } 69 | } 70 | 71 | /** 72 | * insert a record 73 | * 74 | * @param table 75 | * @param values 76 | * @return the row ID of the newly inserted row, or -1 if an error occurred 77 | */ 78 | public long insert(String table, ContentValues values) { 79 | try { 80 | openDB(); 81 | return mSQLiteDatabase.insertOrThrow(table, null, values); 82 | } catch (Exception ex) { 83 | ex.printStackTrace(); 84 | return -1; 85 | } 86 | } 87 | 88 | /** 89 | * 90 | * insert or replace a record by if its value of primary key has exsits 91 | * 92 | * @param table 93 | * @param values 94 | * @return the row ID of the newly inserted row, or -1 if an error occurred 95 | */ 96 | public long insertOrReplace(String table, ContentValues values){ 97 | try { 98 | openDB(); 99 | return mSQLiteDatabase.replaceOrThrow(table, null, values); 100 | } catch (SQLException ex) { 101 | ex.printStackTrace(); 102 | throw ex; 103 | } 104 | } 105 | 106 | /** 107 | * insert mutil records at one time 108 | * @param table 109 | * @param listVal 110 | * @return success return true 111 | */ 112 | public boolean batchInsert(final String table,final List listVal){ 113 | try { 114 | openDB(); 115 | DBTransaction.transact(this , new DBTransaction.DBTransactionInterface(){ 116 | @Override 117 | public void onTransact() { 118 | for (ContentValues contentValues : listVal) { 119 | mSQLiteDatabase.insertOrThrow(table, null, contentValues); 120 | } 121 | } 122 | }); 123 | return true; 124 | } catch (SQLException ex) { 125 | ex.printStackTrace(); 126 | throw ex; 127 | } 128 | } 129 | 130 | /** 131 | * delele by the condition 132 | * 133 | * @param table table the table to delete from 134 | * @param whereClause whereClause the optional WHERE clause to apply when deleting. Passing null will delete all rows. 135 | * @param whereArgs whereArgs You may include ?s in the where clause, which will be replaced by the values from whereArgs. The values will be bound as Strings. 136 | * @return the number of rows affected if a whereClause is passed in, 0 otherwise. To remove all rows and get a count pass "1" as the whereClause. 137 | */ 138 | public int delete(String table, String whereClause, String[] whereArgs) { 139 | try { 140 | openDB(); 141 | return mSQLiteDatabase.delete(table, whereClause, whereArgs); 142 | } catch (SQLException ex) { 143 | ex.printStackTrace(); 144 | throw ex; 145 | } 146 | } 147 | 148 | /** 149 | * a more flexible query by condition 150 | * 151 | * @param table The table name to compile the query against. 152 | * @param columns A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn't going to be used. 153 | * @param selection A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table. 154 | * @param groupBy A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped. 155 | * @param having A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used. 156 | * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered. 157 | * @param selectionArgs selectionArgs You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings. 158 | * @return if exceptions happen or no match records, then return null 159 | */ 160 | public List query(String table, String[] columns, 161 | String selection,String[] selectionArgs, String groupBy, String having, String orderBy) { 162 | Cursor cursor = null; 163 | try { 164 | openDB(); 165 | cursor = mSQLiteDatabase.query(table, columns, selection, 166 | selectionArgs, groupBy, having, orderBy); 167 | if(cursor.getCount() < 1){ 168 | return null; 169 | }else{ 170 | List resultList = new ArrayList(); 171 | parseCursorToResult(cursor, resultList); 172 | return resultList; 173 | } 174 | } catch (SQLException ex) { 175 | ex.printStackTrace(); 176 | throw ex; 177 | } finally { 178 | if(cursor!=null) 179 | cursor.close(); 180 | } 181 | } 182 | 183 | /** 184 | * a simple query by condition 185 | * 186 | * @param table 187 | * @param columns 188 | * @param selection 189 | * @param selectionArgs 190 | * @return 191 | */ 192 | public List query(String table, String[] columns, 193 | String selection, String[] selectionArgs) { 194 | return query(table, columns, selection, selectionArgs, null, null, null); 195 | } 196 | 197 | /** 198 | * paging query 199 | * 200 | * @param table 201 | * @param columns 202 | * @param selection 203 | * @param selectionArgs 204 | * @param groupBy 205 | * @param having 206 | * @param orderBy cann't be null if define page and pageSize 207 | * @param page first page is 1 208 | * @param pageSize 209 | * @return 210 | */ 211 | public PagingList pagingQuery(String table, String[] columns, 212 | String selection,String[] selectionArgs, String groupBy, String having, String orderBy,int page,int pageSize){ 213 | 214 | if(orderBy == null && pageSize != 0) 215 | throw new SQLException("orderBy cann't be null if define page and pageSize"); 216 | 217 | String orderWithLimit; 218 | if(orderBy != null && pageSize != 0){ 219 | orderWithLimit = String.format("%s LIMIT %s , %s", orderBy, (page-1)*pageSize, pageSize); 220 | }else{ 221 | orderWithLimit = orderBy; 222 | } 223 | 224 | Cursor cursor = null; 225 | Cursor totalCursor = null; 226 | try { 227 | openDB(); 228 | 229 | PagingList resultList = new PagingList(); 230 | 231 | totalCursor = mSQLiteDatabase.query(table, new String[]{"count(*) as totalSize"}, selection, 232 | selectionArgs, groupBy, having,null); 233 | 234 | if(totalCursor.moveToNext()){ 235 | int totalSize = totalCursor.getInt(0); 236 | resultList.setTotalSize(totalSize); 237 | } 238 | 239 | cursor = mSQLiteDatabase.query(table, columns, selection, 240 | selectionArgs, groupBy, having, orderWithLimit); 241 | 242 | if(cursor.getCount() < 1){ 243 | return resultList; 244 | }else{ 245 | parseCursorToResult(cursor, resultList); 246 | return resultList; 247 | } 248 | } catch (SQLException ex) { 249 | ex.printStackTrace(); 250 | throw ex; 251 | } finally { 252 | if(cursor!=null) 253 | cursor.close(); 254 | if(totalCursor != null) 255 | totalCursor.close(); 256 | } 257 | } 258 | 259 | /** 260 | * Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE. 261 | * 262 | * @param sql 263 | * @param bindArgs 264 | * @return 265 | */ 266 | public boolean execSQL(String sql, Object... bindArgs) { 267 | try { 268 | openDB(); 269 | mSQLiteDatabase.execSQL(sql, bindArgs); 270 | return true; 271 | } catch (SQLException ex) { 272 | ex.printStackTrace(); 273 | throw ex; 274 | } 275 | } 276 | 277 | /** 278 | * execute raw query sql 279 | * 280 | * @param sql the SQL query. The SQL string must not be ; terminated 281 | * @param bindArgs You may include ?s in where clause in the query, which will be replaced by the values from selectionArgs. The values will be bound as Strings. 282 | * @return return result as List or null 283 | */ 284 | public List execQuerySQL(String sql, String... bindArgs){ 285 | Cursor cursor = null; 286 | try{ 287 | openDB(); 288 | cursor = mSQLiteDatabase.rawQuery(sql, bindArgs); 289 | if(cursor.getCount() < 1){ 290 | return null; 291 | } 292 | List resultList = new ArrayList(); 293 | parseCursorToResult(cursor, resultList); 294 | return resultList; 295 | }catch(SQLException ex) { 296 | ex.printStackTrace(); 297 | throw ex; 298 | }finally{ 299 | if(cursor!=null) 300 | cursor.close(); 301 | } 302 | 303 | } 304 | 305 | /** 306 | * open database 307 | */ 308 | public void openDB() { 309 | if (mSQLiteDatabase == null || mSQLiteDatabase.isOpen() == false) 310 | mSQLiteDatabase = SQLiteDatabase.openOrCreateDatabase(dbPath, null); 311 | } 312 | 313 | /** 314 | * close database 315 | */ 316 | public void closeDB() { 317 | if (mSQLiteDatabase != null && mSQLiteDatabase.isOpen()) { 318 | mSQLiteDatabase.close(); 319 | } 320 | } 321 | 322 | 323 | public String getDbPath() { 324 | return dbPath; 325 | } 326 | 327 | /** 328 | * set data in cursor to ResultSet List 329 | * @param cursor 330 | * @param resultList the data will set in it 331 | */ 332 | private void parseCursorToResult(Cursor cursor,List resultList){ 333 | int columnCount; 334 | int columnType; 335 | Object columnVal = null; 336 | while (cursor.moveToNext()) { 337 | columnCount = cursor.getColumnCount(); 338 | ResultSet result = new ResultSet(); 339 | for (int index = 0; index < columnCount; ++index) { 340 | columnType = cursor.getType(index); 341 | switch (columnType) { 342 | case Cursor.FIELD_TYPE_BLOB: 343 | columnVal = cursor.getBlob(index); 344 | break; 345 | case Cursor.FIELD_TYPE_FLOAT: 346 | columnVal = cursor.getDouble(index); 347 | break; 348 | case Cursor.FIELD_TYPE_INTEGER: 349 | columnVal = cursor.getLong(index); 350 | break; 351 | case Cursor.FIELD_TYPE_NULL: 352 | columnVal = null; 353 | break; 354 | default: 355 | columnVal = cursor.getString(index); 356 | break; 357 | } 358 | result.setValue(cursor.getColumnName(index), columnVal); 359 | } 360 | resultList.add(result); 361 | } 362 | } 363 | } 364 | --------------------------------------------------------------------------------