├── library
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── android
│ │ │ └── sqlite
│ │ │ └── orm
│ │ │ ├── OnDBUpgrade.java
│ │ │ ├── IDColumn.java
│ │ │ ├── DBFile.java
│ │ │ ├── OpenHelper.java
│ │ │ ├── DBContextUse.java
│ │ │ ├── DBContext.java
│ │ │ ├── OpenHelperProxy.java
│ │ │ ├── ClassInfo.java
│ │ │ └── DBProxy.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── sanders
│ │ └── db
│ │ └── sanders
│ │ └── com
│ │ └── library
│ │ └── ApplicationTest.java
├── build.gradle
├── proguard-rules.pro
└── gradle.properties
├── sample
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ └── layout
│ │ │ │ └── activity_simple.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── sanders
│ │ │ │ └── db
│ │ │ │ └── simple
│ │ │ │ ├── TableBean.java
│ │ │ │ ├── TableModel.java
│ │ │ │ └── SimpleActivity.java
│ │ └── AndroidManifest.xml
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── sanders
│ │ └── db
│ │ └── sanders
│ │ └── com
│ │ └── dbproject
│ │ └── ApplicationTest.java
├── build.gradle
└── proguard-rules.pro
├── settings.gradle
├── .gitignore
├── gradle.properties
├── README.md
└── LICENSE
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':sample', ':library'
2 |
--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | local.properties
3 | .idea
4 | .DS_Store
5 | build
6 | *.iml
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | DBProject
3 |
4 |
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sopage/android-orm/HEAD/sample/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sopage/android-orm/HEAD/sample/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sopage/android-orm/HEAD/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Sopage/android-orm/HEAD/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/library/src/androidTest/java/com/sanders/db/sanders/com/library/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.sanders.db.sanders.com.library;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/sample/src/androidTest/java/com/sanders/db/sanders/com/dbproject/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.sanders.db.sanders.com.dbproject;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/library/src/main/java/android/sqlite/orm/OnDBUpgrade.java:
--------------------------------------------------------------------------------
1 | package android.sqlite.orm;
2 |
3 | import android.database.sqlite.SQLiteDatabase;
4 |
5 | /**
6 | * 数据库升级操作类
7 | * Created by sanders on 15/5/9.
8 | */
9 | public interface OnDBUpgrade {
10 |
11 | /**
12 | * 数据库升级调用此方法
13 | *
14 | * @param db
15 | * @param oldVersion
16 | * @param newVersion
17 | * @return true是手动升级,false是自动升级
18 | */
19 | boolean onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/sanders/db/simple/TableBean.java:
--------------------------------------------------------------------------------
1 | package com.sanders.db.simple;
2 |
3 | import android.sqlite.orm.IDColumn;
4 |
5 | import java.util.Date;
6 |
7 | /**
8 | * Created by sanders on 15/3/30.
9 | */
10 | public class TableBean extends IDColumn {
11 |
12 | private String fieldString;
13 | private short fieldShort;
14 | private int fieldInt;
15 | private long fieldLong;
16 | private double fieldDouble;
17 | private float fieldFloat;
18 | private byte[] fieldBytes;
19 | private boolean fieldBoolean;
20 | private Date fieldDate;
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | android {
3 | compileSdkVersion 15
4 | buildToolsVersion "22.0.1"
5 | defaultConfig {
6 | minSdkVersion 15
7 | targetSdkVersion 22
8 | versionCode 1
9 | versionName "1.0"
10 | }
11 | buildTypes {
12 | release {
13 | minifyEnabled false
14 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
15 | }
16 | }
17 | productFlavors {
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation fileTree(dir: 'libs', include: ['*.jar'])
23 | }
--------------------------------------------------------------------------------
/library/src/main/java/android/sqlite/orm/IDColumn.java:
--------------------------------------------------------------------------------
1 | package android.sqlite.orm;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 所有数据库表对应的实体类都要继承自此类
7 | * 此类只统一主键为primary_key而不是_id,这样以防ID冲突
8 | */
9 | public abstract class IDColumn implements Serializable {
10 |
11 | /**
12 | * 主键ID 自增长类型
13 | */
14 | public static final String PRIMARY_ID = "_id";
15 |
16 | /**
17 | * 主键ID 自增长类型
18 | */
19 | private long _id;
20 |
21 | public long getPrimaryId() {
22 | return _id;
23 | }
24 |
25 | public void setPrimaryId(long id) {
26 | this._id = id;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 15
5 | buildToolsVersion '22.0.1'
6 |
7 | defaultConfig {
8 | applicationId "com.sanders.db.simple"
9 | minSdkVersion 15
10 | targetSdkVersion 22
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | implementation fileTree(dir: 'libs', include: ['*.jar'])
24 | implementation project(':library')
25 | }
26 |
--------------------------------------------------------------------------------
/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 /Users/sanders/Developer/android-sdk-macosx/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 |
--------------------------------------------------------------------------------
/sample/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 /Users/sanders/Developer/android-sdk-macosx/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/gradle.properties:
--------------------------------------------------------------------------------
1 | VERSION_NAME=1.0-SNAPSHOT
2 |
3 | POM_GROUP=com.github.supersanders
4 | POM_ARTIFACT_ID=sqlite-orm
5 | POM_PACKAGING=aar
6 |
7 | POM_NAME=Android SQLite ORM
8 | POM_DESCRIPTION=Android SQLite ORM.
9 |
10 | POM_URL=https://github.com/SuperSanders/cube-orm
11 | POM_SCM_URL=https://github.com/SuperSanders/cube-orm
12 | POM_SCM_CONNECTION=scm:https://github.com/SuperSanders/cube-orm.git
13 | POM_SCM_DEV_CONNECTION=scm:https://github.com/SuperSanders/cube-orm.git
14 |
15 | POM_LICENCE_NAME=MIT
16 | POM_LICENCE_URL=http://opensource.org/licenses/MIT
17 | POM_LICENCE_DIST=repo
18 | POM_DEVELOPER_ID=Mr. Sanders
19 | POM_DEVELOPER_NAME=Mr. Sanders
20 |
21 | POM_ISSUE_SYSTEM=GitHub Issues
22 | POM_ISSUE_URL=https://github.com/SuperSanders/cube-orm/issues
23 |
--------------------------------------------------------------------------------
/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 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/library/src/main/java/android/sqlite/orm/DBFile.java:
--------------------------------------------------------------------------------
1 | package android.sqlite.orm;
2 |
3 | import android.database.sqlite.SQLiteDatabase;
4 |
5 | import java.io.File;
6 |
7 | /**
8 | * Created by sanders on 15/5/17.
9 | */
10 | public class DBFile {
11 |
12 | private File dbFile;
13 |
14 | public DBFile(File dbFile) {
15 | this.dbFile = dbFile;
16 | }
17 |
18 | public DBFile(String dbFilePath) {
19 | this.dbFile = new File(dbFilePath);
20 | }
21 |
22 | public DBProxy buildDBProxy() {
23 | DBProxy proxy = new DBProxy() {
24 | private SQLiteDatabase database;
25 |
26 | @Override
27 | public SQLiteDatabase getCreateDatabase() {
28 | if (database == null || !database.isOpen()) {
29 | database = SQLiteDatabase.openOrCreateDatabase(dbFile, null);
30 | }
31 | return database;
32 | }
33 | };
34 | return proxy;
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/library/src/main/java/android/sqlite/orm/OpenHelper.java:
--------------------------------------------------------------------------------
1 | package android.sqlite.orm;
2 |
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteDatabase;
5 | import android.database.sqlite.SQLiteOpenHelper;
6 |
7 | import java.util.Collection;
8 |
9 | /**
10 | * Created by sanders on 15/6/20.
11 | */
12 | public class OpenHelper extends SQLiteOpenHelper {
13 |
14 | private OnDBUpgrade mUpgrade;
15 | private Collection mSql;
16 |
17 | public OpenHelper(Context context, String name, int version) {
18 | super(context, name, null, version);
19 | }
20 |
21 | public void addCreateTableSqlList(Collection sql) {
22 | this.mSql = sql;
23 | }
24 |
25 | public void setOnUpgrade(OnDBUpgrade upgrade) {
26 | this.mUpgrade = upgrade;
27 | }
28 |
29 | @Override
30 | public void onCreate(SQLiteDatabase db) {
31 | for (String sql : mSql) {
32 | db.execSQL(sql);
33 | }
34 | }
35 |
36 | @Override
37 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
38 | if (mUpgrade != null) {
39 | mUpgrade.onUpgrade(db, oldVersion, newVersion);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/library/src/main/java/android/sqlite/orm/DBContextUse.java:
--------------------------------------------------------------------------------
1 | package android.sqlite.orm;
2 |
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteDatabase;
5 |
6 | import java.util.Collection;
7 | import java.util.LinkedHashSet;
8 |
9 | /**
10 | * Created by sanders on 15/6/20.
11 | */
12 | public class DBContextUse {
13 | private String name;
14 | private int version;
15 | private OnDBUpgrade upgrade;
16 | private Collection mSqlList = new LinkedHashSet();
17 |
18 | public DBContextUse(String name, int version, OnDBUpgrade upgrade) {
19 | this.name = name;
20 | this.version = version;
21 | this.upgrade = upgrade;
22 | }
23 |
24 | public DBContextUse addCreateTableSql(String sql) {
25 | this.mSqlList.add(sql);
26 | return this;
27 | }
28 |
29 | public DBProxy buildDBProxy(Context context) {
30 | final OpenHelper helper = new OpenHelper(context, name, version);
31 | helper.addCreateTableSqlList(mSqlList);
32 | helper.setOnUpgrade(upgrade);
33 | DBProxy proxy = new DBProxy() {
34 | @Override
35 | public SQLiteDatabase getCreateDatabase() {
36 | return helper.getWritableDatabase();
37 | }
38 | };
39 | return proxy;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/library/src/main/java/android/sqlite/orm/DBContext.java:
--------------------------------------------------------------------------------
1 | package android.sqlite.orm;
2 |
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteDatabase;
5 |
6 | import java.util.Collection;
7 | import java.util.LinkedHashSet;
8 |
9 | /**
10 | * Created by sanders on 15/5/17.
11 | */
12 | public class DBContext {
13 |
14 | private String name;
15 | private int version;
16 | private OnDBUpgrade upgrade;
17 | private Collection tableBeans = new LinkedHashSet();
18 |
19 | public DBContext(String name, int version, OnDBUpgrade upgrade) {
20 | this.name = name;
21 | this.version = version;
22 | this.upgrade = upgrade;
23 | }
24 |
25 | public DBContext addTableBean(Class clazz) {
26 | this.tableBeans.add(clazz);
27 | return this;
28 | }
29 |
30 | public DBProxy buildDBProxy(Context context) {
31 | final OpenHelperProxy helper = new OpenHelperProxy(context, name, version);
32 | helper.addTableBeans(tableBeans);
33 | helper.setOnUpgrade(upgrade);
34 | DBProxy proxy = new DBProxy() {
35 | @Override
36 | public SQLiteDatabase getCreateDatabase() {
37 | return helper.getWritableDatabase();
38 | }
39 | };
40 | helper.setDBProxy(proxy);
41 | return proxy;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_simple.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
19 |
20 |
25 |
26 |
31 |
32 |
37 |
38 |
43 |
44 |
49 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cube-orm [](https://996.icu)
2 | 此项目是为Android简单封装的SQLite数据库ORM, 实现自动建表和自动更新升级,实现基本的单表CRUD,提高数据库开发效率。
3 | ## 使用方法
4 | Android Studio引用方式:
5 |
6 | `compile 'com.github.supersanders:cube-orm:3.1@aar'`
7 |
8 | 混淆配置:
9 |
10 | `-keep public class * extends com.sanders.db.IDColumn`
11 | ### 约定:
12 | #### 所有的实体都要继承IDColumn.java类,并遵守以下命名规范:
13 | 表名称和Java类名称对应表:
14 |
15 | | 表名称 | Java类名 | 备注 |
16 | | --- | --- | --- |
17 | | table_name | TableName | 表名称必须以小写字母开始,单词之间用“_”下划线分开(当然也可以全部小写不分开) |
18 |
19 | 表字段名称和Java类属性字段名称对应表:
20 |
21 | | 表字段 | Java字段 | 备注 |
22 | | --- | --- | --- |
23 | | field_name | fieldName | 表字段名称必须以小写字母开始,单词之间用“_”下划线分开(当然也可以全部小写不分开)。按照Java驼峰命名规范命名Java字段属性名称 |
24 |
25 | 数据库创建方式:
26 |
27 | | 创建方式 | 说明 |
28 | | --- | --- |
29 | | 系统创建数据库 | 支持自动建表,自动升级。如果使用自动升级,若表字段类型有变则会重新创建新表并备份旧表为 `表名_oldVersion`,这需要手动将数据导入新表。 |
30 | | 外部数据库 | 不支持自动建表和升级。另外主键名称必须是`primary_key` |
31 |
32 | ##### 系统创建表
33 | //使用DBContext自动化创建表,每个表对应一个继承IDColumn.java类的POJO实体
34 | DBContext dbContext = new DBContext("数据库名称", 数据库名称, new OnDBUpgrade() {
35 | @Override
36 | public boolean onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
37 | //return false 自己处理升级,return true 自动处理
38 | return false;
39 | }
40 | });
41 | dbContext.addTableBean(TableModel.class).addTableBean(TableBean.class);
42 | DBProxy db = dbContext.buildDBProxy(this);
43 |
44 | //使用DBContextUse创建数据库
45 | DBContextUse dbContextUse = new DBContextUse("数据库名称", 数据库版本, OnDBUpgrade);
46 | dbContextUse.addSql(create table sql).addSql(create table sql);
47 | DBProxy db = dbContextUse.buildDBProxy(getApplicationContext());
48 | ##### 设置外部数据库,主键名称必须是`primary_key`
49 | DBFile dbFile = new DBFile(file path or File);
50 | DBProxy db = dbFile.buildDBProxy();
51 | ##### `DBProxy.java`类包涵了所有数据库操作
52 |
53 | # [](https://github.com/996icu/996.ICU/blob/master/LICENSE)
54 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/sanders/db/simple/TableModel.java:
--------------------------------------------------------------------------------
1 | package com.sanders.db.simple;
2 |
3 | import android.sqlite.orm.IDColumn;
4 |
5 | /**
6 | * Created by sanders on 15/3/28.
7 | */
8 | public class TableModel extends IDColumn {
9 |
10 | private Short fieldShort;
11 | private Integer fieldInt;
12 | private Long fieldLong;
13 | private Double fieldDouble;
14 | private Float fieldFloat;
15 | private Boolean fieldBoolean;
16 |
17 | public TableModel() {
18 | }
19 |
20 | public TableModel(long primaryKey, Short fieldShort, Integer fieldInt, Long fieldLong, Double fieldDouble, Float fieldFloat, Boolean fieldBoolean) {
21 | setPrimaryId(primaryKey);
22 | this.fieldShort = fieldShort;
23 | this.fieldInt = fieldInt;
24 | this.fieldLong = fieldLong;
25 | this.fieldDouble = fieldDouble;
26 | this.fieldFloat = fieldFloat;
27 | this.fieldBoolean = fieldBoolean;
28 | }
29 |
30 | public TableModel(Short fieldShort, Integer fieldInt, Long fieldLong, Double fieldDouble, Float fieldFloat, Boolean fieldBoolean) {
31 | this.fieldShort = fieldShort;
32 | this.fieldInt = fieldInt;
33 | this.fieldLong = fieldLong;
34 | this.fieldDouble = fieldDouble;
35 | this.fieldFloat = fieldFloat;
36 | this.fieldBoolean = fieldBoolean;
37 | }
38 |
39 | public Short getFieldShort() {
40 | return fieldShort;
41 | }
42 |
43 | public void setFieldShort(Short fieldShort) {
44 | this.fieldShort = fieldShort;
45 | }
46 |
47 | public Integer getFieldInt() {
48 | return fieldInt;
49 | }
50 |
51 | public void setFieldInt(Integer fieldInt) {
52 | this.fieldInt = fieldInt;
53 | }
54 |
55 | public Long getFieldLong() {
56 | return fieldLong;
57 | }
58 |
59 | public void setFieldLong(Long fieldLong) {
60 | this.fieldLong = fieldLong;
61 | }
62 |
63 | public Double getFieldDouble() {
64 | return fieldDouble;
65 | }
66 |
67 | public void setFieldDouble(Double fieldDouble) {
68 | this.fieldDouble = fieldDouble;
69 | }
70 |
71 | public Float getFieldFloat() {
72 | return fieldFloat;
73 | }
74 |
75 | public void setFieldFloat(Float fieldFloat) {
76 | this.fieldFloat = fieldFloat;
77 | }
78 |
79 | public Boolean getFieldBoolean() {
80 | return fieldBoolean;
81 | }
82 |
83 | public void setFieldBoolean(Boolean fieldBoolean) {
84 | this.fieldBoolean = fieldBoolean;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/library/src/main/java/android/sqlite/orm/OpenHelperProxy.java:
--------------------------------------------------------------------------------
1 | package android.sqlite.orm;
2 |
3 | import android.content.Context;
4 | import android.database.Cursor;
5 | import android.database.sqlite.SQLiteDatabase;
6 | import android.database.sqlite.SQLiteOpenHelper;
7 |
8 | import java.lang.reflect.Field;
9 | import java.util.ArrayList;
10 | import java.util.Collection;
11 | import java.util.HashMap;
12 | import java.util.List;
13 | import java.util.Map;
14 |
15 | /**
16 | * Created by sanders on 15/3/30.
17 | */
18 | public class OpenHelperProxy extends SQLiteOpenHelper {
19 |
20 | private Collection mClasses;
21 | private OnDBUpgrade mUpgrade;
22 | private DBProxy mProxy;
23 |
24 | public OpenHelperProxy(Context context, String dbName, int dbVersion) {
25 | super(context, dbName, null, dbVersion);
26 | }
27 |
28 | public void addTableBeans(Collection classes) {
29 | this.mClasses = classes;
30 | }
31 |
32 | public void setOnUpgrade(OnDBUpgrade upgrade) {
33 | this.mUpgrade = upgrade;
34 | }
35 |
36 | public void setDBProxy(DBProxy proxy) {
37 | this.mProxy = proxy;
38 | }
39 |
40 | @Override
41 | public void onCreate(SQLiteDatabase db) {
42 | for (Class clazz : mClasses) {
43 | ClassInfo classInfo = mProxy.getClassInfo(clazz);
44 | String sql = classInfo.getCreateTableSql();
45 | db.execSQL(sql);
46 | }
47 | }
48 |
49 | private void upgrade(SQLiteDatabase db, int oldVersion) {
50 | List sqlList = new ArrayList();
51 | for (Class clazz : mClasses) {
52 | sqlList.clear();
53 | ClassInfo classInfo = mProxy.getClassInfo(clazz);
54 | String tableName = classInfo.getTableName();
55 | Cursor cursor = db.rawQuery("PRAGMA table_info(`" + tableName + "`)", null);//查询表结构
56 | if (cursor.getCount() < 1) {
57 | continue;
58 | }
59 | Map dbFieldMap = new HashMap();
60 | while (cursor.moveToNext()) {
61 | String name = cursor.getString(cursor.getColumnIndex("name"));
62 | String type = cursor.getString(cursor.getColumnIndex("type"));
63 | dbFieldMap.put(name, type);
64 | }
65 | cursor.close();
66 | Map fieldMap = classInfo.getFieldMap();
67 | //更新数据库字段及字段类型
68 | for (Map.Entry entry : fieldMap.entrySet()) {
69 | if (!dbFieldMap.containsKey(entry.getKey())) {
70 | sqlList.add("ALTER TABLE `" + tableName + "` ADD COLUMN `" + entry.getKey() + "` " + ClassInfo.getDBFieldType(entry.getValue()) + ";");
71 | } else if (!dbFieldMap.get(entry.getKey()).equals(ClassInfo.getDBFieldType(entry.getValue()))) {
72 | sqlList.clear();
73 | sqlList.add("ALTER TABLE `" + tableName + "` RENAME TO `" + tableName + "_" + oldVersion + "`;");
74 | break;
75 | }
76 | }
77 | for (String sql : sqlList) {
78 | db.execSQL(sql);
79 | }
80 | }
81 | }
82 |
83 |
84 | @Override
85 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
86 | if (mUpgrade == null || mUpgrade.onUpgrade(db, oldVersion, newVersion)) {
87 | this.upgrade(db, oldVersion);
88 | this.onCreate(db);
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/sanders/db/simple/SimpleActivity.java:
--------------------------------------------------------------------------------
1 | package com.sanders.db.simple;
2 |
3 | import android.app.Activity;
4 | import android.database.sqlite.SQLiteDatabase;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.widget.LinearLayout;
8 |
9 | import android.sqlite.orm.ClassInfo;
10 | import android.sqlite.orm.DBContext;
11 | import android.sqlite.orm.DBContextUse;
12 | import android.sqlite.orm.DBFile;
13 | import android.sqlite.orm.DBProxy;
14 | import android.sqlite.orm.OnDBUpgrade;
15 |
16 | /**
17 | * Created by sanders on 15/3/27.
18 | */
19 | public class SimpleActivity extends Activity implements View.OnClickListener {
20 |
21 | public DBProxy db;
22 | public DBProxy db2;
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | setContentView(R.layout.activity_simple);
28 | LinearLayout linearLayout = (LinearLayout) findViewById(R.id.layout);
29 | for (int i = 0; i < linearLayout.getChildCount(); i++) {
30 | linearLayout.getChildAt(i).setOnClickListener(this);
31 | }
32 |
33 | // DBContext dbContext = new DBContext("database", 3, new OnDBUpgrade() {
34 | // @Override
35 | // public boolean onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
36 | // return false;
37 | // }
38 | // });
39 | // dbContext.addTableBean(TableModel.class).addTableBean(TableBean.class);
40 | // db = dbContext.buildDBProxy(this);
41 | // dbContext = new DBContext("database", 3, null);
42 | // dbContext.addTableBean(TableModel.class).addTableBean(TableBean.class);
43 | // db2 = dbContext.buildDBProxy(this);
44 |
45 | DBContextUse dbContextUse = new DBContextUse("dbdbdbdbdbd", 1, null);
46 | dbContextUse.addCreateTableSql(new ClassInfo(TableBean.class).getCreateTableSql()).addCreateTableSql(new ClassInfo(TableModel.class).getCreateTableSql());
47 | db = dbContextUse.buildDBProxy(getApplicationContext());
48 | // DBFile dbFile = new DBFile("/mnt/sdcard/database.db");
49 | // db = dbFile.buildDBProxy();
50 | // db.execSQL(new ClassInfo(TableModel.class).getCreateTableSql());
51 | // dbFile = new DBFile(new File("/mnt/sdcard/database.db"));
52 | // db2 = dbFile.buildDBProxy();
53 | }
54 |
55 | @Override
56 | public void onClick(View v) {
57 | int viewId = v.getId();
58 | switch (viewId) {
59 | case R.id.btn_insert:
60 | // for (int i = 0; i < 10; i++) {
61 | // new Thread() {
62 | // @Override
63 | // public void run() {
64 | // int j = 100;
65 | // do {
66 | // long count = db.queryCount(TableModel.class, null);
67 | // Log.e("ESA", "query count --------------" + count);
68 | // j--;
69 | // try {
70 | // Thread.sleep(10);
71 | // } catch (InterruptedException e) {
72 | // e.printStackTrace();
73 | // }
74 | // } while (j > 0);
75 | // }
76 | // }.start();
77 | // new Thread() {
78 | // @Override
79 | // public void run() {
80 | // int j = 100;
81 | // do {
82 | long id = db.insert(new TableModel(Short.parseShort("1"), 1, 1l, 1d, 1f, true));
83 | // Log.e("ESA", "insert id++++++++++++" + id);
84 | // j--;
85 | // try {
86 | // Thread.sleep(10);
87 | // } catch (InterruptedException e) {
88 | // e.printStackTrace();
89 | // }
90 | // } while (j > 0);
91 | // }
92 | // }.start();
93 | // }
94 | break;
95 | case R.id.btn_insert_list:
96 | // Log.e("ESA", "db count=" + db.getOpenCount() + " db count=" + db.getOpenCount());
97 |
98 | // List list = new ArrayList();
99 | // list.add(new TableModel(Short.parseShort("1"), 1, 1l, 1d, 1f, true));
100 | // list.add(new TableModel(Short.parseShort("1"), 1, 1l, 1d, 1f, true));
101 | // list.add(new TableModel(Short.parseShort("1"), 1, 1l, 1d, 1f, true));
102 | // list.add(new TableModel(Short.parseShort("1"), 1, 1l, 1d, 1f, true));
103 | // list.add(new TableModel(Short.parseShort("1"), 1, 1l, 1d, 1f, true));
104 | // list.add(new TableModel(Short.parseShort("1"), 1, 1l, 1d, 1f, true));
105 | // db.insert(list);
106 |
107 | // db.insertOrUpdate(new TableModel(1, Short.parseShort("2"), 2, 2l, 2d, 2f, false));
108 |
109 | // Log.e("ESA",""+db.queryCount(TableModel.class, "field_boolean=?", db.getBooleanValue(false)));
110 |
111 | // Map map = db.query("SELECT * FROM table_model");
112 | // for(Map.Entry entry : map.entrySet()){
113 | // Log.e("ESA", "key=" + entry.getKey() + " value=" + entry.getValue());
114 | // }
115 |
116 | // Log.e("ESA", db.query(TableModel.class, 1).getFieldDouble().toString());
117 |
118 | break;
119 | case R.id.btn_update:
120 | break;
121 | case R.id.btn_update_list:
122 | break;
123 | case R.id.btn_delete:
124 | break;
125 | case R.id.btn_query:
126 | break;
127 | case R.id.btn_query_list:
128 | break;
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/library/src/main/java/android/sqlite/orm/ClassInfo.java:
--------------------------------------------------------------------------------
1 | package android.sqlite.orm;
2 |
3 | import android.content.ContentValues;
4 | import android.database.Cursor;
5 |
6 | import java.lang.reflect.Field;
7 | import java.util.ArrayList;
8 | import java.util.Date;
9 | import java.util.LinkedHashMap;
10 | import java.util.List;
11 | import java.util.Map;
12 |
13 | /**
14 | * Created by sanders on 15/4/4.
15 | */
16 | public class ClassInfo {
17 |
18 | private Class mClass;
19 | private String mTableName;
20 | private Map mFieldMap = new LinkedHashMap();
21 |
22 | public ClassInfo(Class clazz) {
23 | this.mClass = clazz;
24 | this.mTableName = conversionClassNameToTableName(clazz.getName());
25 | try {
26 | Field superField = clazz.getSuperclass().getDeclaredField(IDColumn.PRIMARY_ID);
27 | superField.setAccessible(true);
28 | mFieldMap.put(IDColumn.PRIMARY_ID, superField);
29 | } catch (NoSuchFieldException e) {
30 | e.printStackTrace();
31 | }
32 | Field[] fields = clazz.getDeclaredFields();
33 | for (Field field : fields) {
34 | int modifiers = field.getModifiers();
35 | if (modifiers == 25 || modifiers == 26 || modifiers == 28) {
36 | continue;
37 | }
38 | field.setAccessible(true);
39 | mFieldMap.put(conversionJavaFieldNameToDBFieldName(field.getName()), field);
40 | }
41 | }
42 |
43 | public String getTableName() {
44 | return mTableName;
45 | }
46 |
47 | public Map getFieldMap() {
48 | return mFieldMap;
49 | }
50 |
51 | public ContentValues getContentValues(T t) {
52 | ContentValues values = new ContentValues();
53 | for (Map.Entry entry : mFieldMap.entrySet()) {
54 | try {
55 | String key = entry.getKey();
56 | if (IDColumn.PRIMARY_ID.equals(key)) {
57 | continue;
58 | }
59 | putFieldValue(key, entry.getValue(), t, values);
60 | } catch (IllegalAccessException e) {
61 | e.printStackTrace();
62 | }
63 | }
64 | return values;
65 | }
66 |
67 | public T getInstanceObject(Cursor cursor) {
68 | try {
69 | String[] columnNames = cursor.getColumnNames();
70 | if (cursor.moveToNext()) {
71 | T t = mClass.newInstance();
72 | for (String columnName : columnNames) {
73 | int index = cursor.getColumnIndex(columnName);
74 | Field field;
75 | if (IDColumn.PRIMARY_ID.equals(columnName)) {
76 | field = mFieldMap.get(IDColumn.PRIMARY_ID);
77 | } else {
78 | field = mFieldMap.get(columnName);
79 | }
80 | if (field != null) {
81 | setFieldValue(t, field, cursor, index);
82 | }
83 | }
84 | return t;
85 | }
86 | } catch (Exception e) {
87 | e.printStackTrace();
88 | }
89 | return null;
90 | }
91 |
92 | public List getInstanceList(Cursor cursor) {
93 | List list = new ArrayList();
94 | String[] columnNames = cursor.getColumnNames();
95 | while (cursor.moveToNext()) {
96 | try {
97 | T t = mClass.newInstance();
98 | for (String columnName : columnNames) {
99 | int index = cursor.getColumnIndex(columnName);
100 | Field field;
101 | if (IDColumn.PRIMARY_ID.equals(columnName)) {
102 | field = mFieldMap.get(IDColumn.PRIMARY_ID);
103 | } else {
104 | field = mFieldMap.get(columnName);
105 | }
106 | if (field != null) {
107 | setFieldValue(t, field, cursor, index);
108 | }
109 | }
110 | list.add(t);
111 | } catch (Exception e) {
112 | e.printStackTrace();
113 | }
114 | }
115 | return list;
116 | }
117 |
118 | public String getCreateTableSql() {
119 | StringBuilder sql = new StringBuilder();
120 | sql.append("CREATE TABLE IF NOT EXISTS `").append(this.mTableName).append("` (`").append(IDColumn.PRIMARY_ID).append("` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT");
121 | for (Map.Entry entry : this.mFieldMap.entrySet()) {
122 | String javaField = entry.getKey();
123 | if (IDColumn.PRIMARY_ID.equals(javaField)) {
124 | continue;
125 | }
126 | String tableField = conversionJavaFieldNameToDBFieldName(javaField);
127 | sql.append(", `").append(tableField).append("` ").append(getDBFieldType(entry.getValue()));
128 | }
129 | sql.append(");");
130 | return sql.toString();
131 | }
132 |
133 | public static String getDBFieldType(Field field) {
134 | String type = "NULL";
135 | Class> classType = field.getType();
136 | if (classType.equals(String.class) || classType.equals(CharSequence.class)) {
137 | type = "TEXT";
138 | } else if (classType.equals(Integer.TYPE) || classType.equals(Integer.class) || classType.equals(Long.TYPE) || classType.equals(Long.class) || classType.equals(Short.TYPE) || classType.equals(Short.class) || classType.equals(Date.class) || classType.equals(Boolean.TYPE) || classType.equals(Boolean.class)) {
139 | type = "INTEGER";
140 | } else if (classType.equals(Double.TYPE) || classType.equals(Double.class) || classType.equals(Float.TYPE) || classType.equals(Float.class)) {
141 | type = "REAL";
142 | } else if (classType.equals(byte[].class)) {
143 | type = "BLOB";
144 | }
145 | return type;
146 | }
147 |
148 | private static void putFieldValue(String fieldName, Field field, T t, ContentValues values) throws IllegalAccessException {
149 | Class> classType = field.getType();
150 | if (classType.equals(Integer.TYPE)) {
151 | values.put(fieldName, field.getInt(t));
152 | } else if (classType.equals(Integer.class)) {
153 | Object value = field.get(t);
154 | if (value != null) {
155 | values.put(fieldName, (Integer) value);
156 | }
157 | } else if (classType.equals(String.class)) {
158 | Object value = field.get(t);
159 | if (value != null) {
160 | values.put(fieldName, (String) value);
161 | }
162 | } else if (classType.equals(Boolean.TYPE)) {
163 | values.put(fieldName, field.getBoolean(t));
164 | } else if (classType.equals(Boolean.class)) {
165 | Object value = field.get(t);
166 | if (value != null) {
167 | values.put(fieldName, (Boolean) value);
168 | }
169 | } else if (classType.equals(Long.TYPE)) {
170 | values.put(fieldName, field.getLong(t));
171 | } else if (classType.equals(Long.class)) {
172 | Object value = field.get(t);
173 | if (value != null) {
174 | values.put(fieldName, (Long) value);
175 | }
176 | } else if (classType.equals(Double.TYPE)) {
177 | values.put(fieldName, field.getDouble(t));
178 | } else if (classType.equals(Double.class)) {
179 | Object value = field.get(t);
180 | if (value != null) {
181 | values.put(fieldName, (Double) value);
182 | }
183 | } else if (classType.equals(Float.TYPE)) {
184 | values.put(fieldName, field.getFloat(t));
185 | } else if (classType.equals(Float.class)) {
186 | Object value = field.get(t);
187 | if (value != null) {
188 | values.put(fieldName, (Float) value);
189 | }
190 | } else if (classType.equals(byte[].class)) {
191 | Object value = field.get(t);
192 | if (value != null) {
193 | values.put(fieldName, (byte[]) value);
194 | }
195 | } else if (classType.equals(Short.TYPE)) {
196 | values.put(fieldName, field.getShort(t));
197 | } else if (classType.equals(Short.class)) {
198 | Object value = field.get(t);
199 | if (value != null) {
200 | values.put(fieldName, (Short) value);
201 | }
202 | } else if (classType.equals(Date.class)) {
203 | Object value = field.get(t);
204 | if (value != null) {
205 | values.put(fieldName, ((Date) value).getTime());
206 | }
207 | }
208 | }
209 |
210 | private static final void setFieldValue(T t, Field field, Cursor cursor, int index) throws IllegalAccessException {
211 | Class> classType = field.getType();
212 | if (classType.equals(Integer.TYPE) || classType.equals(Integer.class)) {
213 | field.set(t, cursor.getInt(index));
214 | } else if (classType.equals(String.class)) {
215 | field.set(t, cursor.getString(index));
216 | } else if (classType.equals(Boolean.TYPE) || classType.equals(Boolean.class)) {
217 | field.set(t, cursor.getInt(index) == 1 ? true : false);
218 | } else if (classType.equals(Long.TYPE) || classType.equals(Long.class)) {
219 | field.set(t, cursor.getLong(index));
220 | } else if (classType.equals(Double.TYPE) || classType.equals(Double.class)) {
221 | field.set(t, cursor.getDouble(index));
222 | } else if (classType.equals(Float.TYPE) || classType.equals(Float.class)) {
223 | field.set(t, cursor.getFloat(index));
224 | } else if (classType.equals(byte[].class)) {
225 | field.set(t, cursor.getBlob(index));
226 | } else if (classType.equals(Short.TYPE) || classType.equals(Short.class)) {
227 | field.set(t, cursor.getShort(index));
228 | } else if (classType.equals(Date.class)) {
229 | field.set(t, new Date(cursor.getLong(index)));
230 | }
231 | }
232 |
233 | public static String conversionClassNameToTableName(String className) {
234 | className = className.substring(className.lastIndexOf(".") + 1, className.length());
235 | char[] chars = className.toCharArray();
236 | StringBuilder sb = new StringBuilder();
237 | for (char c : chars) {
238 | if (Character.isUpperCase(c)) {
239 | sb.append("_").append(Character.toLowerCase(c));
240 | } else {
241 | sb.append(c);
242 | }
243 | }
244 | sb.delete(0, 1);
245 | return sb.toString();
246 | }
247 |
248 | public static String conversionJavaFieldNameToDBFieldName(String fieldName) {
249 | char[] chars = fieldName.toCharArray();
250 | StringBuilder sb = new StringBuilder();
251 | for (char c : chars) {
252 | if (Character.isUpperCase(c)) {
253 | sb.append("_").append(Character.toLowerCase(c));
254 | } else {
255 | sb.append(c);
256 | }
257 | }
258 | return sb.toString();
259 | }
260 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
--------------------------------------------------------------------------------
/library/src/main/java/android/sqlite/orm/DBProxy.java:
--------------------------------------------------------------------------------
1 | package android.sqlite.orm;
2 |
3 | import android.content.ContentValues;
4 | import android.database.Cursor;
5 | import android.database.sqlite.SQLiteDatabase;
6 |
7 | import java.util.ArrayList;
8 | import java.util.Collection;
9 | import java.util.HashMap;
10 | import java.util.List;
11 | import java.util.Map;
12 | import java.util.concurrent.atomic.AtomicLong;
13 |
14 | /**
15 | * Created by sanders on 15/5/17.
16 | */
17 | public abstract class DBProxy {
18 |
19 | /**
20 | * 数据库操作计数,防止异常关闭问题
21 | */
22 | private final AtomicLong mOpenCount = new AtomicLong(0);
23 |
24 | /**
25 | * 用于缓存实体类Class和实体类详情
26 | */
27 | private final Map mClassInfoMap = new HashMap<>();
28 |
29 | /**
30 | * 获取一个实体类Class的详细信息并缓存
31 | *
32 | * @param t
33 | * @param
34 | * @return
35 | */
36 | protected final ClassInfo getClassInfo(T t) {
37 | return this.getClassInfo(t.getClass());
38 | }
39 |
40 | /**
41 | * 获取一个实体类Class的详细信息并缓存
42 | *
43 | * @param clazz
44 | * @param
45 | * @return
46 | */
47 | protected final ClassInfo getClassInfo(Class clazz) {
48 | ClassInfo classInfo = mClassInfoMap.get(clazz);
49 | if (classInfo == null) {
50 | classInfo = new ClassInfo(clazz);
51 | }
52 | return classInfo;
53 | }
54 |
55 |
56 | /**
57 | * 插入对应实体到数据库
58 | *
59 | * @param t
60 | * @param
61 | * @return
62 | */
63 | public final long insert(T t) {
64 | if (t == null) {
65 | throw new NullPointerException("插入对象为NULL");
66 | }
67 | ClassInfo classInfo = getClassInfo(t);
68 | String tableName = classInfo.getTableName();
69 | ContentValues values = classInfo.getContentValues(t);
70 | if (values.size() > 0) {
71 | SQLiteDatabase database = getDatabase();
72 | database.beginTransaction();
73 | long id = database.insert(tableName, null, values);
74 | t.setPrimaryId(id);
75 | database.setTransactionSuccessful();
76 | database.endTransaction();
77 | close(database);
78 | return id;
79 | }
80 | return -1;
81 | }
82 |
83 | /**
84 | * 插入数据
85 | *
86 | * @param tableName
87 | * @param values
88 | * @return
89 | */
90 | public final long insert(String tableName, ContentValues values) {
91 | SQLiteDatabase database = getDatabase();
92 | long id = -1;
93 | database.beginTransaction();
94 | if (values.size() > 0) {
95 | id = database.insert(tableName, null, values);
96 | }
97 | database.setTransactionSuccessful();
98 | database.endTransaction();
99 | close(database);
100 | return id;
101 | }
102 |
103 | /**
104 | * 批量插入对应实体类到数据库。建议集合不要太大,这是一次性事务
105 | *
106 | * @param list
107 | * @param
108 | */
109 | public final void insert(Collection list) {
110 | if (isEmpty(list)) {
111 | return;
112 | }
113 | ClassInfo classInfo = getClassInfo(list.iterator().next());
114 | SQLiteDatabase database = getDatabase();
115 | database.beginTransaction();
116 | for (T t : list) {
117 | ContentValues values = classInfo.getContentValues(t);
118 | if (values.size() > 0) {
119 | long id = database.insert(classInfo.getTableName(), null, values);
120 | t.setPrimaryId(id);
121 | }
122 | }
123 | database.setTransactionSuccessful();
124 | database.endTransaction();
125 | close(database);
126 | }
127 |
128 |
129 | /**
130 | * 更具条件更新实体到数据库
131 | *
132 | * @param t
133 | * @param where
134 | * @param args
135 | * @param
136 | * @return
137 | */
138 | public final int update(T t, String where, String... args) {
139 | if (t == null) {
140 | throw new NullPointerException("更新对象为NULL!");
141 | }
142 | if (where == null || where.trim().length() < 1) {
143 | throw new NullPointerException("缺少WHERE条件语句!");
144 | }
145 | ClassInfo classInfo = getClassInfo(t);
146 | String tableName = classInfo.getTableName();
147 | ContentValues values = classInfo.getContentValues(t);
148 | if (values.size() < 1) {
149 | return -1;
150 | }
151 | values.remove(IDColumn.PRIMARY_ID);
152 | SQLiteDatabase database = getDatabase();
153 | database.beginTransaction();
154 | int row = database.update(tableName, values, where, args);
155 | database.setTransactionSuccessful();
156 | database.endTransaction();
157 | close(database);
158 | return row;
159 | }
160 |
161 | /**
162 | * 更新表数据
163 | *
164 | * @param tableName
165 | * @param values
166 | * @param where
167 | * @param args
168 | * @return
169 | */
170 | public final int update(String tableName, ContentValues values, String where, String... args) {
171 | SQLiteDatabase database = getDatabase();
172 | database.beginTransaction();
173 | int row = database.update(tableName, values, where, args);
174 | database.setTransactionSuccessful();
175 | database.endTransaction();
176 | close(database);
177 | return row;
178 | }
179 |
180 | /**
181 | * 更具实体中的主键(_key_id)更新实体到数据库
182 | *
183 | * @param t
184 | * @param
185 | * @return
186 | */
187 | public final int update(T t) {
188 | long primaryKey;
189 | if (t == null) {
190 | throw new NullPointerException("更新对象为NULL!");
191 | } else if ((primaryKey = t.getPrimaryId()) <= 0) {
192 | return -1;
193 | }
194 | return update(t, IDColumn.PRIMARY_ID + "=" + primaryKey);
195 | }
196 |
197 | /**
198 | * 更具实体中的主键更新实体到数据库
199 | *
200 | * @param t
201 | * @param keyId
202 | * @param
203 | * @return
204 | */
205 | public final int update(T t, long keyId) {
206 | return update(t, IDColumn.PRIMARY_ID + "=" + keyId);
207 | }
208 |
209 | /**
210 | * 更具集合实体中的主键(_key_id)更新实体到数据库
211 | *
212 | * @param list
213 | * @param
214 | */
215 | public final void update(List list) {
216 | if (isEmpty(list)) {
217 | return;
218 | }
219 | ClassInfo classInfo = getClassInfo(list.get(0));
220 | String tableName = classInfo.getTableName();
221 | SQLiteDatabase database = getDatabase();
222 | database.beginTransaction();
223 | for (T t : list) {
224 | long primaryKey = t.getPrimaryId();
225 | ContentValues values = classInfo.getContentValues(t);
226 | if (values.size() > 0 && primaryKey > 0) {
227 | values.remove(IDColumn.PRIMARY_ID);
228 | database.update(tableName, values, IDColumn.PRIMARY_ID + "=" + primaryKey, null);
229 | }
230 | }
231 | database.setTransactionSuccessful();
232 | database.endTransaction();
233 | close(database);
234 | }
235 |
236 | public final long insertOrUpdate(T t) {
237 | if (t == null) {
238 | return -1;
239 | }
240 | ClassInfo classInfo = getClassInfo(t);
241 | ContentValues values = classInfo.getContentValues(t);
242 | long rowId = -1;
243 | if (values.size() > 0) {
244 | if (t.getPrimaryId() > 0) {
245 | rowId = update(t);
246 | } else {
247 | rowId = insert(t);
248 | }
249 | }
250 | return rowId;
251 | }
252 |
253 | /**
254 | * 插入或者更新集合
255 | *
256 | * @param list
257 | * @param
258 | */
259 | public final void insertOrUpdate(List list) {
260 | if (isEmpty(list)) {
261 | return;
262 | }
263 | ClassInfo classInfo = getClassInfo(list.get(0));
264 | String tableName = classInfo.getTableName();
265 | SQLiteDatabase database = getDatabase();
266 | database.beginTransaction();
267 | for (T t : list) {
268 | ContentValues values = classInfo.getContentValues(t);
269 | if (values.size() > 0) {
270 | long primaryKey = t.getPrimaryId();
271 | if (primaryKey > 0) {
272 | database.update(tableName, values, IDColumn.PRIMARY_ID + "=" + primaryKey, null);
273 | } else {
274 | database.insert(tableName, null, values);
275 | }
276 | }
277 | }
278 | database.setTransactionSuccessful();
279 | database.endTransaction();
280 | close(database);
281 | }
282 |
283 | /**
284 | * 执行原生sql
285 | *
286 | * @param sql
287 | */
288 | public final void execSQL(String... sql) {
289 | SQLiteDatabase database = getDatabase();
290 | database.beginTransaction();
291 | for (String s : sql) {
292 | database.execSQL(s);
293 | }
294 | database.setTransactionSuccessful();
295 | database.endTransaction();
296 | close(database);
297 | }
298 |
299 | /**
300 | * 更具条件删除数据库内容
301 | *
302 | * @param clazz
303 | * @param where
304 | * @param args
305 | * @return
306 | */
307 | public final int delete(Class> clazz, String where, String... args) {
308 | String table = ClassInfo.conversionClassNameToTableName(clazz.getName());
309 | return delete(table, where, args);
310 | }
311 |
312 | /**
313 | * 根据主键删除数据库内容
314 | *
315 | * @param clazz
316 | * @param primaryKey
317 | * @return
318 | */
319 | public final int delete(Class> clazz, long primaryKey) {
320 | return delete(clazz, IDColumn.PRIMARY_ID + "=" + primaryKey);
321 | }
322 |
323 | /**
324 | * 更具条件删除数据库内容
325 | *
326 | * @param tableName
327 | * @param where
328 | * @param args
329 | * @return
330 | */
331 | public final int delete(String tableName, String where, String... args) {
332 | SQLiteDatabase database = getDatabase();
333 | database.beginTransaction();
334 | int row = database.delete(tableName, where, args);
335 | database.setTransactionSuccessful();
336 | database.endTransaction();
337 | close(database);
338 | return row;
339 | }
340 |
341 | /**
342 | * 查询数量
343 | *
344 | * @param clazz
345 | * @param where
346 | * @param args
347 | * @param
348 | * @return
349 | */
350 | public long queryCount(Class clazz, String where, String... args) {
351 | ClassInfo classInfo = getClassInfo(clazz);
352 | return queryCount(classInfo.getTableName(), where, args);
353 | }
354 |
355 | /**
356 | * 查询数量
357 | *
358 | * @param tableName
359 | * @param where
360 | * @param args
361 | * @return
362 | */
363 | public long queryCount(String tableName, String where, String... args) {
364 | SQLiteDatabase database = getDatabase();
365 | StringBuilder sql = new StringBuilder("SELECT COUNT(").append(IDColumn.PRIMARY_ID).append(") AS count FROM ");
366 | sql.append(tableName);
367 | if (where != null && where.trim().length() > 0) {
368 | sql.append(" WHERE ").append(where);
369 | }
370 | sql.append(";");
371 | Cursor cursor = database.rawQuery(sql.toString(), args);
372 | long count = 1;
373 | if (cursor.moveToNext()) {
374 | count = cursor.getLong(0);
375 | }
376 | close(cursor);
377 | close(database);
378 | return count;
379 | }
380 |
381 | /**
382 | * 查询主键
383 | *
384 | * @param clazz
385 | * @param where
386 | * @param args
387 | * @param
388 | * @return
389 | */
390 | public long queryPrimaryKey(Class clazz, String where, String... args) {
391 | ClassInfo classInfo = getClassInfo(clazz);
392 | return queryPrimaryKey(classInfo.getTableName(), where, args);
393 | }
394 |
395 | /**
396 | * 查询主键
397 | *
398 | * @param tableName
399 | * @param where
400 | * @param args
401 | * @return
402 | */
403 | public long queryPrimaryKey(String tableName, String where, String... args) {
404 | if (where == null) {
405 | throw new NullPointerException("缺少WHERE条件语句!");
406 | }
407 | SQLiteDatabase database = getDatabase();
408 | StringBuilder sql = new StringBuilder("SELECT ").append(IDColumn.PRIMARY_ID).append(" FROM ").append(tableName).append(" WHERE ").append(where);
409 | Cursor cursor = database.rawQuery(sql.toString(), args);
410 | long id = -1;
411 | if (cursor.moveToNext()) {
412 | id = cursor.getLong(0);
413 | }
414 | close(cursor);
415 | close(database);
416 | return id;
417 | }
418 |
419 | /**
420 | * 根据条件查询一条记录到实体
421 | *
422 | * @param clazz
423 | * @param where
424 | * @param args
425 | * @param
426 | * @return
427 | */
428 | public T query(Class clazz, String where, String... args) {
429 | SQLiteDatabase database = getDatabase();
430 | ClassInfo classInfo = getClassInfo(clazz);
431 | Cursor cursor = database.query(classInfo.getTableName(), null, where, args, null, null, null);
432 | T t = classInfo.getInstanceObject(cursor);
433 | close(cursor);
434 | close(database);
435 | return t;
436 | }
437 |
438 | /**
439 | * 根据主键查询实体
440 | *
441 | * @param clazz
442 | * @param primaryKey
443 | * @param
444 | * @return
445 | */
446 | public T query(Class clazz, long primaryKey) {
447 | return query(clazz, IDColumn.PRIMARY_ID + "=" + primaryKey);
448 | }
449 |
450 | /**
451 | * 根据sql语句查询实体
452 | *
453 | * @param clazz
454 | * @param sql
455 | * @param args
456 | * @param
457 | * @return
458 | */
459 | public T queryBySql(Class clazz, String sql, String... args) {
460 | SQLiteDatabase database = getDatabase();
461 | Cursor cursor = database.rawQuery(sql, args);
462 | ClassInfo classInfo = getClassInfo(clazz);
463 | T t = classInfo.getInstanceObject(cursor);
464 | close(cursor);
465 | close(database);
466 | return t;
467 | }
468 |
469 | /**
470 | * 根据sql语句查询实体集合
471 | *
472 | * @param clazz
473 | * @param sql
474 | * @param args
475 | * @param
476 | * @return
477 | */
478 | public List queryListBySql(Class clazz, String sql, String... args) {
479 | SQLiteDatabase database = getDatabase();
480 | Cursor cursor = database.rawQuery(sql, args);
481 | ClassInfo classInfo = getClassInfo(clazz);
482 | List list = classInfo.getInstanceList(cursor);
483 | close(cursor);
484 | close(database);
485 | return list;
486 | }
487 |
488 | /**
489 | * 更具条件插叙实体集合
490 | *
491 | * @param clazz
492 | * @param selection
493 | * @param selectionArgs
494 | * @param groupBy
495 | * @param having
496 | * @param orderBy
497 | * @param limit
498 | * @param
499 | * @return
500 | */
501 | public List queryList(Class clazz, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) {
502 | ClassInfo classInfo = getClassInfo(clazz);
503 | SQLiteDatabase database = getDatabase();
504 | Cursor cursor = database.query(classInfo.getTableName(), null, selection, selectionArgs, groupBy, having, orderBy, limit);
505 | List list = classInfo.getInstanceList(cursor);
506 | close(cursor);
507 | close(database);
508 | return list;
509 | }
510 |
511 | /**
512 | * 分页查询实体集合
513 | *
514 | * @param clazz
515 | * @param selection
516 | * @param pageNumber
517 | * @param pageSize
518 | * @param selectionArgs
519 | * @param
520 | * @return
521 | */
522 | public List queryList(Class clazz, String selection, int pageNumber, int pageSize, String... selectionArgs) {
523 | int startPosition = ((pageNumber - 1) * pageSize);
524 | return queryList(clazz, selection, selectionArgs, null, null, null, startPosition + "," + pageSize);
525 | }
526 |
527 | /**
528 | * 根据条件查询实体集合
529 | *
530 | * @param clazz
531 | * @param selection
532 | * @param selectionArgs
533 | * @param
534 | * @return
535 | */
536 | public List queryList(Class clazz, String selection, String... selectionArgs) {
537 | return queryList(clazz, selection, selectionArgs, null, null, null, null);
538 | }
539 |
540 | /**
541 | * 此方法适用于Build.VERSION_CODES.HONEYCOMB以上版本
542 | * 查询一条记录到Map
543 | *
544 | * @param sql
545 | * @param args
546 | * @return
547 | */
548 | public Map query(String sql, String... args) {
549 | SQLiteDatabase database = getDatabase();
550 | Cursor cursor = database.rawQuery(sql, args);
551 | String[] names = cursor.getColumnNames();
552 | Map map = null;
553 | if (cursor.moveToNext()) {
554 | map = new HashMap();
555 | for (String columnName : names) {
556 | this.putMapKeyValue(cursor, columnName, map);
557 | }
558 | }
559 | close(cursor);
560 | close(database);
561 | return map;
562 | }
563 |
564 | /**
565 | * 此方法适用于Build.VERSION_CODES.HONEYCOMB以上版本
566 | * 根据sql语句查询map到list
567 | *
568 | * @param sql
569 | * @param args
570 | * @return
571 | */
572 | public List