一、使用嵌入式关系型SQLite数据库存储数据
在Android平台上,集成了一个嵌入式关系型数据库——SQLite,SQLite3支持NULL、INTEGER、REAL(浮点数字)、 TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型只有五种,但实际上sqlite3也接受varchar(n)、 char(n)、decimal(p,s) 等数据类型,只不过在运算或保存时会转成对应的五种数据类型。 SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么。例如:可以在Integer类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。 但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数, 当向这种字段保存除整数以外的数据时,将会产生错误。 另外,在编写CREATE TABLE 语句时,你可以省略跟在字段名称后面的数据类型信息,如下面语句你可以省略name字段的类型信息:
CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))
SQLite可以解析大部分标准SQL语句,如:
复制代码 代码如下:
查询语句:select from 表名 where 条件子句 group by 分组字句 having order by 排序子句
如: select from person
select from person order by id desc
select name from person group by name having count()>1
分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录
select from Account limit 5 offset 3 或者 select from Account limit 3,5
插入语句:insert into 表名(字段列表) values(值列表)。如: insert into person(name, age) values(‘传智',3)
更新语句:update 表名 set 字段名=值 where 条件子句。如:update person set name=‘传智‘ where id=10
删除语句:delete from 表名 where 条件子句。如:delete from person where id=10
二、使用SQLiteOpenHelper对数据库进行版本管理
我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用软件时创建出应用使用到的数据库表结构及添加一些初始化记录,另外在软件升级的时候,也需要对数据表结构进行更新。那么,我们如何才能实现在用户初次使用或升级软件时自动在用户的手机上创建出应用需要的数据库表呢?总不能让我们在每个需要安装此软件的手机上通过手工方式创建数据库表吧?因为这种需求是每个数据库应用都要面临的,所以在Android系统,为我们提供了一个名为SQLiteOpenHelper的抽象类,必须继承它才能使用,它是通过对数据库版本进行管理来实现前面提出的需求。
为了实现对数据库版本进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion),前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结构。当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法获取用于 *** 作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库时才会被调用,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。onUpgrade()方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号,而数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的变更,修改了数据库表结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为2(有同学问设置为3行不行?当然可以,如果你愿意,设置为100也行),并且在 onUpgrade()方法里面实现表结构的更新。当软件的版本升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断,然后作出相应的表结构及数据更新。
getWritableDatabase()和 getReadableDatabase()方法都可以获取一个用于 *** 作数据库的SQLiteDatabase实例。但 getWritableDatabase() 方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用getWritableDatabase()打开数据库就会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。
注意:getWritableDatabase(),getReadableDatabase的区别是当数据库写满时,调用前者会报错,调用后者不会,所以如果不是更新数据库的话,最好调用后者来获得数据库连接。
代码:
复制代码 代码如下:
public class DatabaseHelper extends SQLiteOpenHelper {
//类没有实例化,是不能用作父类构造器的参数,必须声明为静态
private static final String name = "ljqdb"; //数据库名称
private static final int version = 1; //数据库版本
public DatabaseHelper(Context context) {
//第三个参数CursorFactory指定在执行查询时获得一个游标实例的工厂类,设置为null,代表使用系统默认的工厂类
super(context, name, null, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
dbexecSQL("CREATE TABLE IF NOT EXISTS person (
personid integer primary key autoincrement, name varchar(20), age INTEGER)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
dbexecSQL(" ALTER TABLE person ADD phone VARCHAR(12) NULL "); //往表中增加一列
// DROP TABLE IF EXISTS person 删除表
}
}
在实际项目开发中,当数据库表结构发生更新时,应该避免用户存放于数据库中的数据丢失。
三、使用SQLiteDatabase *** 作SQLite数据库
Android提供了一个名为SQLiteDatabase的类,该类封装了一些 *** 作数据库的API,使用该类可以完成对数据进行添加(Create)、查询(Retrieve)、更新(Update)和删除(Delete) *** 作(这些 *** 作简称为CRUD)。对SQLiteDatabase的学习,我们应该重点掌握execSQL()和rawQuery()方法。execSQL()方法可以执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句; rawQuery()方法用于执行select语句。
execSQL()方法的使用例子:
复制代码 代码如下:
SQLiteDatabase db = ;
dbexecSQL("insert into person(name, age) values('林计钦', 24)");
dbclose();
执行上面SQL语句会往person表中添加进一条记录,在实际应用中, 语句中的“林计钦”这些参数值会由用户输入界面提供,如果把用户输入的内容原样组拼到上面的insert语句, 当用户输入的内容含有单引号时,组拼出来的SQL语句就会存在语法错误。要解决这个问题需要对单引号进行转义,也就是把单引号转换成两个单引号。有些时候用户往往还会输入像“ & ”这些特殊SQL符号,为保证组拼好的SQL语句语法正确,必须对SQL语句中的这些特殊SQL符号都进行转义,显然,对每条SQL语句都做这样的处理工作是比较烦琐的。 SQLiteDatabase类提供了一个重载后的execSQL(String sql, Object[] bindArgs)方法,使用这个方法可以解决前面提到的问题,因为这个方法支持使用占位符参数()。使用例子如下:
复制代码 代码如下:
SQLiteDatabase db = ;
dbexecSQL("insert into person(name, age) values(,)", new Object[]{"传智播客", 4});
dbclose();
execSQL(String sql, Object[] bindArgs)方法的第一个参数为SQL语句,第二个参数为SQL语句中占位符参数的值,参数值在数组中的顺序要和占位符的位置对应。
SQLiteDatabase的rawQuery()用于执行select语句,使用例子如下:
复制代码 代码如下:
SQLiteDatabase db = ;
Cursor cursor = dbrawQuery("select from person", null);
while (cursormoveToNext()) {
int personid = cursorgetInt(0); //获取第一列的值,第一列的索引从0开始
String name = cursorgetString(1);//获取第二列的值
int age = cursorgetInt(2);//获取第三列的值
}
cursorclose();
dbclose();
rawQuery()方法的第一个参数为select语句;第二个参数为select语句中占位符参数的值,如果select语句没有使用占位符,该参数可以设置为null。带占位符参数的select语句使用例子如下:
复制代码 代码如下:
Cursor cursor = dbrawQuery("select from person where name like and age=", new String[]{"%林计钦%", "4"});
Cursor是结果集游标,用于对结果集进行随机访问,如果大家熟悉jdbc, 其实Cursor与JDBC中的ResultSet作用很相似。使用moveToNext()方法可以将游标从当前行移动到下一行,如果已经移过了结果集的最后一行,返回结果为false,否则为true。另外Cursor 还有常用的moveToPrevious()方法(用于将游标从当前行移动到上一行,如果已经移过了结果集的第一行,返回值为false,否则为true )、moveToFirst()方法(用于将游标移动到结果集的第一行,如果结果集为空,返回值为false,否则为true )和moveToLast()方法(用于将游标移动到结果集的最后一行,如果结果集为空,返回值为false,否则为true ) 。
除了前面给大家介绍的execSQL()和rawQuery()方法, SQLiteDatabase还专门提供了对应于添加、删除、更新、查询的 *** 作方法: insert()、delete()、update()和query() 。这些方法实际上是给那些不太了解SQL语法的菜鸟使用的,对于熟悉SQL语法的程序员而言,直接使用execSQL()和rawQuery()方法执行SQL语句就能完成数据的添加、删除、更新、查询 *** 作。
1、设置一个DB_VERSION
public static final int DB_VERSION = 1;2、当你要更新表的时候就把DB_VERSION+1,就会触发onUpgrade,数据库就更新了,记得采纳
public DBHelper() {// for test
daoConfig = new DbManagerDaoConfig()
setDbName(DB_NAME)
setDbVersion(DB_VERSION)
setDbDir(EnvironmentgetExternalStorageDirectory())
setDbOpenListener(new DbManagerDbOpenListener() {
@Override
public void onDbOpened(DbManager db) {
dbgetDatabase()enableWriteAheadLogging();
}
})
setDbUpgradeListener(new DbManagerDbUpgradeListener() {
@Override
public void onUpgrade(DbManager db, int oldVersion, int newVersion) {
updateTable(db, xxclass);
}
});
}
SQL语句中的更新语句update是最常用的语句之一,下面将介绍update语句的三种使用方法,供参考
一、环境:
MySQL-5041-win32
Windows
XP
professional
二、建立测试环境:
DROP
TABLE
IF
EXISTS
t_test;
CREATE
TABLE
t_test
(
bs
bigint(20)
NOT
NULL
auto_increment,
username
varchar(20)
NOT
NULL,
password
varchar(20)
default
NULL,
remark
varchar(200)
default
NULL,
PRIMARY
KEY
(bs)
)
ENGINE=InnoDB
AUTO_INCREMENT=4
DEFAULT
CHARSET=gbk;
INSERT
INTO
t_test
VALUES
(1,'lavasoft','123456',NULL);
INSERT
INTO
t_test
VALUES
(2,'hello',NULL,NULL);
INSERT
INTO
t_test
VALUES
(3,'haha',zz,tt);
三、测试
1、set一个字段
在表t_test中设置第二条记录(bs为2)的password为''。
update
t_test
t
set
tpassword
=
''
where
tbs
=
2;
2、set多个字段
在表t_test中设置第一条记录(bs为1)的password为''、remark为''。
update
t_test
t
set
tpassword
=
'',
tremark
=
''
where
tbs
=
1;
3、set
null值
在表t_test中设置第三条记录(bs为3)的password为null、remark为null。
update
t_test
t
set
tpassword
=
null,
tremark
=
null
where
tbs
=
3;
这个是按照标准语法写的,在不同的数据库系统中,update还有更多的写法,但是标准写法都是支持的。以上三个例子为了说明情况,每次都更新一行。在实际中,可以通过where语句约束来控制更新行数。
可以使用 TableAdapterUpdate 方法更新(编辑)数据库中的记录。 TableAdapterUpdate 方法根据传入的参数提供了若干次执行不同 *** 作的重载。 了解调用这些不同方法签名的结果非常重要。 说明 如果您的应用程序不使用 TableAdapter,您就可以使用命令对象更新数据库中的记录(例如, ExecuteNonQuery)。 有关使用命令对象更新数据的更多信息,请参见下面的“使用命令对象更新记录”。 下表描述了各种 TableAdapterUpdate 方法的行为: 方法 说明TableAdapterUpdate(DataTable) 尝试将 DataTable 中的所有更改保存到数据库中。 (这包括从表中移除所有删除的行、将插入的行添加到表中、更新表中已更改的所有行。) TableAdapterUpdate(DataSet) 虽然该参数带有一个数据集,但 TableAdapter 仍尝试将 TableAdapter 的关联 DataTable 中的所有更改保存到数据库中。 (这包括从表中移除所有删除的行、将插入的行添加到表中、更新表中已更改的所有行。) 说明 TableAdapter 的关联 DataTable 是最初配置 TableAdapter 时创建的 DataTable。 TableAdapterUpdate(DataRow) 尝试将指示 DataRow 中的更改保存到数据库中。 TableAdapterUpdate(DataRows()) 尝试将 DataRow 数组中任意行中的更改保存到数据库中。 TableAdapterUpdate("new column values", "original column values") 尝试保存由原始列值标识的单行中的更改。 通常,当应用程序使用数据集以独占方式存储数据时,您使用的是带有 DataSet、 DataTable 或 DataRow 的TableAdapterUpdate 方法。 通常,当应用程序使用对象存储数据时,您使用的是带有列值的 TableAdapterUpdate 方法。 如果TableAdapter 没有带列值的 Update 方法,就表示已将 TableAdapter 配置为使用存储过程,或者已将它的 GenerateDBDirectMethods 属性设置为 false。 尝试从 “数据集设计器”内将TableAdapter 的 GenerateDBDirectMethods 属性设置为 true,然后保存该数据集以重新生成 TableAdapter。 如果TableAdapter 仍没有带列值的 Update 方法,该表就可能没有提供足够多的架构信息以区分各行(例如,未在表中设置任何主键)。 使用TableAdapter 更新现有记录 根据应用程序的需要,TableAdapter 提供了更新数据库中记录的不同方法。 如果应用程序使用数据集存储数据,则可以在所需的 DataTable 中简单地更新记录,然后调用 TableAdapterUpdate 方法并传入 DataSet、 DataTable、 DataRow 或 DataRow 数组。 上表描述了不同的 Update 方法。 用带有 DataSet、DataTable、DataRow 或 DataRows() 的 TableAdapterUpdate 方法更新数据库中的记录 通过直接编辑 DataTable 中的 DataRow,编辑所需的 DataTable 中的记录。 有关更多信息,请参见 如何:编辑数据表中的行。 在 DataTable 中对行进行编辑后,请调用 TableAdapterUpdate 方法。 通过传入完整的 DataSet、 DataTable、 DataRow 数组或单个 DataRow,您可以控制要更新的数据量。 下面的代码显示如何编辑 DataTable 中的记录,然后调用 TableAdapterUpdate 方法将更改保存到数据库中。 (此示例使用 Northwind 数据库 Region 表。) ' Locate the row you want to update Dim regionRow As NorthwindDataSetRegionRow regionRow = NorthwindDataSet_RegionFindByRegionID(1) ' Assign the new value to the desired column regionRowRegionDescription = "East" ' Save the updated row to the database MeRegionTableAdapterUpdate(MeNorthwindDataSet_Region) // Locate the row you want to update NorthwindDataSetRegionRow regionRow; regionRow = northwindDataSetRegionFindByRegionID(1); // Assign the new value to the desired column regionRowRegionDescription = "East"; // Save the updated row to the database thisregionTableAdapterUpdate(thisnorthwindDataSetRegion); 如果应用程序使用对象存储应用程序中的数据,您就可以使用 TableAdapter 的 DBDirect 方法将数据从对象中直接发送到数据库。 这些方法可让您将各列的单个值传递为方法参数。 调用此方法用传入该方法的列值更新数据库中的现有记录。 以下过程使用 Northwind Region 表作为示例。 使用带有列值的 TableAdapterUpdate 方法更新数据库中的记录 调用TableAdapter 的 Update 方法,以参数的形式为每一列传入新值和原始值。 说明 如果没有实例可用,请实例化您要使用的 TableAdapter。 Dim regionTableAdapter As New NorthwindDataSetTableAdaptersRegionTableAdapter regionTableAdapterUpdate(1, "East", 1, "Eastern") NorthwindDataSetTableAdaptersRegionTableAdapter regionTableAdapter = new NorthwindDataSetTableAdaptersRegionTableAdapter(); regionTableAdapterUpdate(1, "East", 1, "Eastern"); 使用命令对象更新记录 下面的示例使用命令对象直接更新数据库中的现有记录。 有关使用命令对象执行命令和存储过程的更多信息,请参见 将数据获取到应用程序。 以下过程使用 Northwind Region 表作为示例。 使用命令对象更新数据库中的现有记录 创建新的命令对象;设置它的 Connection、CommandType 和CommandText 属性;然后打开一个连接,并执行该命令。 Dim sqlConnection1 As New SystemDataSqlClientSqlConnection("YOUR CONNECTION STRING") Dim cmd As New SystemDataSqlClientSqlCommand cmdCommandType = SystemDataCommandTypeText cmdCommandText = "UPDATE Region SET [RegionDescription] = @RegionDescription WHERE [RegionID] = @RegionID" cmdParametersAddWithValue("@RegionDescription", "East") cmdParametersAddWithValue("@RegionID", "1") cmdConnection = sqlConnection1 sqlConnection1Open() cmdExecuteNonQuery() sqlConnection1Close() SystemDataSqlClientSqlConnection sqlConnection1 = new SystemDataSqlClientSqlConnection("YOUR CONNECTION STRING"); SystemDataSqlClientSqlCommand cmd = new SystemDataSqlClientSqlCommand(); cmdCommandType = SystemDataCommandTypeText; cmdCommandText = "UPDATE Region SET [RegionDescription] = @RegionDescription WHERE [RegionID] = @RegionID"; cmdParametersAddWithValue("@RegionDescription", "East"); cmdParametersAddWithValue("@RegionID", "1"); cmdConnection = sqlConnection1; sqlConnection1Open(); cmdExecuteNonQuery(); sqlConnection1Close(); 安全性 您必须具有访问正尝试连接到的数据库的权限,以及更新所需表中记录的权限。 请参见任务 如何:删除数据库中的记录 如何:将新记录插入数据库 如何:将数据从对象保存到数据库概念 TableAdapter 概述 准备应用程序以接收数据 将数据获取到应用程序 在Visual Studio 中将控件绑定到数据 在应用程序中编辑数据 验证数据 保存数据其他资源 Visual Studio 的数据应用程序概述 连接到 Visual Studio 中的数据
1、首先开启遥控器以及飞行器,联网后App会d窗提示更新数据库,点击更新。
2、其次此时App会提示连接飞行器和遥控器,然后将飞行器和遥控器通过OTG线连接。
3、最后即可下载并更新数据库。
更新需要在程序后端里边完成如:
自增方法:db('数据表名')->where('条件')->setInc('字段',值);
例子:db('team')->where('teamid',$teamid)->setInc('score',3);//球队积分加3
自减方法:db('数据表名')->where('条件')->setDec('字段',值);
例子:db('team')->where('teamid',$teamid)->setDec('score',3);//球队积分减3
更新数据库时,可以用以下方式(我常用的,还有其他的方式):
一、用recordset记录集的方式。
rsopen "select from tablename where id="&request("id"),conn,1,3
rs("a")=request("a")
rs("b")=request("b")
rsupdate
rsclose
用这种方式进行数据更新,有个好处就是当要更新的数据量非常大时,也可以很顺利的更新成功(比如备注型字段的数据,中间还包含了换行等等的)
二、用sql的update语句:
connexecute("update tablename set a='"&request("a")&"',b='"&request("b")&"',c="&request("c")&" where id="&request("id"))
用上面的方法更新数据时,如果是SQL数据库,而你要更新的数据内容里含有比如单引号['],双横线[--]之类的特殊字符,就会更新不成功的,因为这时候SQL会认为是非法字符,而把你的单引号给去掉的。而且当如果更新的是备注型字段,里面包含了换行等字符,也会显得很乱。但用这种方法更新,速度比用recordset的速度要快很多,因为毕竟这是直接更新数据库,而recordset是对update的封装形式。
其实更新数据库,非常简单,如果你对字符串连接的单引号,双引号,&号的使用觉得很混乱,那就用recordset的方式进行,这样会很清晰,一点都不会有混乱的感觉的。而如果你能熟练的使用单引号,双引号,&号,那么你用update语句更新数据库,就大在的提交了速度(当然如果数据量小,我建议用recordset记录集的方式,因为这种方式一个字段对应一个值,一行一个,这样下来,很清晰,还可以对每行做个备注,以后改起来也方便。而用update的方式,所有的值和记录全部连在一块,老长的一串,看得人头都发麻,而且update还不能添加特殊字符,比如上面说的单引号等。。。)
以上就是关于android sqlite数据库的更新全部的内容,包括:android sqlite数据库的更新、Android 数据库如何更新、sql数据库更新语句等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)