澳门新莆京手机网站-新蒲京娱乐场 > 书籍 > Android中SQLite 使用办法详细解释

Android中SQLite 使用办法详细解释

数据库插入框架

数据库插入操作框架能够缓解你写代码量,让你一步成功数据库插入操作而无须关心此中间繁杂的操作。相像运用java反射来得以完结上述效果。代码如下:

 /**
     * 插入一条数据
     *
     * @param obj
     * @return 返回-1代表插入数据库失败,否则成功
     * @throws IllegalAccessException
     */
    public long insert(Object obj) {
        Class<?> modeClass = obj.getClass();
        Field[] fields = modeClass.getDeclaredFields();
        ContentValues values = new ContentValues();

        for (Field fd : fields) {
            fd.setAccessible(true);
            String fieldName = fd.getName();
            //剔除主键id值得保存,由于框架默认设置id为主键自动增长
            if (fieldName.equalsIgnoreCase("id") || fieldName.equalsIgnoreCase("_id")) {
                continue;
            }
            putValues(values, fd, obj);
        }
        return db.insert(DBUtils.getTableName(modeClass), null, values);
    }

............

 /**
     * put value to ContentValues for Database
     *
     * @param values ContentValues object
     * @param fd     the Field
     * @param obj    the value
     */
    private void putValues(ContentValues values, Field fd, Object obj) {
        Class<?> clazz = values.getClass();
        try {
            Object[] parameters = new Object[]{fd.getName(), fd.get(obj)};
            Class<?>[] parameterTypes = getParameterTypes(fd, fd.get(obj), parameters);
            Method method = clazz.getDeclaredMethod("put", parameterTypes);
            method.setAccessible(true);
            method.invoke(values, parameters);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

有以上框架之后,大家后日来向数据库插入一条数据代码如下:

Person person = new Person("Tom",18,false);
DBManager.insert(person);

哇!如此总结,一行代码消弭麻烦的插入操作。大家只要求传入Person对象的实例作为参数就能够到位数据库插入操作。再也不用去营造什么ContentVaules键值对了。

下面的函数最终骨子里效果是实践了SQL语句:

上边是Cursor对象的常用方法:

注意:mode只的是MODE_PRIVATE , MODE_WORLD_READABLE, MODE_WORLD_WRITEABLE。

数据库框架更新操作

 ContentValues values = new ContentValues();
        values.put("age", 34);
        dbManager.updateById(Person.class, values, 1);

先是个参数为Person类的品种,第四个参数为供给改革的vaules,第三个参数是基准,更新id为1的数码。用法超粗略,它的落到实处如下:

 /**
     * 更新一条记录
     *
     * @param clazz  类
     * @param values 更新对象
     * @param id     更新id索引
     */
    public void updateById(Class<?> clazz, ContentValues values, long id) {
        db.update(clazz.getSimpleName(), values, "id=" + id, null);
    }

然后,数据库的基本操作都位列出来了,也印证了Android提供的sqlite数据库在平时花费中的一些繁缛的位置,所以本人总计提取了二个轻巧型的数据库操作框架,仅仅是比较容易的操作,如若您有数据量大的操作,请出门左转利用其余多效果与利益成熟牢固的数据库开源框架。该框架只相符数据量小,不真实表与表之间的附和关系,能够将查询结果向来调换到对象的轻量级框架。

源码以至示例地址: DataBaseDemo

复制代码 代码如下:

上边的话说查询操作。查询操作相对于地点的三种操作要复杂些,因为我们日常要直面着五颜六色的查询条件,所以系统也设想到这种复杂,为大家提供了较为充裕的查询格局:

while (cursor.moveToNext()) {

android提供的数据库插入操作

对数据库插入操作 SQLite提供了之类方法

public long insert(String table, String nullColumnHack, ContentValues values)

能够看到,第三个参数是table 表示表名,第三个参数经常用不到,传入null就可以,第二个参数将数据以 ContentValues键值对的款型积攒。举个例子大家在数据库中插入一条人Person的新闻代码如下:

public void insert(Person person){
        ContentValues values = new ContentValues();
        values.put("name",person.getName());
        values.put("age",person.getAge());
        values.put("flag",person.getFlag());
        db.insert("Person",null,values);
    }

内部ContentValues是以键值没有错款式积存数据,上面代码中的key 分别对应数据库中的每一列的字段,vaule分别对应着该列的值。你是或不是发现Person类中有多少个天性就得写多少行values.put(key,value);参加它有十一个字段须求保留到数据库中,你是还是不是认为这样很麻烦呢?认为费力就对了,接下去大家利用反射来一步成功以上数据库插入操作。

图片 1

  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    //打开或创建test.db数据库 
    SQLiteDatabase db = openOrCreateDatabase("test.db", Context.MODE_PRIVATE, null); 
    db.execSQL("DROP TABLE IF EXISTS person"); 
    //创建person表 
    db.execSQL("CREATE TABLE person (_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age SMALLINT)"); 
    Person person = new Person(); 
    person.name = "john"; 
    person.age = 30; 
    //插入数据 
    db.execSQL("INSERT INTO person VALUES (NULL, ?, ?)", new Object[]{person.name, person.age}); 

    person.name = "david"; 
    person.age = 33; 
    //ContentValues以键值对的形式存放数据 
    ContentValues cv = new ContentValues(); 
    cv.put("name", person.name); 
    cv.put("age", person.age); 
    //插入ContentValues中的数据 
    db.insert("person", null, cv); 

    cv = new ContentValues(); 
    cv.put("age", 35); 
    //更新数据 
    db.update("person", cv, "name = ?", new String[]{"john"}); 

    Cursor c = db.rawQuery("SELECT * FROM person WHERE age >= ?", new String[]{"33"}); 
    while (c.moveToNext()) { 
      int _id = c.getInt(c.getColumnIndex("_id")); 
      String name = c.getString(c.getColumnIndex("name")); 
      int age = c.getInt(c.getColumnIndex("age")); 
      Log.i("db", "_id=>" + _id + ", name=>" + name + ", age=>" + age); 
    } 
    c.close(); 

    //删除数据 
    db.delete("person", "age < ?", new String[]{"35"}); 

    //关闭当前数据库 
    db.close(); 

    //删除test.db数据库 
//   deleteDatabase("test.db"); 
  } 

while (cursor.moveToNext()) {

数据库删除框架

去除这一块比较轻便,小编直接贴出代码来

 /**
     * 删除记录一条记录
     *
     * @param clazz 需要删除的类名
     * @param id    需要删除的 id索引
     */
    public void deleteById(Class<?> clazz, long id) {
        db.delete(DBUtils.getTableName(clazz), "id=" + id, null);
    }

顾客调用如下:

dbManager.deleteById(Person.class, 1);

先是个 参数是Person类的系列,第贰个参数是被删除数据的id。是或不是异常粗略吗?它的得以实现如下:

   /**
     * 删除记录一条记录
     *
     * @param clazz 需要删除的类名
     * @param id    需要删除的 id索引
     */
    public void deleteById(Class<?> clazz, long id) {
        db.delete(DBUtils.getTableName(clazz), "id=" + id, null);
    }

复制代码 代码如下:

末段,他们还要重回二个Cursor对象,代表数据集的游标,有一点点相符于JavaSE中的ResultSet。

 

数据库更新操作

cd /data/data/cn.demo.sql

世家可以见到,几个关键步骤是,首先决断mDatabase假如不为空已开发并非只读情势则直接重回,不然大器晚成旦mDatabase不为空则加锁,然后初步展开或创建数据库,比较版本,依照版本号来调用相应的章程,为数据库设置新版本号,最终获释旧的不为空的mDatabase并解锁,把新开垦的数据库实例给予mDatabase,并重返最新实例。

}

数据库操作–查询

从表格中询问记录

文中提到,startManagingCursor方法会依照Activity的生命周期去管理当前的Cursor对象的生命周期,正是说当Activity截至时他会活动调用Cursor的deactivate方法,禁止使用游标,当Activity重新归来荧屏时它会调用Cursor的requery方法重新查询,当Activity摧毁时,被管理的Cursor都会活动关闭释放。

 

android提供的删减

android系统提供了sqlite数据库删除方法 delete(卡塔尔,其定义如下:

public int delete(String table, String whereClause, String[] whereArgs)

在那之中,第二个参数表示表名,第叁个参数是基准SQL语句,第四个参数是替换第三个参数中的占位符(?)。要是小编要去除Person表中的age=18的多少,则代码调用如下:

db.delete("Person","age = ?",new String[]{"18"});

复制代码 代码如下:

图片 2

public static SQLiteDatabase create(SQLiteDatabase.CursorFactory factory)

框架成效

  1. public long insert(Object obj卡塔尔;插入数据
  2. public List findAll(Class clazz卡塔尔(قطر‎;查询全数数据
  3. public List findByArgs(Class clazz, String select, String[] selectArgs卡塔尔(قطر‎ ;依据钦定条件查询餍足条件数据
  4. public T findById(Class clazz, int id卡塔尔国;依据id查询一条记下
  5. public void deleteById(Class)

为了方便使用,可以自定义多个insert函数,将值通过参数字传送入,而ContentValues设置则在函数内部落实。

三:第后生可畏,建表时依照职业去做;第二,查询时用外号,比如:SELECT id AS _id FROM person;第三,在CursorWrapper里做文章:

下边代码用于从person表中寻找name字段含有“传智”的笔录,相称的记录按personid降序排序,对排序后的结果略过第一条记下,只得到2条记下。

android提供的更新操作

在android的sqlite中提供了update()方法来更新数据操作,其定义如下:

public int update(String table, ContentValues values, String whereClause, String[] whereArgs)

update(卡塔尔(قطر‎方法采纳三个参数,第二个参数是表名,第三个参数是贰个装进了待更正数据的ContentValues对象,第三和第四个参数用于内定改正哪些行,对应了SQL语句中的where部分。比方本身要改革id=1的Person人的年龄age改成20,那么代码完成如下:

 ContentValues values = new ContentValues();
        values.put("age",20);
        db.update("Person",values,"id = ?",new String[]{"1"});

该方式也算比较容易,那么大家来走访本人写的数据库框架是怎么贯彻的呢?

结构函数:

下边,大家就以四个实例来说学习用具体的用法,大家新建一个名称为db的门类,构造如下:

query(卡塔尔国方法其实是把select语句拆分成了好八个组成部分,然后作为艺术的输入参数:

android提供的数据库查询

android 的sqlite数据库提供的查询语句有rawQuery(State of Qatar方法。该格局的概念如下:

public Cursor rawQuery(String sql, String[] selectionArgs)

里头第叁个参数是sql字符串,第4个参数是用来替换SQL语句中占位符(?)的字符串数组。重回结果寄放在Cursor对象个中,大家假若循环大器晚成豆蔻梢头抽出数据就可以。当然大家平常微微用那个法子,因为急需记住很超多据库查询语句的规行矩步等。Android给开荒者封装了别的一个数据库查询办法,即SQLiteDatabase中的query(卡塔尔国方法。该方法的定义如下:

public Cursor query(String table, String[] columns, String selection,
            String[] selectionArgs, String groupBy, String having,
            String orderBy)

其中,

率先个参数是内需查询数据的表名称;

其次个参数指查询表中的那几列字段,假使不点名则默许查询全部列;

其多少个参数是sql语句,表示查询条件;

第八个参数是用于替换第五个参数sql语句中的占位符(?)数组,要是第三,多个参数不钦赐则暗中同意查询全体行;

第三个参数用于钦命须要去group by的列,不点名则代表不对查询结果开展group by操作。

第三个参数用于对group by之后的多少开展更进一层的过滤,不点名则代表不实行过滤。

第多个参数用于内定询问结果的排序格局,不钦命则代表使用默许的排序方式。

query(卡塔尔方法的参数是或不是过多,普普通通的人都很难记住那几个参数的意趣,在用的时候就特不便民,举个例子你要查询数据库中 age=18的人,你的代码得那般写:

 Cursor cursor = db.query("Person", null, "age = ?", new String[]{"18"}, null, null, null);

其多少个参数是查询条件,去束缚查询结果 age = 18,所以 第八个参数是“age= ?”,第多少个参数用于替换第多少个参数的占位符(?),由此是String的数组。查询的结果保存在Cursor中,为了获得查询结果,大家必须要去变量里Cursor意气风发黄金时代抽出在那之中的数额并保存。代码如下:

List<Person> list = new ArrayList<>();
        if (cursor != null && cursor.moveToFirst()) {
            do {
                Person person = new Person();
                int id = cursor.getInt(cursor.getColumnIndex("id"));
                String name = cursor.getString(cursor.getColumnIndex("name"));
                String age = cursor.getString(cursor.getColumnIndex("age"));
                boolean flag = cursor.getInt(cursor.getColumnIndex("flag")) == 1 ? true : false;
                person.setId(id);
                person.setName(name);
                person.setAge(age);
                person.setFlag(flag);
                list.add(person);
            } while (cursor.moveToNext());

        }

为了赢得Cursor中的查询结果,我们写了这样多的冗杂的代码,借使此时有一个新的Student类,那么你是否又要去改过那个查询形式吧?如此看来该查询格局和获得结果是或不是未有通用性,非常不方便使用。对于讨厌敲重复代码的程序员来讲那样很费劲,用的优伤,那么有未有风度翩翩种方法直接将查询结果调换到笔者需求的类的成团呢?这里大家又要用到温馨写的询问框架了,利用该框架少年老成行代码就可以化解全部。

您恐怕感兴趣的篇章:

  • Android SQLite数据库增加和删除改查操作的利用精解
  • Android使用SQLite数据库的回顾实例
  • android将图纸转变存到数据库再从数据库读取转换来图片实现代码
  • android创造数据库(SQLite卡塔尔保存图片示例
  • Android 用adb pull或push 拷贝手提式无线电话机文件到到计算机上,拷贝手提式有线电话机数据库到计算机上,拷贝Computer数据库到手提式无线电话机上
  • Android中的SQL查询语句LIKE绑定参数难题解决办法(sqlite数据库)
  • 原则数据库Android:sqllite的简便利用
  • Android学习笔记-保存数据到SQL数据库中(Saving Data in SQL Databases卡塔尔国
  • android完成raw文件夹导入数据库代码
  • Android数据库操作工具类共享

大家全体应用关闭时实施,那几个环节轻松被淡忘,所以朋友们要在意。

}

创制数据库

Android系统中早就合龙了Sqlite数据库,大家一向运用它就好了,同有时间Android系统提供了叁个数据库扶持类SQLiteOpenHelper,该类是三个抽象类,所以得写一个类来继续它落成里面包车型地铁秘技。代码如下:

MySQLiteHelper类

public class MySQLiteHelper extends SQLiteOpenHelper {

    public MySQLiteHelper(Context context, String name, CursorFactory factory,
            int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }

}

当数据库创制时系统会调用个中的 onCreate方法,那么大家就足以来贯彻onCreate 方法来创设数量库表。假若大家要成立一张 Person表,表中有 id,name,age,flag字段。那么代码如下:

public class MySQLiteHelper extends SQLiteOpenHelper {

    public static final String CREATE_TABLE = "create table Person ("
            + "id integer primary key autoincrement, "
            + "name text, "
            + "age integer, "
            + "flag boolean)";

    public MySQLiteHelper(Context context, String name, CursorFactory factory,
            int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABLE);
    }
    ...
}

经过我们的数据库帮助类就完事了,接下去是如此使用的:

    private static final String DB_NAME = "demo.db";
    private static final int DB_VERSION = 1;

    public void oepnDB(){
        MySQLiteHelper helper = new MySQLiteHelper(context, DB_NAME, null, DB_VERSION);
        SQLiteDatabase db = helper.getWritableDatabase();
    }

有上述代码就早就成功了叁个数据库成立以致一张表的创立,是不不是以为不是很难啊?这么看起来确实不是很难,然而自己的也必须要每便一了百了襲SQLiteOpenHelper类来促成里面包车型的士议程。关键是每一遍都要去写创造表语句

public static final String CREATE_TABLE = "create table Person ("
            + "id integer primary key autoincrement, "
            + "name text, "
            + "age integer, "
            + "flag boolean)";

此间表的字段唯有4个,假诺有一天你遇上表里的字段有10列怎么办?还继续遵循地点的措施写创立表语句么?你就不嫌繁缛么?何况轻便粗错。那么有未有最好轻易的不二等秘书籍一步成功表语句的创设呢?你细想:存放在数据库中表的这一个字段无非正是二个Person类中的全体成员变量,这么一来是还是不是可以只经过Person类型直接创建表语句呢?答案是放任自流的。大家经过java 的反射机制来一步暂劳永逸的贯彻建表操作。代码如下:

 /**
         * 得到建表语句
         *
         * @param clazz 指定类
         * @return sql语句
         */
        private String getCreateTableSql(Class<?> clazz) {
            StringBuilder sb = new StringBuilder();
            //将类名作为表名
            String tabName = Utils.getTableName(clazz);
            sb.append("create table ").append(tabName).append(" (id  INTEGER PRIMARY KEY AUTOINCREMENT, ");
            //得到类中所有属性对象数组
            Field[] fields = clazz.getDeclaredFields();
            for (Field fd : fields) {
                String fieldName = fd.getName();
                String fieldType = fd.getType().getName();
                if (fieldName.equalsIgnoreCase("_id") || fieldName.equalsIgnoreCase("id")) {
                    continue;
                } else {
                    sb.append(fieldName).append(Utils.getColumnType(fieldType)).append(", ");
                }
            }
            int len = sb.length();
            sb.replace(len - 2, len, ")");
            Log.d(TAG, "the result is " + sb.toString());
            return sb.toString();
        }

工具类代码如下:

package com.xjp.databasedemo;

import android.text.TextUtils;

import java.util.Locale;

/**
 * Created by xjp on 2016/1/23.
 */
public class DBUtils {
    //得到每一列字段的数据类型
    public static String getColumnType(String type) {
        String value = null;
        if (type.contains("String")) {
            value = " text ";
        } else if (type.contains("int")) {
            value = " integer ";
        } else if (type.contains("boolean")) {
            value = " boolean ";
        } else if (type.contains("float")) {
            value = " float ";
        } else if (type.contains("double")) {
            value = " double ";
        } else if (type.contains("char")) {
            value = " varchar ";
        } else if (type.contains("long")) {
            value = " long ";
        }
        return value;
    }

    //得到表名
    public static String getTableName(Class<?> clazz){
        return clazz.getSimpleName();
    }

    public static String capitalize(String string) {
        if (!TextUtils.isEmpty(string)) {
            return string.substring(0, 1).toUpperCase(Locale.US) + string.substring(1);
        }
        return string == null ? null : "";
    }
}

如此一来,顾客创立数据库表就变的很粗大略了,传入Person类的品类(Person.class卡塔尔(قطر‎作为参数,那么代码就帮你创建出了一张名叫Person的表。使用代码如下:

class MySqLiteHelper extends SQLiteOpenHelper {

        ..................

        @Override
        public void onCreate(SQLiteDatabase db) {
            createTable(db);
        }
        /**
         * 根据制定类名创建表
         */
        private void createTable(SQLiteDatabase db) {
            db.execSQL(getCreateTableSql(Person.class));

        ..............
    }

是或不是非常的粗略!!!领导再也不用怀念本人不会成立数据库了。

SQL语句:SELECT column list FROM table WHERE expr ORDER BY column list; 通过SQLiteDatabase类的query()函数:

Android中SQLite 使用方法详明

除去能够动用文件或SharedPreferences存款和储蓄数据,还足以选用使用SQLite数据仓库储存款和储蓄数据。

数据库操作–插入

SQLite是Android平台软件开荒中会平时接收的数据库成品,作为大器晚成款轻型数据库,SQLite的宏图指标正是是嵌入式的,何况最近意气风发度在超多嵌入式产品中利用了它,它占用财富足够的低,在嵌入式设备中,恐怕只要求几百K的内部存款和储蓄器就够。上边大家少年老成并来探问针对Android平台的SQlite 3的运用。

中间DBHelper世襲了SQLiteOpenHelper,作为维护和保管数据库的基类,DBManager是自立门户在DBHelper之上,封装了常用的事务方法,Person是我们的person表对应的JavaBean,MainActivity就是我们显示的界面。

values.put(“name”, “传智播客”卡塔尔(قطر‎;//key为字段名,value为值

数据库删除操作

1.SQlite 通过文件来保存数据库,一个文本正是一个数据库。
2.数据库里又包括数个表格;
3.每种表格里面包含了八个记录;
4.种种记录由四个字段组成;
5.各种字段都有其对应的值;
6.每一个值都得以钦命项目。

正如上边所述,数据库第三回成立时onCreate方法会被调用,大家得以施行制造表的言语,当系统一发布掘版本变化未来,会调用onUpgrade方法,大家得以实行改过表布局等说话。

 2. Person实体

友好动手写Android数据库框架

信赖广大开拓者跟自家相通,每一次都很窝心自个儿写数据库,并且那贰个数据库语句也时时记不住。当然网络也可以有成都百货上千很好的数据库框架,你能够直接拿来用,可是非常多时候我们的体系,极度是二个Mini的Andrond应用原来用到的数据库构造比较轻巧,没必要去用那多少个有一点肥壮的框架。当然,即便你用那个框架,当你相逢标题时,你是或不是也得去修正它?你要修改外人的框架必得的读懂旁人的宏图代码。所以无论是从那么些角度出发,你都得调控轻便的数据库操作。那么那篇博客就从轻便的数据库操作来上学Android数据库相关知识点,然后一步一步去搭建自个儿的回顾型数据库框架,今后就再也不用忧郁惊愕去写数据库了,直接拿本人的数据库框架用就好了。

table 要翻新的笔录所在的表名。
values 要校订的字段值。
whereClause Where子句。更新哪些记录。
whereArgs Where子句中的'?'替换串。
试行update操作时,假设只给大器晚成部分字段赋值,那么update后,未有赋值的字段还是维持原本的值不改变。

为了方便我们面向对象的行使数据,大家建一个Person类,对应person表中的字段,如下:

public static SQLiteDatabase openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory)

数据库查询框架

1.查询数据库中兼有数据

  /**
     * 查询数据库中所有的数据
     *
     * @param clazz
     * @param <T>   以 List的形式返回数据库中所有数据
     * @return 返回list集合
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    public <T> List<T> findAll(Class<T> clazz) {
        Cursor cursor = db.query(clazz.getSimpleName(), null, null, null, null, null, null);
        return getEntity(cursor, clazz);
    }

.....................

    /**
     * 从数据库得到实体类
     *
     * @param cursor
     * @param clazz
     * @param <T>
     * @return
     */
    private <T> List<T> getEntity(Cursor cursor, Class<T> clazz) {
        List<T> list = new ArrayList<>();
        try {
            if (cursor != null && cursor.moveToFirst()) {
                do {
                    Field[] fields = clazz.getDeclaredFields();
                    T modeClass = clazz.newInstance();
                    for (Field field : fields) {
                        Class<?> cursorClass = cursor.getClass();
                        String columnMethodName = getColumnMethodName(field.getType());
                        Method cursorMethod = cursorClass.getMethod(columnMethodName, int.class);

                        Object value = cursorMethod.invoke(cursor, cursor.getColumnIndex(field.getName()));

                        if (field.getType() == boolean.class || field.getType() == Boolean.class) {
                            if ("0".equals(String.valueOf(value))) {
                                value = false;
                            } else if ("1".equals(String.valueOf(value))) {
                                value = true;
                            }
                        } else if (field.getType() == char.class || field.getType() == Character.class) {
                            value = ((String) value).charAt(0);
                        } else if (field.getType() == Date.class) {
                            long date = (Long) value;
                            if (date <= 0) {
                                value = null;
                            } else {
                                value = new Date(date);
                            }
                        }
                        String methodName = makeSetterMethodName(field);
                        Method method = clazz.getDeclaredMethod(methodName, field.getType());
                        method.invoke(modeClass, value);
                    }
                    list.add(modeClass);
                } while (cursor.moveToNext());
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return list;
    }

查询全体数据同时自动保存在List中回到,无须客户去将Cursor剖判成对象封装。简单易用,自须求四个措施三个参数就可以。调用代码如下:

List<Person> list = dbManager.findAll(Person.class);

至上轻巧啊!

2.询问钦点条件的多少

 /**
     * 根据指定条件返回满足条件的记录
     *
     * @param clazz      类
     * @param select     条件语句 :("id>?")
     * @param selectArgs 条件(new String[]{"0"}) 查询id=0的记录
     * @param <T>        类型
     * @return 返回满足条件的list集合
     */
    public <T> List<T> findByArgs(Class<T> clazz, String select, String[] selectArgs) {
        Cursor cursor = db.query(clazz.getSimpleName(), null, select, selectArgs, null, null, null);
        return getEntity(cursor, clazz);
    }

3.基于钦点id查询一条数据

/**
     * 通过id查找制定数据
     *
     * @param clazz 指定类
     * @param id    条件id
     * @param <T>   类型
     * @return 返回满足条件的对象
     */
    public <T> T findById(Class<T> clazz, int id) {
        Cursor cursor = db.query(clazz.getSimpleName(), null, "id=" + id, null, null, null, null);
        List<T> list = getEntity(cursor, clazz);
        return list.get(0);
    }

客商代码调用如下:

 Person p = dbManager.findById(Person.class, 1);

查询id=1的多寡,第叁个参数为Person类型,第三个参数为id值,查询结果直接保存在Person对象p里。

以上就是本身包裹的数据库查询操作,轻松易用,无须记住quary()方法中的那么多参数,也不要本身去二个个拆解深入分析Cursor数据并保留。该办法一步到位,直接回到Person类型的list会集。注释:当中使用的有的艺术自己权且并未有贴出来,文章最后作者会把例子和代码都贴出来。

1.SQLiteOpenHelper 抽象类:通过从此类世襲完成顾客类,来提供数据库展开、关闭等操作函数。
2.SQLiteDatabase 数据库访谈类:试行对数据库的插入记录、查询记录等操作。
3.SQLiteCursor 查询构造操作类:用来访谈查询结果中的记录。

图片 3

}

.dump 能够见见数据库中的数据。

package com.scott.db; 

import android.content.Context; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteOpenHelper; 

public class DBHelper extends SQLiteOpenHelper { 

  private static final String DATABASE_NAME = "test.db"; 
  private static final int DATABASE_VERSION = 1; 

  public DBHelper(Context context) { 
    //CursorFactory设置为null,使用默认值 
    super(context, DATABASE_NAME, null, DATABASE_VERSION); 
  } 

  //数据库第一次被创建时onCreate会被调用 
  @Override 
  public void onCreate(SQLiteDatabase db) { 
    db.execSQL("CREATE TABLE IF NOT EXISTS person" + 
        "(_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER, info TEXT)"); 
  } 

  //如果DATABASE_VERSION值被改为2,系统发现现有数据库版本不同,即会调用onUpgrade 
  @Override 
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
    db.execSQL("ALTER TABLE person ADD COLUMN other STRING"); 
  } 
} 

SQLiteDatabase db = databaseHelper.getWritableDatabase();

复制代码 代码如下:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:orientation="vertical" 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent"> 
  <Button 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="add" 
    android:onClick="add"/> 
  <Button 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="update" 
    android:onClick="update"/> 
  <Button 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="delete" 
    android:onClick="delete"/> 
  <Button 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="query" 
    android:onClick="query"/> 
  <Button 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="queryTheCursor" 
    android:onClick="queryTheCursor"/> 
  <ListView 
    android:id="@+id/listView" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"/> 
</LinearLayout> 


package com.scott.db; 

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 

import android.app.Activity; 
import android.database.Cursor; 
import android.database.CursorWrapper; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.ListView; 
import android.widget.SimpleAdapter; 
import android.widget.SimpleCursorAdapter; 


public class MainActivity extends Activity { 

  private DBManager mgr; 
  private ListView listView; 

  @Override 
  public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    listView = (ListView) findViewById(R.id.listView); 
    //初始化DBManager 
    mgr = new DBManager(this); 
  } 

  @Override 
  protected void onDestroy() { 
    super.onDestroy(); 
    //应用的最后一个Activity关闭时应释放DB 
    mgr.closeDB(); 
  } 

  public void add(View view) { 
    ArrayList<Person> persons = new ArrayList<Person>(); 

    Person person1 = new Person("Ella", 22, "lively girl"); 
    Person person2 = new Person("Jenny", 22, "beautiful girl"); 
    Person person3 = new Person("Jessica", 23, "sexy girl"); 
    Person person4 = new Person("Kelly", 23, "hot baby"); 
    Person person5 = new Person("Jane", 25, "a pretty woman"); 

    persons.add(person1); 
    persons.add(person2); 
    persons.add(person3); 
    persons.add(person4); 
    persons.add(person5); 

    mgr.add(persons); 
  } 

  public void update(View view) { 
    Person person = new Person(); 
    person.name = "Jane"; 
    person.age = 30; 
    mgr.updateAge(person); 
  } 

  public void delete(View view) { 
    Person person = new Person(); 
    person.age = 30; 
    mgr.deleteOldPerson(person); 
  } 

  public void query(View view) { 
    List<Person> persons = mgr.query(); 
    ArrayList<Map<String, String>> list = new ArrayList<Map<String, String>>(); 
    for (Person person : persons) { 
      HashMap<String, String> map = new HashMap<String, String>(); 
      map.put("name", person.name); 
      map.put("info", person.age + " years old, " + person.info); 
      list.add(map); 
    } 
    SimpleAdapter adapter = new SimpleAdapter(this, list, android.R.layout.simple_list_item_2, 
          new String[]{"name", "info"}, new int[]{android.R.id.text1, android.R.id.text2}); 
    listView.setAdapter(adapter); 
  } 

  public void queryTheCursor(View view) { 
    Cursor c = mgr.queryTheCursor(); 
    startManagingCursor(c); //托付给activity根据自己的生命周期去管理Cursor的生命周期 
    CursorWrapper cursorWrapper = new CursorWrapper(c) { 
      @Override 
      public String getString(int columnIndex) { 
        //将简介前加上年龄 
        if (getColumnName(columnIndex).equals("info")) { 
          int age = getInt(getColumnIndex("age")); 
          return age + " years old, " + super.getString(columnIndex); 
        } 
        return super.getString(columnIndex); 
      } 
    }; 
    //确保查询结果中有"_id"列 
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2,  
        cursorWrapper, new String[]{"name", "info"}, new int[]{android.R.id.text1, android.R.id.text2}); 
    ListView listView = (ListView) findViewById(R.id.listView); 
    listView.setAdapter(adapter); 
  } 
} 

               onCreate(db);

复制代码 代码如下:

目前的主流移动设备像android、摩托罗拉等都利用SQLite作为复杂数据的囤积引擎,在我们为移动设备支出应用程序时,大概将在动用到SQLite来存款和储蓄大家大批量的多寡,所以大家就供给调节活动设备上的SQLite开采本事。对于Android平台来讲,系统内置了增加的API来供开辟职员操作SQLite,大家得以轻便的完毕对数据的存取。

db.close();

若是使用一个数据仓库储存款和储蓄一个表格,表格中保留了多条记下,各样记录蕴涵3个字段,分别是: ID、name、age。 从SQLiteOpenHelper世袭实现一个类,全数对数据库的操作都封装在这里类中。

然后,我们供给一个DBManager,来封装大家具备的事情方法,代码如下:

update(卡塔尔国方法的使用:

数据库根底概念

上边就向我们介绍一下SQLite常用的操作方法,为了便于,小编将代码写在了Activity的onCreate中:

SQLiteDatabase db = databaseHelper.getWritableDatabase();

创立数据库

我们收获数据库实例时接收了getWritableDatabase(State of Qatar方法,恐怕朋友们会有疑难,在getWritableDatabase(卡塔尔(قطر‎和getReadableDatabase(卡塔尔国中,你怎么接受前者作为一切应用的数据库实例呢?在这里边小编想和富贵人家根本深入分析一下这点。
大家来看一下SQLiteOpenHelper中的getReadableDatabase(卡塔尔国方法:

 

从SQLite的总体创造和查询进度大家能够观望,在Android平台,由于SQLite的特点,一切以文件为主,未有各种的定义。大家得以因而询问来赢得满意条件的笔录,通过SQL指令来操作数据库。别的,我们应当熟记Android平台操作SQLite的多少个类:SQLiteOpenHelper抽象类、SQLiteDatabase数据库访问类以至SQLiteCursor 查询布局操作类。

db.insert(String table, String nullColumnHack, ContentValues values); 
db.update(String table, Contentvalues values, String whereClause, String whereArgs); 
db.delete(String table, String whereClause, String whereArgs); 

仍可以够透过Context对象调用

public void onCreate(SQLiteDatabase db) { 
    StringBuilder sql = new StringBuilder(); 
    sql.append("CREATE TABLE "); 
    sql.append(TBL_NAME); 
    sql.append(" ("); 
    sql.append(FIELD_ID + " TEXT PRIMARY KEY NOT NULL, "); 
    sql.append(FIELD_NAME + " TEXT, "); 
    sql.append(FIELD_AGE + " INTEGER"); 
    sql.append(");"); 
    db.execSQL(sql.toString()); 
}

在getReadableDatabase(State of Qatar方法中,首先推断是还是不是已存在数据库实例并且是开辟状态,假如是,则直接重返该实例,不然试图拿走贰个可读写格局的数据库实例,假如越过磁盘空间已满等境况得到战败以来,再以只读格局张开数据库,获取数据库实例并回到,然后为mDatabase赋值为新型开拓的数据库实例。既然有十分的大大概调用到getWritableDatabase(卡塔尔方法,大家将在看一下了:

  • db.rar (64.2 KB)

public void insert(String id, String name, int age) { 
if( mDb == null ) mDb = getWritableDatabase(); 
ContentValues v = new ContentValues(); 
v.put("id", id); 
v.put("name", name); 
if(age > 0) v.put("age", age); 
mDb.insert(TBL_NAME, "null", v);

上面大家先来看一下DBHelper:

    //类未有实例化,是不能用作父类构造器的参数,必需注解为静态

向表格中添增加少

db.rawQuery(String sql, String[] selectionArgs); 
db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy); 
db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit); 
db.query(String distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit); 

       Package name: com.jbridge.db

sqlite3 database.db 步向了sqlite操作分界面。

意气风发旦准备从CursorWrapper里获取“_id”对应的列索引,我们就重返查询结果里“id”对应的列索引就可以。
终极大家来看一下结实怎么着:

  

Android平台下数据库相关类

假如手动去管理Cursor的话会非常的麻烦,还会有一定的风险,管理不当的话运营时期就能够现身相当,还好Activity为我们提供了startManagingCursor(Cursor cursorState of Qatar方法,它会依赖Activity的生命周期去管理当前的Cursor对象,上边是该措施的求证:

execSQL(String sql, Object[] bindArgs卡塔尔方法的第叁个参数为SQL语句,第二个参数为SQL语句中占位符参数的值,参数值在数组中的顺序要和占位符之处对应。

.help能够看看命令扶持。

public synchronized SQLiteDatabase getReadableDatabase() { 
  if (mDatabase != null && mDatabase.isOpen()) { 
    // 如果发现mDatabase不为空并且已经打开则直接返回 
    return mDatabase; 
  } 

  if (mIsInitializing) { 
    // 如果正在初始化则抛出异常 
    throw new IllegalStateException("getReadableDatabase called recursively"); 
  } 

  // 开始实例化数据库mDatabase 

  try { 
    // 注意这里是调用了getWritableDatabase()方法 
    return getWritableDatabase(); 
  } catch (SQLiteException e) { 
    if (mName == null) 
      throw e; // Can't open a temp database read-only! 
    Log.e(TAG, "Couldn't open " + mName + " for writing (will try read-only):", e); 
  } 

  // 如果无法以可读写模式打开数据库 则以只读方式打开 

  SQLiteDatabase db = null; 
  try { 
    mIsInitializing = true; 
    String path = mContext.getDatabasePath(mName).getPath();// 获取数据库路径 
    // 以只读方式打开数据库 
    db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY); 
    if (db.getVersion() != mNewVersion) { 
      throw new SQLiteException("Can't upgrade read-only database from version " + db.getVersion() + " to " 
          + mNewVersion + ": " + path); 
    } 

    onOpen(db); 
    Log.w(TAG, "Opened " + mName + " in read-only mode"); 
    mDatabase = db;// 为mDatabase指定新打开的数据库 
    return mDatabase;// 返回打开的数据库 
  } finally { 
    mIsInitializing = false; 
    if (db != null && db != mDatabase) 
      db.close(); 
  } 
} 

    db.execSQL("insert into person(name, age) values(?,?)", new Object[]{"传智播客", 4}卡塔尔(قطر‎;

能够经过以下指令来查看结果:

Cursor结果集须求留意些什么:一个最亟需介意的是,在大家的结果集中一定要满含八个“_id”的列,不然SimpleCursorAdapter就能够反目不认人,为啥必要求这么啊?因为那源于SQLite的正规,主键以“_id”为行业内部。消除办法有

地点两条SQL语句在同叁个业务中推行。

有二种艺术能够向表格中添扩张少,生机勃勃种是由此SQLiteDatabase提供的execSQL函数直接实行SQL指令; 风华正茂种是经过SQLiteDatabase提供的insert函数,此函数把SQL语句进行了包装方便客户使用。

何以包装Cursor:我们会选取到CursorWrapper对象去包装大家的Cursor对象,实现大家供给的数码转变专业,这一个CursorWrapper实际上是达成了Cursor接口。我们查询获得到的Cursor其实是Cursor的援引,而系统实际再次回到给大家的必定是Cursor接口的四个得以达成类的靶子实例,大家用CursorWrapper包装这么些实例,然后再使用SimpleCursorAdapter将结果显示到列表上。

      DataBaseOpenHelper继承自SQLiteOpenHelper类。大家须求成立数据表,必须重写onCreate(更新时重写onUpgrade方法)方法,在此个主意中开创数据表。

int SQLiteDatabase.delete(String table, String whereClause, String[] whereArgs);

你可能感兴趣的小说:

  • Android SQLite数据库增加和删除改查操作的接受详明
  • Android开拓之SQLite的运用方式
  • Android使用SQLite数据库的简易实例
  • android成立数据库(SQLite卡塔尔国保存图片示例
  • 浓重Android SQLite 事务管理精解
  • Android--SQLite(增,删,改,查)操作实例代码
  • android中sqlite的按准则查找的小例子

动用SQLiteDatabase对象足以做到对数据开展增添(Create卡塔尔国、查询(Retrieve卡塔尔国、更新(UpdateState of Qatar和删除(Delete卡塔尔国操作(那个操作简单称谓为CRUD)。对SQLiteDatabase的上学,大家理应注重理解execSQL(卡塔尔(قطر‎和rawQuery(卡塔尔国方法。 execSQL(卡塔尔(قطر‎方法能够实行insert、delete、update和CREATE TABLE之类有改观行为的SQL语句; rawQuery(卡塔尔方法能够实行select语句。

在onCreate函数中创造表格:

地点就是SQLite的主干使用,但在实际上费用中,为了能够越来越好的管制和保卫安全数据库,大家会卷入叁个继续自SQLiteOpenHelper类的数据库操作类,然后以这一个类为根基,再装进大家的事情逻辑情势。

db.close(); 

Cursor SQLiteDatabase.query(String table,
String[] columns, String selection, String[] selectionArgs,
String groupBy, String having, String orderBy);

在推行完上边的代码后,系统就能在/data/data/[PACKAGE_NAME]/databases目录下生成三个“test.db”的数据库文件,如图:

 

ContentValues v = new ContentValues();
 v.put("id", "101");
 v.put("name", "user 101");
 v.put("age", 44);
 mDb.insert("mytable", "null", v);

package com.scott.db; 

public class Person { 
  public int _id; 
  public String name; 
  public int age; 
  public String info; 

  public Person() { 
  } 

  public Person(String name, int age, String info) { 
    this.name = name; 
    this.age = age; 
    this.info = info; 
  } 
} 

               db.execSQL("DROP TABLE IF EXISTS person");

复制代码 代码如下:

package com.scott.db; 

import java.util.ArrayList; 
import java.util.List; 

import android.content.ContentValues; 
import android.content.Context; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 

public class DBManager { 
  private DBHelper helper; 
  private SQLiteDatabase db; 

  public DBManager(Context context) { 
    helper = new DBHelper(context); 
    //因为getWritableDatabase内部调用了mContext.openOrCreateDatabase(mName, 0, mFactory); 
    //所以要确保context已初始化,我们可以把实例化DBManager的步骤放在Activity的onCreate里 
    db = helper.getWritableDatabase(); 
  } 

  /** 
   * add persons 
   * @param persons 
   */ 
  public void add(List<Person> persons) { 
    db.beginTransaction(); //开始事务 
    try { 
      for (Person person : persons) { 
        db.execSQL("INSERT INTO person VALUES(null, ?, ?, ?)", new Object[]{person.name, person.age, person.info}); 
      } 
      db.setTransactionSuccessful(); //设置事务成功完成 
    } finally { 
      db.endTransaction();  //结束事务 
    } 
  } 

  /** 
   * update person's age 
   * @param person 
   */ 
  public void updateAge(Person person) { 
    ContentValues cv = new ContentValues(); 
    cv.put("age", person.age); 
    db.update("person", cv, "name = ?", new String[]{person.name}); 
  } 

  /** 
   * delete old person 
   * @param person 
   */ 
  public void deleteOldPerson(Person person) { 
    db.delete("person", "age >= ?", new String[]{String.valueOf(person.age)}); 
  } 

  /** 
   * query all persons, return list 
   * @return List<Person> 
   */ 
  public List<Person> query() { 
    ArrayList<Person> persons = new ArrayList<Person>(); 
    Cursor c = queryTheCursor(); 
    while (c.moveToNext()) { 
      Person person = new Person(); 
      person._id = c.getInt(c.getColumnIndex("_id")); 
      person.name = c.getString(c.getColumnIndex("name")); 
      person.age = c.getInt(c.getColumnIndex("age")); 
      person.info = c.getString(c.getColumnIndex("info")); 
      persons.add(person); 
    } 
    c.close(); 
    return persons; 
  } 

  /** 
   * query all persons, return cursor 
   * @return Cursor 
   */ 
  public Cursor queryTheCursor() { 
    Cursor c = db.rawQuery("SELECT * FROM person", null); 
    return c; 
  } 

  /** 
   * close database 
   */ 
  public void closeDB() { 
    db.close(); 
  } 
} 
  1. package com.jbridge.service;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Currency;  
  5. import java.util.List;  
  6.   
  7. import android.R.string;  
  8. import android.content.ContentValues;  
  9. import android.content.Context;  
  10. import android.database.Cursor;  
  11. import android.database.sqlite.SQLiteDatabase;  
  12.   
  13. import com.jbridge.domain.Person;  
  14.   
  15. public class OtherPersonService {  
  16.   
  17.     private DataBaseOpenHelper dbOpenHelper;  
  18.   
  19.     // private Context context;  
  20.   
  21.     public OtherPersonService(Context context) {  
  22.         // this.context = context;  
  23.         dbOpenHelper = new DataBaseOpenHelper(context);  
  24.     }  
  25.   
  26.     public void save(Person person) {  
  27.         SQLiteDatabase database = dbOpenHelper.getWritableDatabase();  
  28.         ContentValues contentValues = new ContentValues();  
  29.         contentValues.put("name", person.getName());  
  30.         contentValues.put("age", person.getAge());  
  31.         database.insert("person", null, contentValues);  
  32.     }  
  33.   
  34.     public void update(Person person) {  
  35.         SQLiteDatabase database = dbOpenHelper.getWritableDatabase();  
  36.         ContentValues contentValues = new ContentValues();  
  37.         contentValues.put("name", person.getName());  
  38.         contentValues.put("age", person.getAge());  
  39.         database.update("person", null, "personid=?",  
  40.                 new String[] { String.valueOf(person.getId()) });  
  41.     }  
  42.   
  43.     public Person find(Integer id) {  
  44.         SQLiteDatabase database = dbOpenHelper.getReadableDatabase();  
  45.         Cursor cursor = database.query("person", new String[] { "personid",  
  46.                 "name", "age" }, "personid=?",  
  47.                 new String[] { String.valueOf(id) }, null, null, null);  
  48.         if (cursor.moveToNext()) {  
  49.             return new Person(cursor.getInt(0), cursor.getString(1),  
  50.                     cursor.getShort(2));  
  51.         }  
  52.         return null;  
  53.     }  
  54.   
  55.     public void delete(Integer... ids) {  
  56.         if (ids.length > 0) {  
  57.             StringBuffer sb = new StringBuffer();  
  58.             String[] strIds = new String[ids.length];  
  59.             // for (Integer id : ids) {  
  60.             // sb.append('?').append(',');  
  61.             // }  
  62.             for (int i = 0; i < strIds.length; i++) {  
  63.                 sb.append('?').append(',');  
  64.                 strIds[i] = String.valueOf(ids[i]);  
  65.             }  
  66.             sb.deleteCharAt(sb.length() - 1);  
  67.             SQLiteDatabase database = dbOpenHelper.getWritableDatabase();  
  68.             database.delete("person", "personid in(" + sb.toString() + ")",  
  69.                     strIds);  
  70.         }  
  71.     }  
  72.   
  73.     public List<Person> getScrollData(int startResult, int maxResult) {  
  74.         List<Person> persons = new ArrayList<Person>();  
  75.         SQLiteDatabase database = dbOpenHelper.getReadableDatabase();  
  76.         Cursor cursor = database.query("person", new String[] { "personid",  
  77.                 "name", "age" }, null, null, null, null, "personid desc",  
  78.                 startResult + "," + maxResult);  
  79.         while (cursor.moveToNext()) {  
  80.             persons.add(new Person(cursor.getInt(0), cursor.getString(1),  
  81.                     cursor.getShort(2)));  
  82.         }  
  83.         return persons;  
  84.     }  
  85.   
  86.     public long getCount() {  
  87.         SQLiteDatabase database = dbOpenHelper.getReadableDatabase();  
  88.         Cursor cursor = database.query("person", new String[] { "count(*)" },  
  89.                 null, null, null, null, null);  
  90.         if (cursor.moveToNext()) {  
  91.             return cursor.getLong(0);  
  92.         }  
  93.         return 0;  
  94.     }  
  95.   
  96. }  

    package com.jbridge.service;

    import java.util.ArrayList; import java.util.Currency; import java.util.List;

    import android.R.string; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase;

    import com.jbridge.domain.Person;

    public class OtherPersonService {

    private DataBaseOpenHelper dbOpenHelper;
    
    // private Context context;
    
    public OtherPersonService(Context context) {
        // this.context = context;
        dbOpenHelper = new DataBaseOpenHelper(context);
    }
    
    public void save(Person person) {
        SQLiteDatabase database = dbOpenHelper.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put("name", person.getName());
        contentValues.put("age", person.getAge());
        database.insert("person", null, contentValues);
    }
    
    public void update(Person person) {
        SQLiteDatabase database = dbOpenHelper.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put("name", person.getName());
        contentValues.put("age", person.getAge());
        database.update("person", null, "personid=?",
                new String[] { String.valueOf(person.getId()) });
    }
    
    public Person find(Integer id) {
        SQLiteDatabase database = dbOpenHelper.getReadableDatabase();
        Cursor cursor = database.query("person", new String[] { "personid",
                "name", "age" }, "personid=?",
                new String[] { String.valueOf(id) }, null, null, null);
        if (cursor.moveToNext()) {
            return new Person(cursor.getInt(0), cursor.getString(1),
                    cursor.getShort(2));
        }
        return null;
    }
    
    public void delete(Integer... ids) {
        if (ids.length > 0) {
            StringBuffer sb = new StringBuffer();
            String[] strIds = new String[ids.length];
            // for (Integer id : ids) {
            // sb.append('?').append(',');
            // }
            for (int i = 0; i < strIds.length; i++) {
                sb.append('?').append(',');
                strIds[i] = String.valueOf(ids[i]);
            }
            sb.deleteCharAt(sb.length() - 1);
            SQLiteDatabase database = dbOpenHelper.getWritableDatabase();
            database.delete("person", "personid in(" + sb.toString() + ")",
                    strIds);
        }
    }
    
    public List<Person> getScrollData(int startResult, int maxResult) {
        List<Person> persons = new ArrayList<Person>();
        SQLiteDatabase database = dbOpenHelper.getReadableDatabase();
        Cursor cursor = database.query("person", new String[] { "personid",
                "name", "age" }, null, null, null, null, "personid desc",
                startResult + "," + maxResult);
        while (cursor.moveToNext()) {
            persons.add(new Person(cursor.getInt(0), cursor.getString(1),
                    cursor.getShort(2)));
        }
        return persons;
    }
    
    public long getCount() {
        SQLiteDatabase database = dbOpenHelper.getReadableDatabase();
        Cursor cursor = database.query("person", new String[] { "count(*)" },
                null, null, null, null, null);
        if (cursor.moveToNext()) {
            return cursor.getLong(0);
        }
        return 0;
    }
    

    }

adb shell施行后步入shell;

在上边的代码示例中,已经采用了那多少个常用艺术中的一些,关于愈来愈多的消息,我们能够参谋官方文书档案中的表达。
末段当大家成功了对数据库的操作后,记得调用SQLiteDatabase的close(卡塔尔方法释放数据库连接,不然轻便现身SQLiteException。

Java代码  

复制代码 代码如下:

此间须要留意的是SimpleCursorAdapter的应用,当大家利用那么些适配器时,大家必须要先得到三个Cursor对象,这里面有多少个难点:如什么地方理Cursor的生命周期,假设包装Cursor,Cursor结果集都要求介怀哪些。

        int age = cursor.getInt(2State of Qatar;//获取第三列的值

CREATE TABLE mytable (id TEXT PRIMARY KEY NOT NULL, name TEXT, age INTEGER);

地方三种都以常用的查询办法,第风流倜傥种最为简单,将兼具的SQL语句都集体到四个字符串中,使用占位符替代实际参数,selectionArgs就是占位符实际参数集;下边包车型大巴三种参数都很周围,columns表示要查询的列所知名称集,selection表示WHERE之后的标准化语句,能够接收占位符,groupBy钦定分组的列名,having钦定分组条件,合营groupBy使用,orderBy钦命排序的列名,limit内定分页参数,distinct能够内定“true”或“false”表示要不要过滤重复值。须求专心的是,selection、groupBy、having、orderBy、limit那多少个参数中不包蕴“WHERE”、“GROUP BY”、“HAVING”、“O福特ExplorerDE奥迪Q3 BY”、“LIMIT”等SQL关键字。

 flags参数可以是 OPEN_READWRITE, OPEN_READONLY ,CREATE_IF_NECESSARY, NO_LOCALIZED_COLLATO冠道S两个的多个或多少个(多少个格局组合用|隔开).

1.通过execSQL(“INSERT INTO mytable VALUES(‘idStr', 'nameStr', 20State of Qatar;”卡塔尔国;能够插入一条记下,当插入记录出错开上下班时间会抛出非常须求管理。
2.经过insert函数:insert函数供给二个ContentValues类型的值,此类型肖似于hashmap,三个key,多个值配成风度翩翩对。key正是字段名。

图片 4

         ......略

onCreate函数只会在数据库第三次创造时调用,所以那边切合做一些数据库早先化操作。

public synchronized SQLiteDatabase getWritableDatabase() { 
  if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) { 
    // 如果mDatabase不为空已打开并且不是只读模式 则返回该实例 
    return mDatabase; 
  } 

  if (mIsInitializing) { 
    throw new IllegalStateException("getWritableDatabase called recursively"); 
  } 

  // If we have a read-only database open, someone could be using it 
  // (though they shouldn't), which would cause a lock to be held on 
  // the file, and our attempts to open the database read-write would 
  // fail waiting for the file lock. To prevent that, we acquire the 
  // lock on the read-only database, which shuts out other users. 

  boolean success = false; 
  SQLiteDatabase db = null; 
  // 如果mDatabase不为空则加锁 阻止其他的操作 
  if (mDatabase != null) 
    mDatabase.lock(); 
  try { 
    mIsInitializing = true; 
    if (mName == null) { 
      db = SQLiteDatabase.create(null); 
    } else { 
      // 打开或创建数据库 
      db = mContext.openOrCreateDatabase(mName, 0, mFactory); 
    } 
    // 获取数据库版本(如果刚创建的数据库,版本为0) 
    int version = db.getVersion(); 
    // 比较版本(我们代码中的版本mNewVersion为1) 
    if (version != mNewVersion) { 
      db.beginTransaction();// 开始事务 
      try { 
        if (version == 0) { 
          // 执行我们的onCreate方法 
          onCreate(db); 
        } else { 
          // 如果我们应用升级了mNewVersion为2,而原版本为1则执行onUpgrade方法 
          onUpgrade(db, version, mNewVersion); 
        } 
        db.setVersion(mNewVersion);// 设置最新版本 
        db.setTransactionSuccessful();// 设置事务成功 
      } finally { 
        db.endTransaction();// 结束事务 
      } 
    } 

    onOpen(db); 
    success = true; 
    return db;// 返回可读写模式的数据库实例 
  } finally { 
    mIsInitializing = false; 
    if (success) { 
      // 打开成功 
      if (mDatabase != null) { 
        // 如果mDatabase有值则先关闭 
        try { 
          mDatabase.close(); 
        } catch (Exception e) { 
        } 
        mDatabase.unlock();// 解锁 
      } 
      mDatabase = db;// 赋值给mDatabase 
    } else { 
      // 打开失败的情况:解锁、关闭 
      if (mDatabase != null) 
        mDatabase.unlock(); 
      if (db != null) 
        db.close(); 
    } 
  } 
} 

任由第多个参数是还是不是含有数据,试行Insert(卡塔尔国方法肯定会增多一条记下,即便第多个参数为空,会增多一条除主键之外任何字段值为Null的笔录。Insert(卡塔尔(قطر‎方法内部实际上通过布局insert语句达成多少的丰盛,Insert(卡塔尔方法的第三个参数用于钦命空值字段的名号,相信我们对此参数会深感纠缠,此参数的功效是干嘛的?是那样的:假如第四个参数values 为Null大概成分个数为0, Insert(State of Qatar方法断定要增加一条除了主键之外别的字段为Null值的笔录,为了满意那条insert语句的语法, insert语句必需给定叁个字段名,如:insert into person(name卡塔尔国values(NULL卡塔尔国,假设不给定字段名 , insert语句就成了如此: insert into person(卡塔尔国values(卡塔尔国,显著那不知足规范SQL的语法。对于字段名,建议接纳主键之外的字段,假使使用了INTEGE福特Explorer类型的主键字段,推行相像insert into person(personid卡塔尔国values(NULLState of Qatar的insert语句后,该主键字段值也不会为NULL。若是第几个参数values 不为Null而且成分的个数大于0 ,能够把第三个参数设置为null。

public DbHelper(Context context, String name, CursorFactory factory, int version) { 
        super(context, name, factory, version); 
    }

末段,让大家看一下什么样使用这几个数据操作方法来展现数据,下边是MainActivity.Java的结构文件和代码:

         private static final String name = "itcast"; //数据库名称

Parameters:

/** 
   * This method allows the activity to take care of managing the given 
   * {@link Cursor}'s lifecycle for you based on the activity's lifecycle. 
   * That is, when the activity is stopped it will automatically call 
   * {@link Cursor#deactivate} on the given Cursor, and when it is later restarted 
   * it will call {@link Cursor#requery} for you. When the activity is 
   * destroyed, all managed Cursors will be closed automatically. 
   * 
   * @param c The Cursor to be managed. 
   * 
   * @see #managedQuery(android.net.Uri , String[], String, String[], String) 
   * @see #stopManagingCursor 
   */ 

Cursor是结果集游标,用于对结果集进行随机拜望,如果大家纯熟jdbc, 其实Cursor与JDBC中的ResultSet功能超级帅似。使用moveToNext(卡塔尔国方法能够将游标从当前进移动到下豆蔻年华行,即使已经移过了结果集的最后大器晚成行,再次来到结果为false,不然为true。别的Cursor 还会有常用的moveToPrevious(卡塔尔方法(用于将游标从近年来进移动到上黄金时代行,如若已经移过了结果集的率先行,重返值为false,不然为true )、moveToFirst(卡塔尔(قطر‎方法(用于将游标移动到结果集的首先行,借使结果集为空,再次回到值为false,否则为true )和moveToLast(卡塔尔方法(用于将游标移动到结果集的最后大器晚成行,假使结果集为空,重返值为false,不然为true ) 。

以下概念都以在Android平台的SQlite约束下的知道:

多谢阅读,希望能帮助到我们,多谢大家对本站的支撑!

最后记住,不管用何种方法展开了数据库,得到的SQLite对象不再利用时,都要调用close(卡塔尔国来关闭展开的数据库,否则抛出IllegalStateException至极。

此函数中的参数name正是数据库名称,也便是数据库文件名; version则从1早先,当现在数据库的报表以至字段发生变化时,客商能够抓牢此version,进而触发onUpgrade(卡塔尔到达旧数据进级的效率。

我们在DBManager布局方法中实例化DBHelper并拿走一个SQLiteDatabase对象,作为全数应用的数据库实例;在拉长五个Person音信时,我们使用了事务管理,确认保证数据完整性;最终大家提供了一个closeDB方法,释放数据库能源,那一个步骤在

 

假诺v中的key未有完全的钦赐全数字段,举例少name只怕少id,那么记录是不是被成功插入要依附表格创立时的字段限定来调节, 譬喻少name,那么此记录会插入,只是name字段的值为NULL;若是少id,那么记录不会被插入,因为创设时钦定了NOT NULL.

看完上边的经过之后,大家兴许就明白了无数,如若不是在境遇磁盘空间已满等情事,getReadableDatabase()日常都会回到和getWritableDatabase(卡塔尔(قطر‎同样的数据库实例,所以大家在DBManager布局方法中运用getWritableDatabase(卡塔尔(قطر‎获取整个应用所选拔的数据库实例是卓有效用的。当然如若你真正顾忌这种景观会时有产生,那么您能够先用getWritableDatabase(卡塔尔国获取数据实例,假若境遇特别,再试图用getReadableDatabase(卡塔尔(قطر‎获取实例,当然此时你获取的实例只好读不可能写了。

除去语句:delete from 表名 where 条件子句。如:delete from person  where id=10

数据库名称即文件名;表格有自个儿的称号;记录未有称谓;各个字段皆闻明称。在SQlite中,记录未有各种的概念,不设有第意气风发、第二此类的定义;只好通过查询来拿到满意条件的笔录。大家因此施行SQL指令来操作数据库。

db.executeSQL(String sql); 
db.executeSQL(String sql, Object[] bindArgs);//sql语句中使用占位符,然后第二个参数是实际的参数集 

先是次调用getWritableDatabase(卡塔尔(قطر‎或getReadableDatabase(卡塔尔国方法后,SQLiteOpenHelper会缓存当前的SQLiteDatabase实例,SQLiteDatabase实例符合规律意况下会维持数据库的展开状态,所以在你不再须求SQLiteDatabase实例时,请及时调用close(卡塔尔方法释放资源。生机勃勃旦SQLiteDatabase实例被缓存,多次调用getWritableDatabase(卡塔尔(قطر‎或getReadableDatabase(State of Qatar方法取得的都以如出风流浪漫辙实例。

从表格中除去记录:

除开集合的方式之外,他们还有些的操作方法:

4、别的, SQLite 在言之有序CREATE TABLE 语句时,会忽略 CREATE TABLE 语句中跟在字段名前面的数据类型音讯,如下边语句会忽视name字段的类型音讯:

地点的代码中山大学多包含了大多数的数据库操作;对于增进、更新和删除来讲,大家都足以动用

         private static final String name = "itcast"; //数据库名称

上述四个章程的第1个参数都是表示要操作的表名;insert中的第二个参数表示豆蔻年华旦插入的数量每一列都为空的话,要求钦赐此行中某一列的称号,系统将此列设置为NULL,不至于现身错误;insert中的第七个参数是ContentValues类型的变量,是键值对构成的Map,key代表列名,value代表该列要插入的值;update的第三个参数也很临近,只可是它是立异该字段key为新型的value值,第多少个参数whereClause代表WHERE表达式,比如“age > ? and age < ?”等,最终的whereArgs参数是占位符的骨子里参数值;delete方法的参数也是朝气蓬勃致。

 4.编写PersonService类

CursorWrapper cursorWrapper = new CursorWrapper(c) { 
  @Override 
  public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException { 
    if (columnName.equals("_id")) { 
      return super.getColumnIndex("id"); 
    } 
    return super.getColumnIndexOrThrow(columnName); 
  } 
}; 

orderBy:相当于select语句order by关键字背后的黄金时代部分,如:personid desc, age asc;

c.move(int offset); //以当前位置为参考,移动到指定行 
c.moveToFirst();  //移动到第一行 
c.moveToLast();   //移动到最后一行 
c.moveToPosition(int position); //移动到指定行 
c.moveToPrevious(); //移动到前一行 
c.moveToNext();   //移动到下一行 
c.isFirst();    //是否指向第一条 
c.isLast();   //是否指向最后一条 
c.isBeforeFirst(); //是否指向第一条之前 
c.isAfterLast();  //是否指向最后一条之后 
c.isNull(int columnIndex); //指定列是否为空(列基数为0) 
c.isClosed();    //游标是否已关闭 
c.getCount();    //总数据项数 
c.getPosition();  //返回当前游标所指向的行数 
c.getColumnIndex(String columnName);//返回某列名对应的列索引值 
c.getString(int columnIndex);  //返回当前行指定列的值 

public abstract String[] databaseList(卡塔尔国;//再次回到私有数据库目录全部数据库名字

图片 5

Java代码  

delete(卡塔尔方法的接受:

上一篇:Android 应用开垦性质优化完全解析 下一篇:没有了

Copyright © 2015-2019 http://www.carrefourstation.com. 澳门新莆京手机网站-新蒲京娱乐场有限公司 版权所有