对于android–ORMLite–返回项目w/最大ID(或值)感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解android返回上一个activity,并且为您提供关于AndroidCon
对于android – ORMLite – 返回项目w /最大ID(或值)感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解android返回上一个activity,并且为您提供关于Android ContentProvider与ORMLite、Android greenDAO数据库开发梳理 : Android ORM for your SQLite database、Android ORM 框架之 LiteOrm 的使用心得、android ormlite – 存储字符串数组的宝贵知识。
本文目录一览:- android – ORMLite – 返回项目w /最大ID(或值)(android返回上一个activity)
- Android ContentProvider与ORMLite
- Android greenDAO数据库开发梳理 : Android ORM for your SQLite database
- Android ORM 框架之 LiteOrm 的使用心得
- android ormlite – 存储字符串数组
android – ORMLite – 返回项目w /最大ID(或值)(android返回上一个activity)
我正在使用Ormlite w / Android.我想获取具有最高值ID的对象的ID值.
我还想将此概括为请求任意字段的具有最大/最小值的单个对象.这样做的最佳做法是什么?
我意识到我可以执行一个原始查询,但还有其他任何方式可以跳出来吗?在iOS上的CoreData中执行FetchRequests时,我正在想象类似于Predicates的东西.
解决方法:
你的答案看起来不错@Ben但我想我会为后代提供一些额外的信息:
>如果您知道限制(1)将返回单个结果,则可以使用queryForFirst.
qBuilder.orderby("my_field_column_name", false);
qBuilder.limit(1L);
MyEntity maxEntity = myEntityDao.queryForFirst(qBuilder.prepare());
>原始查询也可以.它涉及更多的对象和检查,但如果表大小很大则会更便宜,因为您不需要进行排序.
qBuilder.selectRaw("MAX(my_field_column_name)");
GenericRawResults<String[]> results =
myEntityDao.queryRaw(qBuilder.prepareStatementString());
String[] result = results.getResults().next();
int max = Integer.parseInt(result[0]);
显然,如果您的列是不同的类型,那么您将从result [0]中获得一个不同的对象,您必须根据对象将其转换为适当的类型.
Android ContentProvider与ORMLite
>内容提供者在多线程环境中工作正常.我不知道Ormlite是否是线程安全的.
>内容提供商可以广播数据库更改.我不知道Ormlite是否有这种支持.
> Android提供一些实用程序,如AsynQueryHandler,CursorLoader来做异步查询数据库.如果我使用Ormlite,我必须明确地创建一个线程或AsyncTask来执行查询.
我是否应该用Ormlite替换内容提供者?
解决方法
但除了你提到的事情外,他们是内容提供商的其他好处.
>如果要在多个应用程序或进程之间共享日期.可能现在你没有任何计划这样做,但似乎你的应用程序在数据库上很重,如果您计划与第三方或另一个应用程序共享您的数据,您可以随时与内容提供商选择.
>内容提供商是Android的所有版本的标准,也意味着您的应用程序是安全的.我很确定Ormlite也是稳定的.但是,您是否真的想要承担这一风险,特别是如果不节省您的时间,或者您没有任何业务要求. Android API已经碎片化了吗?
>如果要将数据上传到云端,可以很容易地与SyncAdapter集成
>使用android安全和权限功能.
关于处理内容提供商所需的额外代码,您是对的.
现在我正在开展一个项目,我们有大约20个桌子.我已经为每个表创建了一个DAO.其中基本内部使用内容提供商.
DAO->内容提供者 – > sql Lite Open Helper
Class XyzDao{ private final Context mContext; XyzDao(Context context){ this.mContext=context; } public String getMyData(){ //content provider code return myData; } public void setMyData(String x,int y,double z){ //content provider code to set the data } }
我可以没有内容提供商,现在,目前的要求,将工作正常,但仍然我选择这条路线.你会问大概是为什么?
>异步操作
>轻松与平台/云端集成.
>减少代码少错误这么少的戏剧(想想如果我必须实现我们刚才讨论的那些任务)
而且,最好的部分是从任何活动我可以简单地使用我的DAO访问数据库.
或者,您可以直接从DAO访问SQLLiteOpenHelper.
在一天结束时,每个选择都取决于您的业务需求.如果你有很多持久性对象,Ormlite可能是一个不错的选择.
Android greenDAO数据库开发梳理 : Android ORM for your SQLite database
首先名确一个关键字:Object/relation mapping (ORM):对象/关系映射(ORM)
greenDao是什么?为什么会产生这个框架,也就是说greenDao的诞生是为了解决什么需求的?
关于 Android 中常用的数据存储方式有sharePreference存储、网络存储、文件存储等,但是对于数据量比较大、结构复杂的数据我们想要存储只能通过数据库进行处理,Android 系统中集成了一个轻量级的数据库: sqlite 数据库,但是使用起来比较繁琐和复杂,所以 Android 又新推出了Jetpack 组件库:Room 持久性库,Room 持久性库在 sqlite 的基础上提供了一个抽象层,让用户能够在充分利用 sqlite 的强大功能的同时,获享更强健的数据库访问机制。如果不使用这个新的组件库或者说在jetpack组件库之前,我们怎么能更方便快捷的访问操作sqliteDatabase数据库呢?开源ORM 框架———greenDAO框架。
下面我们来看官网对greenDAO的描述:GreenDAO的本质是为存储在关系数据库sqlite中的数据提供一个面向对象的接口。只需定义数据模型,Green DAO将创建Java数据对象(实体)和DAO(数据访问对象)。这将为您节省大量无聊的代码,只需来回移动数据。除此之外,Green DAO还提供一些高级ORM特性类似于会话缓存、急切加载和活动实体。
greenDAO’s Features at a glance
- Maximum performance (probably the fastest ORM for Android); our benchmarks are open sourced too
- Easy to use powerful APIs covering relations and joins
- Minimal memory consumption
- Small library size (<100KB) to keep your build times low and to avoid the 65k method limit
- Database encryption: greenDAO supports sqlCipher to keep your user’s data safe
- Strong community: More than 5.000 GitHub stars show there is a strong and active community
You want to learn more about greenDAO features like active entities, protocol buffers support, or eager loading? Then have a look at our full feature list.
下面是翻译:
GreenDAO的特点一目了然
- 最大性能(可能是Android最快的ORM);我们的基准测试也是开源的。
- 易用覆盖关系和联接的强大API
- 极小内存消耗
- 小的库大小(<100 kb),以保持较低的构建时间,并避免65k方法限制
- 数据库加密*GreenDAO支持sqlCiPHER,以确保用户数据的安全
- 强群落:5.000多名GitHub明星展示了一个强大而活跃的社区
您想了解有关GreenDAO功能的更多信息,如活动实体、协议缓冲区支持或急切加载?那就来看看我们的特征列表.
官网地址如下:https://greenrobot.org/greendao/
GitHub地址:https://github.com/greenrobot/greenDAO
下面给出使用实例:
首先创建一个项目、添加依赖包:
Add the following Gradle configuration to your Android project. In your root build.gradle
file:
buildscript {
repositories {
jcenter()
mavenCentral() // add repository
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
classpath 'org.greenrobot:greendao-gradle-plugin:3.3.0' // add plugin
}
}
In your app modules app/build.gradle
file:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin
dependencies {
implementation 'org.greenrobot:greendao:3.3.0' // add library
}
Note that this hooks up the greenDAO Gradle plugin to your build process. When you build your project, it generates classes like DaoMaster, DaoSession and DAOs.
下面来看一个示例效果:在EditText中输入文字(比如做课堂笔记Note),点击添加按钮,就会将输入的文字笔记添加到数据库。下面是一个RecyclerView列表,它将数据库中的内容全部读出并展示,点击item条目会删除该条目同时删除数据库中的记录。
对应数据库字段以及数据:
下面按照实际的开发步骤贴出代码:
1.首先我们需要定义一个实体对象(Entity Object),它是我们映射到数据库中的对象,这里你只需要定义实体对象的字段就可以,其他的getter()\setter()方法等编译器会自动生成:
public class Note {
private Long id;
private String text;
private String comment;
private java.util.Date date;
private NoteType type;
}
然后点击Android studio-->build-->Make Project按钮后,编译器就会自动创建完整的实体类:
完整的实体类:
package org.greenrobot.greendao.example;
import org.greenrobot.greendao.annotation.Convert;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Index;
import org.greenrobot.greendao.annotation.NotNull;
/**
* Entity mapped to table "NOTE".
*/
@Entity(indexes = {
@Index(value = "text, date DESC", unique = true)
})
public class Note {
@Id
private Long id;
@NotNull
private String text;
private String comment;
private java.util.Date date;
@Convert(converter = NoteTypeConverter.class, columnType = String.class)
private NoteType type;
@Generated(hash = 1272611929)
public Note() {
}
public Note(Long id) {
this.id = id;
}
@Generated(hash = 1686394253)
public Note(Long id, @NotNull String text, String comment, java.util.Date date, NoteType type) {
this.id = id;
this.text = text;
this.comment = comment;
this.date = date;
this.type = type;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@NotNull
public String getText() {
return text;
}
/** Not-null value; ensure this value is available before it is saved to the database. */
public void setText(@NotNull String text) {
this.text = text;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public java.util.Date getDate() {
return date;
}
public void setDate(java.util.Date date) {
this.date = date;
}
public NoteType getType() {
return type;
}
public void setType(NoteType type) {
this.type = type;
}
}
GreenDao并且会自动生成3个核心类如下:
3个核心类介绍
DaoMaster:
使用 greenDAO 的入口点。DaoMaster 负责管理数据库对象(sqliteDatabase)和 DAO 类(对象),我们可以通过它内部类 OpenHelper 和 DevOpenHelper sqliteOpenHelper 创建不同模式的 sqlite 数据库。
DaoSession :
管理指定模式下的所有 DAO 对象,DaoSession提供了一些通用的持久性方法比如插入、负载、更新、更新和删除实体。
XxxDAO :
每个实体类 greenDAO都会生成一个与之对应DAO对象,如:User实体,则会生成一个一个UserDao类,通过这和UserDao对象调用queryBuilder()进而调用查询条件的方法、增删改查的方法等。
Entities
可持久化对象。通常, 实体对象代表一个数据库行使用标准 Java 属性(如一个POJO 或 JavaBean )。
三个核心类与数据实体对象之间的关系:
DaoMaster.class:
package org.greenrobot.greendao.example;
import android.content.Context;
import android.database.sqlite.sqliteDatabase;
import android.database.sqlite.sqliteDatabase.CursorFactory;
import android.util.Log;
import org.greenrobot.greendao.AbstractDaoMaster;
import org.greenrobot.greendao.database.StandardDatabase;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.database.DatabaSEOpenHelper;
import org.greenrobot.greendao.identityscope.IdentityScopeType;
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/**
* Master of DAO (schema version 1000): kNows all DAOs.
*/
public class DaoMaster extends AbstractDaoMaster {
public static final int SCHEMA_VERSION = 1000;
/** Creates underlying database table using DAOs. */
public static void createallTables(Database db, boolean ifNotExists) {
NoteDao.createTable(db, ifNotExists);
}
/** Drops underlying database table using DAOs. */
public static void dropAllTables(Database db, boolean ifExists) {
NoteDao.dropTable(db, ifExists);
}
/**
* WARNING: Drops all table on Upgrade! Use only during development.
* Convenience method using a {@link DevOpenHelper}.
*/
public static DaoSession newDevSession(Context context, String name) {
Database db = new DevOpenHelper(context, name).getWritableDb();
DaoMaster daoMaster = new DaoMaster(db);
return daoMaster.newSession();
}
public DaoMaster(sqliteDatabase db) {
this(new StandardDatabase(db));
}
public DaoMaster(Database db) {
super(db, SCHEMA_VERSION);
registerDaoClass(NoteDao.class);
}
public DaoSession newSession() {
return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);
}
public DaoSession newSession(IdentityScopeType type) {
return new DaoSession(db, type, daoConfigMap);
}
/**
* Calls {@link #createallTables(Database, boolean)} in {@link #onCreate(Database)} -
*/
public static abstract class OpenHelper extends DatabaSEOpenHelper {
public OpenHelper(Context context, String name) {
super(context, name, SCHEMA_VERSION);
}
public OpenHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory, SCHEMA_VERSION);
}
@Override
public void onCreate(Database db) {
Log.i("greenDAO", "Creating tables for schema version " + SCHEMA_VERSION);
createallTables(db, false);
}
}
/** WARNING: Drops all table on Upgrade! Use only during development. */
public static class DevOpenHelper extends OpenHelper {
public DevOpenHelper(Context context, String name) {
super(context, name);
}
public DevOpenHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
dropAllTables(db, true);
onCreate(db);
}
}
}
DaoSession.class:
package org.greenrobot.greendao.example;
import java.util.Map;
import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.AbstractDaoSession;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.identityscope.IdentityScopeType;
import org.greenrobot.greendao.internal.DaoConfig;
import org.greenrobot.greendao.example.Note;
import org.greenrobot.greendao.example.NoteDao;
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/**
* {@inheritDoc}
*
* @see org.greenrobot.greendao.AbstractDaoSession
*/
public class DaoSession extends AbstractDaoSession {
private final DaoConfig noteDaoConfig;
private final NoteDao noteDao;
public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig>
daoConfigMap) {
super(db);
noteDaoConfig = daoConfigMap.get(NoteDao.class).clone();
noteDaoConfig.initIdentityScope(type);
noteDao = new NoteDao(noteDaoConfig, this);
registerDao(Note.class, noteDao);
}
public void clear() {
noteDaoConfig.clearIdentityScope();
}
public NoteDao getNoteDao() {
return noteDao;
}
}
你不用太多的关心上面两个类。我们来看一下数据库的初始化,以及数据库的库名和数据库中与我们这个实体类Note.class对象对应的数据表在哪里命名?
数据库的初始化:自定义MyApplication.class继承Application类,并在Manifest中声明这个MyApplication.class如下:
package org.greenrobot.greendao.example;
import android.app.Application;
import android.content.Context;
import org.greenrobot.greendao.database.Database;
public class MyApplication extends Application {
private DaoSession daoSession;
@Override
public void onCreate() {
super.onCreate();
/**
* 1、通过DaoMaster内部类OpenHelper获取需要连接的一个标准的数据库对象:sqliteDatabase
*/
ExampleOpenHelper helper = new ExampleOpenHelper(this, "notes-db");
Database db = helper.getWritableDb();
/**
* 2、创建数据库管理对象
* DaoMaster是使用greenDAO的入口点。DaoMaster负责管理数据库对象(sqliteDatabase)和DAO类(对象),
* 我们可以通过它内部类OpenHelper和DevOpenHelper sqliteOpenHelper创建不同模式的sqlite数据库
*/
DaoMaster daoMaster = new DaoMaster(db);
/**
* 3、创建数据库链接会话
* 管理指定模式下的所有DAO对象,DaoSession提供了一些通用的持久性方法比如插入、负载、更新、更新和删除实体。
*/
daoSession = daoMaster.newSession();
}
public DaoSession getDaoSession() {
return daoSession;
}
public static class ExampleOpenHelper extends DaoMaster.OpenHelper {
public ExampleOpenHelper(Context context, String name) {
super(context, name);
}
@Override
public void onCreate(Database db) {
super.onCreate(db);
// Insert some example data.
// INSERT INTO NOTE (_id, DATE, TEXT) VALUES(1, 0, 'Example Note')
db.execsql("INSERT INTO " + NoteDao.TABLENAME + " (" +
NoteDao.Properties.Id.columnName + ", " +
NoteDao.Properties.Date.columnName + ", " +
NoteDao.Properties.Text.columnName +
") VALUES(1, 0, 'Example Note')");
}
}
}
看上面的代码,第1步中获取数据库对象时new ExampleOpenHelper(this, "notes-db");第二个参数用于指定数据库的库名。
你也可以不用像上面那样继承DaoMaster.OpenHelper那样自定义自己的ExampleOpenHelper。可以直接使用DaoMaster.OpenHelper类进行获取数据库对象:
public class MyApplication extends Application {
public static DaoSession mSession;
@Override
public void onCreate() {
super.onCreate();
initDb();
}
/**
* 连接数据库并创建会话
*/
public void initDb() {
// 1、获取需要连接的数据库对象
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(this, "test.db");
sqliteDatabase db = devOpenHelper.getWritableDatabase();
// 2、创建数据库管理对象
DaoMaster daoMaster = new DaoMaster(db);
// 3、创建数据库会话
mSession = daoMaster.newSession();
}
// 供外接使用
public DaoSession getDaoSession() {
return mSession;
}
}
我们还有一个自动生成的类没说,NoteDao.class:
package org.greenrobot.greendao.example;
import android.database.Cursor;
import android.database.sqlite.sqliteStatement;
import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.Property;
import org.greenrobot.greendao.internal.DaoConfig;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.database.DatabaseStatement;
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/**
* DAO for table "NOTE".
*/
public class NoteDao extends AbstractDao<Note, Long> {
public static final String TABLENAME = "NOTE";
/**
* Properties of entity Note.<br/>
* Can be used for QueryBuilder and for referencing column names.
*/
public static class Properties {
public final static Property Id = new Property(0, Long.class, "id", true, "_id");
public final static Property Text = new Property(1, String.class, "text", false, "TEXT");
public final static Property Comment = new Property(2, String.class, "comment", false, "COMMENT");
public final static Property Date = new Property(3, java.util.Date.class, "date", false, "DATE");
public final static Property Type = new Property(4, String.class, "type", false, "TYPE");
}
private final NoteTypeConverter typeConverter = new NoteTypeConverter();
public NoteDao(DaoConfig config) {
super(config);
}
public NoteDao(DaoConfig config, DaoSession daoSession) {
super(config, daoSession);
}
/** Creates the underlying database table. */
public static void createTable(Database db, boolean ifNotExists) {
String constraint = ifNotExists? "IF NOT EXISTS ": "";
db.execsql("CREATE TABLE " + constraint + "\"NOTE\" (" + //
"\"_id\" INTEGER PRIMARY KEY ," + // 0: id
"\"TEXT\" TEXT NOT NULL ," + // 1: text
"\"COMMENT\" TEXT," + // 2: comment
"\"DATE\" INTEGER," + // 3: date
"\"TYPE\" TEXT);"); // 4: type
// Add Indexes
db.execsql("CREATE UNIQUE INDEX " + constraint + "IDX_NOTE_TEXT_DATE_DESC ON \"NOTE\"" +
" (\"TEXT\" ASC,\"DATE\" DESC);");
}
/** Drops the underlying database table. */
public static void dropTable(Database db, boolean ifExists) {
String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"NOTE\"";
db.execsql(sql);
}
@Override
protected final void bindValues(DatabaseStatement stmt, Note entity) {
stmt.clearBindings();
Long id = entity.getId();
if (id != null) {
stmt.bindLong(1, id);
}
stmt.bindString(2, entity.getText());
String comment = entity.getComment();
if (comment != null) {
stmt.bindString(3, comment);
}
java.util.Date date = entity.getDate();
if (date != null) {
stmt.bindLong(4, date.getTime());
}
NoteType type = entity.getType();
if (type != null) {
stmt.bindString(5, typeConverter.convertToDatabaseValue(type));
}
}
@Override
protected final void bindValues(sqliteStatement stmt, Note entity) {
stmt.clearBindings();
Long id = entity.getId();
if (id != null) {
stmt.bindLong(1, id);
}
stmt.bindString(2, entity.getText());
String comment = entity.getComment();
if (comment != null) {
stmt.bindString(3, comment);
}
java.util.Date date = entity.getDate();
if (date != null) {
stmt.bindLong(4, date.getTime());
}
NoteType type = entity.getType();
if (type != null) {
stmt.bindString(5, typeConverter.convertToDatabaseValue(type));
}
}
@Override
public Long readKey(Cursor cursor, int offset) {
return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);
}
@Override
public Note readEntity(Cursor cursor, int offset) {
Note entity = new Note( //
cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id
cursor.getString(offset + 1), // text
cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2), // comment
cursor.isNull(offset + 3) ? null : new java.util.Date(cursor.getLong(offset + 3)), // date
cursor.isNull(offset + 4) ? null : typeConverter.convertToEntityProperty(cursor.getString(offset + 4)) // type
);
return entity;
}
@Override
public void readEntity(Cursor cursor, Note entity, int offset) {
entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));
entity.setText(cursor.getString(offset + 1));
entity.setComment(cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2));
entity.setDate(cursor.isNull(offset + 3) ? null : new java.util.Date(cursor.getLong(offset + 3)));
entity.setType(cursor.isNull(offset + 4) ? null : typeConverter.convertToEntityProperty(cursor.getString(offset + 4)));
}
@Override
protected final Long updateKeyAfterInsert(Note entity, long rowId) {
entity.setId(rowId);
return rowId;
}
@Override
public Long getKey(Note entity) {
if(entity != null) {
return entity.getId();
} else {
return null;
}
}
@Override
public boolean hasKey(Note entity) {
return entity.getId() != null;
}
@Override
protected final boolean isEntityUpdateable() {
return true;
}
}
这个类中第一行一个静态变量就定义了与我们数据实体对象对应的数据表的表名。
在NoteActivity中查询数据并显示:(请不要复制这个例子到项目中运行,因为这里还有一些类我没有贴出。)
/*
* copyright (C) 2011 Markus Junginger, greenrobot (http://greenrobot.de)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.greenrobot.greendao.example;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import org.greenrobot.greendao.query.Query;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.linearlayoutmanager;
import androidx.recyclerview.widget.RecyclerView;
public class NoteActivity extends AppCompatActivity {
private EditText editText;
private View addNoteButton;
private NoteDao noteDao;
private Query<Note> notesQuery;
private NotesAdapter notesAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setUpViews();
// get the note DAO
DaoSession daoSession = ((MyApplication) getApplication()).getDaoSession();
noteDao = daoSession.getNoteDao();
/**
* 查询数据库对应表中所有的笔记数据
* query all notes, sorted a-z by their text
*/
notesQuery = noteDao.queryBuilder().orderAsc(NoteDao.Properties.Text).build();
updateNotes();
}
private void updateNotes() {
List<Note> notes = notesQuery.list();
notesAdapter.setNotes(notes);
}
protected void setUpViews() {
RecyclerView recyclerView = findViewById(R.id.recyclerViewNotes);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new linearlayoutmanager(this));
notesAdapter = new NotesAdapter(noteClickListener);
recyclerView.setAdapter(notesAdapter);
addNoteButton = findViewById(R.id.buttonAdd);
addNoteButton.setEnabled(false);
editText = findViewById(R.id.editTextNote);
editText.setonEditorActionListener((v, actionId, event) -> {
if (actionId == EditorInfo.IME_ACTION_DONE) {
addNote();
return true;
}
return false;
});
editText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
boolean enable = s.length() != 0;
addNoteButton.setEnabled(enable);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
public void onAddButtonClick(View view) {
addNote();
}
private void addNote() {
String noteText = editText.getText().toString();
editText.setText("");
final DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
String comment = "Added on " + df.format(new Date());
Note note = new Note();
note.setText(noteText);
note.setComment(comment);
note.setDate(new Date());
note.setType(NoteType.TEXT);
noteDao.insert(note);
Log.d("DaoExample", "Inserted new note, ID: " + note.getId());
updateNotes();
}
NotesAdapter.NoteClickListener noteClickListener = new NotesAdapter.NoteClickListener() {
@Override
public void onNoteClick(int position) {
Note note = notesAdapter.getNote(position);
Long noteId = note.getId();
noteDao.deleteByKey(noteId);
Log.d("DaoExample", "Deleted note, ID: " + noteId);
updateNotes();
}
};
}
NoteActivity的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="org.greenrobot.greendao.example.NoteActivity"
tools:ignore="RtlHardcoded">
<Button
android:id="@+id/buttonAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:onClick="onAddButtonClick"
android:text="@string/add"/>
<EditText
android:id="@+id/editTextNote"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/buttonAdd"
android:hint="@string/enter_new_note"
android:imeOptions="actionDone"
android:inputType="text"/>
<TextView
android:id="@+id/textViewNoteInstructions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/editTextNote"
android:gravity="center_horizontal"
android:paddingBottom="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:text="@string/click_to_remove"
android:textSize="12sp"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewNotes"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/textViewNoteInstructions"
android:scrollbars="vertical"/>
</RelativeLayout>
RecyclerView适配器代码如下:
package org.greenrobot.greendao.example;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.NoteViewHolder> {
private NoteClickListener clickListener;
private List<Note> dataset;
public interface NoteClickListener {
void onNoteClick(int position);
}
static class NoteViewHolder extends RecyclerView.ViewHolder {
public TextView text;
public TextView comment;
public NoteViewHolder(View itemView, final NoteClickListener clickListener) {
super(itemView);
text = itemView.findViewById(R.id.textViewNoteText);
comment = itemView.findViewById(R.id.textViewNoteComment);
itemView.setonClickListener(view -> {
if (clickListener != null) {
clickListener.onNoteClick(getAdapterPosition());
}
});
}
}
public NotesAdapter(NoteClickListener clickListener) {
this.clickListener = clickListener;
this.dataset = new ArrayList<>();
}
public void setNotes(@NonNull List<Note> notes) {
dataset = notes;
notifyDataSetChanged();
}
public Note getNote(int position) {
return dataset.get(position);
}
@NonNull
@Override
public NotesAdapter.NoteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_note, parent, false);
return new NoteViewHolder(view, clickListener);
}
@Override
public void onBindViewHolder(NotesAdapter.NoteViewHolder holder, int position) {
Note note = dataset.get(position);
holder.text.setText(note.getText());
holder.comment.setText(note.getComment());
}
@Override
public int getItemCount() {
return dataset.size();
}
}
上面只是梳理了GreenDao的使用流程,以及我们需要知道的知识点。当然这并不是所有的知识点,我们需要学习的还很多。这个例子请不要复制到项目中运行,因为这里还有一些类我没有贴出。如果想看完整的代码、并运行上面的实例,请至GreenDao的GitHub地址:https://github.com/greenrobot/greenDAO下载demo示例。上面的例子就是来自官网给的实例。
在说会上面的NoteActivity.class,一般对数据的增删改查,正式的项目开发中我们并不会直接在Activity中直接那么写。而是把它封装到一个诸如NoteDBManager.class的类中,这里贴出一个示例:
public class MessageManager {
private static MessageManager messageManager;
/**
* DaoSession
*/
private DaoSession mDaoSession;
private MessageDao messageDao;
private MessageManager() {
}
@Deprecated
public static MessageManager getMMInstance(Context context) {
return getInstance();
}
public static MessageManager getInstance() {
if (null == messageManager) {
synchronized (MessageManager.class) {
if (messageManager == null) {
messageManager = new MessageManager();
messageManager.mDaoSession = MyApplication.getDaoSession();
messageManager.messageDao = messageManager.mDaoSession.getMessageDao();
}
}
}
return messageManager;
}
/**
* 每天执行一次删除无效过期消息
*/
public static void oneDayDelInvalidMsg() {
Context context = MyApplication.getInstance().getApplicationContext();
final SharedPreferences msgSp = context.getSharedPreferences(MsgCenteractivity.MSG_SP_NAME,
Context.MODE_PRIVATE);
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
final String curDay = format.format(new Date());
String deleteDay = msgSp.getString("delete_day", "");
if (!curDay.equals(deleteDay)) {
MessageManager.getInstance().deleteInvalidMessage();
SharedPreferences.Editor editor = msgSp.edit();
editor.putString("delete_day", curDay);
editor.commit();
}
}
/**
* 根据id删除推送消息
*
* @param mid
*/
public void deleteMessageByMid(String mid) {
try {
QueryBuilder<Message> qb = messageDao.queryBuilder();
DeleteQuery<Message> bd = qb.where(Properties.Mid.eq(mid)).buildDelete();
bd.executeDeleteWithoutDetachingEntities();
} catch (Exception e) {
e.printstacktrace();
}
}
/**
* 根据id删除推送消息(假删除)
*
* @param mid
*/
public void deleteMessageNewByMid(String mid) {
try {
QueryBuilder<Message> qb = messageDao.queryBuilder();
List<Message> msgList ;
msgList = qb.where(Properties.Mid.eq(mid)).list();
if (null != msgList && !msgList.isEmpty()) {
Message msg = msgList.get(0);
if (null != msg) {
msg.setIsdelete(1);
messageDao.insertOrReplace(msg);
}
}
} catch (Exception e) {
e.printstacktrace();
}
}
public void deleteMessageByMid(String mid, String mobile) {
try {
QueryBuilder<Message> qb = messageDao.queryBuilder();
DeleteQuery<Message> bd = qb.where(qb.and(Properties.Mid.eq(mid), Properties.Mobile.eq(mobile)))
.buildDelete();
bd.executeDeleteWithoutDetachingEntities();
} catch (Exception e) {
e.printstacktrace();
}
}
/**
* 根据类型id删除所有消息
*
* @param typeId
*/
public void deleteMessageByType(String typeId) {
try {
QueryBuilder<Message> qb = messageDao.queryBuilder();
DeleteQuery<Message> bd = qb.where(Properties.MsgType.eq(typeId)).buildDelete();
bd.executeDeleteWithoutDetachingEntities();
} catch (Exception e) {
e.printstacktrace();
}
}
/**
* 根据类型id删除该用户手机号
*
* @param typeId
* @param mobile
*/
public void deleteTypeMessageByTypeMob(String typeId, String mobile) {
try {
QueryBuilder<Message> qb = messageDao.queryBuilder();
DeleteQuery<Message> bd = qb.where(qb.and(Properties.MsgType.eq(typeId), Properties.Mobile.eq(mobile)))
.buildDelete();
bd.executeDeleteWithoutDetachingEntities();
} catch (Exception e) {
e.printstacktrace();
}
}
public void deleteInvalidMessage() {
try {
QueryBuilder<Message> qb = messageDao.queryBuilder();
DeleteQuery<Message> bd = qb.where(qb.and(Properties.EffectiveTime.lt(System.currentTimeMillis()),
Properties.EffectiveTime.isNotNull())).buildDelete();
bd.executeDeleteWithoutDetachingEntities();
} catch (Exception e) {
e.printstacktrace();
}
}
public void updateMessageStatus(String mobile) {
try {
String curTime = getCurTime();
QueryBuilder<Message> qb = messageDao.queryBuilder();
List<Message> msgList ;
msgList = qb.where(qb.and(Properties.Status.eq(0),
Properties.Mobile.eq(mobile), Properties.Isdelete.notEq(1))).list();
if (null != msgList && !msgList.isEmpty()) {
int size = msgList.size();
for (int i = 0; i < size; i++) {
Message msg = msgList.get(i);
if (null != msg) {
msg.setStatus(1);
msg.setReadTime(curTime);
messageDao.update(msg);
}
}
}
} catch (Exception e) {
e.printstacktrace();
}
}
}
然后通过管理类的单例在Activity中调用封装后的增删改查方法!。
忠言逆耳:对于初学者请一定先运行GitHub官网给的dome示例。而不是盲目的找示例demo,那样只会放慢你学习的脚步。
岁月鎏金,用知识铭刻生命的每分每秒!
Android ORM 框架之 LiteOrm 的使用心得
之前一直在使用 SQLite,无意中发现 LiteOrm,看了下基本使用,感觉很方便而且效率也挺高的,特别是级联查询上,很面向对象。
LiteOrm 并不是 OrmLite,没有文档仅能查看 GitHub 上的 samples。不过在数据库框架的使用方法上比较相似。
两者之间的比较:Android 数据库框架:greenDAO vs LiteOrm。
GitHub 地址:https://github.com/litesuits/android-lite-orm
LiteSuits 官网: http://litesuits.com/?form=gorm
一、创建数据库
/*
1. 创建config信息
*/
DataBaseConfig config = new DataBaseConfig(mContext);
//数据库名,可设置存储路径。默认在内部存储位置databases文件夹下
//"liteorm.db"是数据库名称,名称里包含路径符号"/"则将数据库建立到该路径下,可以使用sd卡路径。 不包含则在系统默认路径下创建DB文件。
config.dbName = DB_NAME_PATH + File.separator + "liteorm.db";
config.debugged = true; //是否打Log
config.dbVersion = 1; // database Version
config.onUpdateListener = null; //升级
/**
*2. 生成实例对象
*/
//级联操作
liteOrm = LiteOrm.newCascadeInstance(config);
//独立操作
liteOrm = LiteOrm.newSingleInstance(config);
LiteOrm 有两种获取实例的方法:
独立操作:使用 LiteOrm 的 single 实例,可与 cascade 方式平滑切换,性能高,仅处理该对象数据,其关系、和关联对象忽略;
级联操作:使用 LiteOrm 的 cascade 实例,可与 single 方式平滑切换,全递归,该对象数据,及其关系、和关联对象都被处理;
这两种获取方式根据项目需求而定,如果级联操作比较多的话,就可以使用 cascadeInstance,而其又可以和独立操作任意切换:
LiteOrm db = LiteOrm.newCascadeInstance(this, "cascade.db");
db.cascade().save(user);//级联操作:保存[当前对象],以及该对象所有的[关联对象]以及它们的[映射关系]。
db.single().save(user);//非级联操作:仅保存[当前对象],高效率。
二、注解
基础注解
@Table("test_model")
表名@PrimaryKey(AssignType.AUTO_INCREMENT)
主键自增长@PrimaryKey(AssignType.BY_MYSELF)
自己设置主键@Ignore
忽略该字段,不存入数据库@Column("login")
指定列名@Collate("NOCASE")
大小写无关
关系映射:
@Mapping(Relation.ManyToMany)
多对多@Mapping(Relation.OneToMany)
一对多@Mapping(Relation.OneToOne)
一对一@Mapping(Relation.ManyToOne)
多对一@MapCollection(ConcurrentLinkedQueue.class)
指定约束对象的集合类型
约束相关:
@NotNull
非空约束@Default("true")
默认约束@Check("index > 0 ")
check 约束@Unique
唯一约束@UniqueCombine()
联合唯一约束
约束冲突:
ON CONFLICT 子句不是一个单独的 SQL 命令。 它可以出现在很多其它的 SQL 命令中,是一个非标准的子句。ON CONFLICT 子句指定一个用于解决约束冲突的算法。 有五种选择 (具体解释请看文末参考链接,copy 过来也没啥意思):
- @Conflict(Strategy.ROLLBACK)
- @Conflict(Strategy.ABORT)
- @Conflict(Strategy.FAIL)
- @Conflict(Strategy.IGNORE)
- @Conflict(Strategy.REPLACE)
从注解也可以看出来该框架确实比较全面,它的查询某些语法完全和 SQL 语句一样,可以复习一下 SQL 语句。
三、建表
仅需要建立实体类添加相应的注解就可以了,是不是很方便。
四、CRUD 操作
1. 保存
// 仅插入数据
Person man= new Person("name",23);
liteOrm.insert(man);
// 保存单个实例
Person person = new Person("name",23);
liteOrm.save(person);
// 保存一个List
List<Person> list = new ArrayList<>();
liteOrm.save(list);
2. 修改
book.setIndex(1988);
book.setAuthor("hehe");
liteOrm.update(book);
更新指定列
// 把所有书的author强制批量改为liter
HashMap<String, Object> bookIdMap = new HashMap<String, Object>();
bookIdMap.put(Book.COL_AUTHOR, "liter");
liteOrm.update(bookList, new ColumnsValue(bookIdMap), ConflictAlgorithm.Fail);
// 仅 author 这一列更新为该对象的最新值。
//liteOrm.update(bookList, new ColumnsValue(new String[]{Book.COL_AUTHOR}, null), ConflictAlgorithm.Fail);
3. 查询
在写查询语句时,一定要铭记 sql 语句:
SELECT 列
FROM 表
WHERE 条件
GROUP BY 分组条件
HAVING 分组后条件
ORDER BY 排序
LIMIT (x,y)
读取全部数据
// 读取全部数据
List<Person> list = liteOrm.query(Person.class);
查询操作里面这个?必不可少,是不是和写 sql 很像,? 是个占位符。同时 SQL 并不区分大小写,但关键字建议大写。
聚合函数 count 查询
//聚合函数count查询,好像只有这一个
long nums = liteOrm.queryCount(Address.class); //查询有多少行
查询 根据 ID
Student student = liteOrm.queryById(student1.getId(), Student.class);
OrmLog.i(TAG, student);
查询 模糊
//模糊查询
QueryBuilder<Address> qb = new QueryBuilder<Address>(Address.class).where("address LIKE ?", new String[]{"%山%"});
liteOrm.query(qb);
查询 与或非等
qb = new QueryBuilder<Address>(Address.class)
.whereEquals("city", "南京")
.whereAppendAnd()
.whereEquals("address", "香港路");
liteOrm.query(qb);
查询 任意
List<Book> books = liteOrm.query(new QueryBuilder<Book>(Book.class)
.columns(new String[]{"id", "author", Book.COL_INDEX})
.distinct(true)
.whereGreaterThan("id", 0)
.whereAppendAnd()
.whereLessThan("id", 10000)
.limit(6, 9)
.appendOrderAscBy(Book.COL_INDEX));
OrmLog.i(TAG, books);
查询 自己拼 SQL 语句
QueryBuilder<Address> qb = new QueryBuilder<Address>(Address.class)
.columns(new String[]{Address.COL_ADDRESS}) //查询列
.appendOrderAscBy(Address.COL_ADDRESS) //升序
.appendOrderDescBy(Address.COL_ID) //当第一列相同时使用该列降序排序
.distinct(true) //去重
.where(Address.COL_ADDRESS + "=?", new String[]{"香港路"}); //where条件
liteOrm.query(qb);
4. 删除
删除 实体
// 删除 student-0
liteOrm.delete(student0);
删除 指定数量
// 按id升序,删除[2, size-1],结果:仅保留第一个和最后一个
// 最后一个参数可为null,默认按 id 升序排列
liteOrm.delete(Book.class, 2, bookList.size() - 1, "id");
删除 使用 WhereBuilder
// 删除 student-1
liteOrm.delete(new WhereBuilder(Student.class)
.where(Person.COL_NAME + " LIKE ?", new String[]{"%1%"})
.and()
.greaterThan("id", 0)
.and()
.lessThan("id", 10000));
删除全部
// 连同其关联的Person,Person关联的其他对象一带删除
liteOrm.deleteAll(Person.class);
删除数据库文件
liteOrm.deleteDatabase();
// 顺带测试:然后重建一个新库
liteOrm.openOrCreateDatabase();
五、级联操作
为什么说面向对象呢。就是仅仅需要在 JavaBean 里声明对象间关系,并用注解标识就 OK 了。举个例子:
@Table("school")
public class School{
@Mapping(Relation.OneToMany)
public ArrayList<Classes> classesList; //一个学校有多个教室
}
@Table("class")
public class Classes {
@Mapping(Relation.OneToOne)
public Teacher teacher; //一个教室有一个老师,假设
}
@Table("teacher")
public class Teacher {
@Mapping(Relation.ManyToMany)
@MapCollection(ConcurrentLinkedQueue.class)
private Queue<Student> studentLinkedQueue; //一个老师多个学生,一个学生多个老师,多对多关系
}
@Table("student")
public class Student {
@Mapping(Relation.ManyToMany)
private Teacher[] teachersArray;//一个老师多个学生,一个学生多个老师,多对多关系
}
就这样声明,你在 Java 里创建完对象后使用 save()
方法保存后,数据库中各种关联表就建好了,完全不用自己设置主键、外键什么的。是不是很方便?不过前提是你要使用 LiteOrm.newCascadeInstance(config)
这个实例。
六、封装
public enum UOrm implements SQLiteHelper.OnUpdateListener {
INSTANCE;
private LiteOrm mLiteOrm;
UOrm() {
DataBaseConfig config = new DataBaseConfig(MyApplcation.mContext);
config.dbName = DB_NAME_PATH + File.separator + DB_NAME;
config.dbVersion = 1;
config.onUpdateListener = this;
config.debugged = BuildConfig.DEBUG;
//可替换为 newCascadeInstance支持级联操作
mLiteOrm = LiteOrm.newSingleInstance(config);
}
@Override public void onUpdate(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
public void save(Object o) {
if (o == null) {
return;
}
mLiteOrm.save(o);
}
public <T> void save(List<T> collection) {
if (CommonUtil.isEmpty(collection)) {
return;
}
mLiteOrm.save(collection);
}
public <T> void delete(Class<T> tClass) {
if (tClass == null) {
return;
}
mLiteOrm.delete(tClass);
}
public <T> List<T> queryAll(Class<T> tClass) {
if (tClass == null) {
return null;
}
return mLiteOrm.query(tClass);
}
}
使用时只用这样调用:
UOrm.INSTANCE.save(modelA);
七、约束冲突
什么是 sql 约束?比如 @NotNull,@Unique,@Check 等。不满足这些约束就会产生冲突,解决约束冲突的算法。有五个选择:ROLLBACK、ABORT、FAIL、IGNORE 和 REPLACE,缺省方案是 ABORT,它并不是标准的 SQL 语言。
ROLLBACK
当发生约束冲突,立即 ROLLBACK,即结束当前事务处理,命令中止并返回 SQLITE_CONSTRAINT 代码。若当前无活动事务(除了每一条命令创建的默认事务以外),则该算法与 ABORT 相同。
ABORT
当发生约束冲突,命令收回已经引起的改变并中止返回 SQLITE_CONSTRAINT。但由于不执行 ROLLBACK,所以前面的命令产生的改变将予以保留。缺省采用这一行为。
FAIL
当发生约束冲突,命令中止返回 SQLITE_CONSTRAINT。但遇到冲突之前的所有改变将被保留。例如,若一条 UPDATE 语句在 100 行遇到冲突 100th,前 99 行的改变将被保留,而对 100 行或以后的改变将不会发生。
IGNORE
当发生约束冲突,发生冲突的行将不会被插入或改变。但命令将照常执行。在冲突行之前或之后的行将被正常的插入和改变,且不返回错误信息。
REPLACE
当发生 UNIQUE 约束冲突,先存在的,导致冲突的行在更改或插入发生冲突的行之前被删除。这样,更改和插入总是被执行。命令照常执行且不返回错误信息。当发生 NOT NULL 约束冲突,导致冲突的 NULL 值会被字段缺省值取代。若字段无缺省值,执行 ABORT 算法。当冲突应对策略为满足约束而删除行时,它不会调用删除触发器。但在新版中这一特性可能被改变。INSERT 或 UPDATE 的 OR 子句定义的算法会覆盖 CREATE TABLE 所定义的。ABORT 算法将在没有定义任何算法时缺省使用。
android ormlite – 存储字符串数组
我想坚持一个包含String数组的类.
如何在ormlite中做到这一点?
例如,
class A {
int age;
String[] childrenNames = new String[2];
}
解决方法:
首先,你创建Serializable类.
您可以选择通过注释在类顶部添加表名.
然后对于变量,您必须添加数据库字段注释.对于字符串数组,您还必须将其注释为Serializable数据类型.
你会得到这样的东西:
@DatabaseTable(tableName = "A")
Class A implements Serializable{
@DatabaseField
int age
@DatabaseField(dataType = DataType.SERIALIZABLE)
String[] childrenNames = new String[2];
}
也不要忘记为每个变量创建getter和setter.
今天关于android – ORMLite – 返回项目w /最大ID(或值)和android返回上一个activity的介绍到此结束,谢谢您的阅读,有关Android ContentProvider与ORMLite、Android greenDAO数据库开发梳理 : Android ORM for your SQLite database、Android ORM 框架之 LiteOrm 的使用心得、android ormlite – 存储字符串数组等更多相关知识的信息可以在本站进行查询。
本文标签: