SQLite应用详解
转载请注明出处:http://www.52php.cn/article/p-wozzyetm-pt.html
SQLite是D.Richard Hipp用C语言编写的开源嵌入式引擎,它可以在所有主要的操作系统上运行。值得一提的是,袖珍型的SQLite竟然可以支持高达2TB大小的数据库,每个数据库都是以单个文件的形式存在,这些数据都是以B-Tree的数据结构形式存储在磁盘上。在事务处理方面,SQLite通过数据库级上的独立性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库中读取数据,但只有一个可以写入数据,而在某个进程或线程想数据库执行写操作之前,必须获得独占锁; 在数据类型方面,SQLite采用动态数据类型,当某个值插入到数据库时,SQLite将会检查它的类型,如果该类型与关联的列不匹配,SQLite则会尝试将该值类型转换成该列的类型,如果不能转换,则该值将作为本身的类型存储,SQLite称之为“弱类型”。但有个特例:如果是Integer primary key,则其他类型不会被转换,会报"datatype missmatch"错误。概括来说,SQLite支持NULL、INTEGER、REAL、TEXT及BOLB数据类型,分别代表空值、整型、浮点型、字符串文本、二进制对象。下面将从SQLite命令行操作、在Java中使用SQLite、在Android中使用SQLite等这几个方面带大家来掌握和深入理解SQLite数据库。
SQLite命令行操作在操作之前,大家要先下载SQLite数据库,官方的下载页面是http://sqlite.org/download.html,如果你是windows系统,那个大家可以下载这两个文件
下载完成后分别解压,得到两个可执行文件,如下:
这两个文件可以根据自己的喜欢放置在指定位置,我把它放在了F盘根目录下,下面我们来一步步熟悉一下SQlite的命令行操作: 1)建库C:UsersAdministrator>f: 这里我们执行了sqlite3命令,参数就是数据库的名字,如果该数据库已存在则使用,反之创建一个。当然你也可以在别的目录(可写)下创建数据库,如:F:&;sqlite3 e:test.db。如果大家想了解一下SQLite的其他命令,可以执行".help"命令列出所有命令清单进行查看。 2)建表sqlite> create table student(id integer primary key autoincrement,name varchar(15),age smallint); 3)查看建表语句sqlite> .schema student 4)插入数据sqlite> insert into student values(NULL,'zhangsan',24); 5)分析数据库使用状态(使用刚下载的sqlite3_analyzer.exe工具)--先退出sqlite3,可使用.quit或.exit sqlite> .quit .... INSERT INTO space_used VALUES('sqlite_master','sqlite_master',2,197,117,1,711,1024 6)备份数据——导出我们可以指定输出的目标为一个sql文件,然后再使用.dump命令时,输出信息就会写入指定的文件: F:&;sqlite3 test.db 可以看到,F盘中已经创建了一个名为stu_bk的sql文件:
stu_bk.sql文件的内容为:
如果想恢复标准输出,可以这样设定: sqlite> .output stdout 7)从sql文件中导入表数据——导入为了演示效果,我们先把student表删除再导入: sqlite> drop table if exists student; 可以看到,数据导入成功。我们可以通过一个SQLite的客户端管理工具SQLite Expert来查看一下:
最后我们可以使用“.exit”或“.quit”退出SQLite命令行操作。
在Java中使用SQLite要在Java中使用SQLite,需要下载SQLite相关驱动包,下载地址:https://bitbucket.org/xerial/sqlite-jdbc/downloads,这里我下载的还是以前的sqlite-jdbc-3.7.2.jar,当然你也可以下载最新的jar包。下面开始实例演示: ①新建一个名为sqlite的Java项目
我们引入了刚下载好的sqlite驱动包到类路径下,然后新建一个db的文件夹用于放置数据库文件。 ②新建SQLiteTest.java文件,代码如下: package com.leo.sqlite; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; /** * SQLite在Java中的使用实例 * * @author [*昨日重现*] lhy_ycu@163.com * @since version 1.0 * @datetime 2015年5月18日 上午2:06:48 */ public class SQLiteTest { public static void main(String[] args) throws Exception { Class.forName("org.sqlite.JDBC"); Connection conn = DriverManager.getConnection("jdbc:sqlite:db/test.db"); Statement st = conn.createStatement(); st.executeUpdate("drop table if exists person"); st.executeUpdate("create table person(id integer,name varchar(15))"); st.executeUpdate("insert into person values(1,'zhangsan')"); st.executeUpdate("insert into person values(2,'lisi')"); st.executeUpdate("insert into person values(3,'wangwu')"); ResultSet rs = st.executeQuery("select * from person"); while (rs.next()) { System.out.println("id = " + rs.getInt("id") + ",name = " + rs.getString("name")); } st.close(); conn.close(); } }执行SQLiteTest.java文件,运行结果如下: 这时候,我们刷新一下sqlite项目,可以看到db文件夹下生成了一个test.db文件: 【注意】SQLite只提供数据库级的锁定,并且SQLite没有用户账户的概念,而是根据文件系统来确定所有数据库的权限。
在Android中使用SQLite现在主流移动设备像Android、iPhone等都使用SQLite作为复杂数据的存储引擎,在我们为移动设备开发应用程序时,也许就要使用到SQLite来存储大量的数据,所以我们有要掌握移动设备上SQLite开发技巧。对于Android平台来说,系统内置了大量丰富的API来供我们操作SQLite。下面开始演示一下SQLite的常用操作,为了方便,这里就将代码写在了Activity的onCreate方法中: /** * 在Android中使用SQLite:建库、建表、CRUD等简单操作 * * @author [*昨日重现*] lhy_ycu@163.com * @since version 1.0 * @datetime 2015-5-18 下午3:55:53 */ public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 打开或创建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.setName("zhangsan"); person.setAge(34); // 插入数据 db.execSQL("insert into person values(NULL,?,?)",new Object[] { person.getName(),person.getAge() }); person.setName("lisi"); person.setAge(32); // ContentValues以键值对的形式存放数据 ContentValues values = new ContentValues(); values.put("name",person.getName()); values.put("age",person.getAge()); // 插入ContentValues中的数据 db.insert("person",null,values); values = new ContentValues(); values.put("age","40"); // 更新数据 db.update("person",values,"name = ? ",new String[] { "zhangsan" }); Cursor c = db.rawQuery("select * from person where age>= ?",new String[] { "32" }); 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("leo","_id = " + _id + ",name = " + name + ",age = " + age); } c.close(); // 删除数据 // db.delete("person","age < ?",new String[] { "36" }); // 关闭当前数据库 db.close(); // 删除test.db数据库 // deleteDatabase("test.db"); } }在Android手机或模拟器上运行后,系统就会在/data/data/[项目包名]databases目录下生成一个"test.db"的数据库文件,我们可以用手机下载一个名为Root Explorer的软件进行查看,如图:
上面的示例代码基本上囊括了数据库大部分操作,对于添加、更新和删除,我们都可以使用 1.db.executeSQL(String sql); 除了统一的形式之外,它们还有各自的操作方法: 1.db.insert(String table,String nullColumnHack,ContentValues values); 参数说明:以上3个方法的第一个参数都是要操作的表名;①insert中的第二个参数表示要插入的数据每一列都为空的话,需要指定此行中某一列的名称,系统将此列设置为null,不至于出现错误;insert的第三个参数为ContentValues类型的变量,是键值对组成的Map,key代表列名,value代表要插入的值。②update的第二个参数也很类似,只不过它是更新该字段key为最新的value值,第三个参数表示where的表达式,比如:"age > ? and age < ? "等,最后一个参数是占位符的实际参数值。③delete方法同上。 下面说说查询操作,查询操作相对于上面的几种操作要复杂一些,因为我们要经常面对各种各样的查询条件,所以系统也考虑到这种复杂性,为我们提供了较为丰富的查询形式: 1.db.rawQuery(String sql,String[] selectionArgs); 参数说明:上面几种都是常用的查询方法,第一种最为简单,将所有的SQL语句都组织到一个字符串中,使用占位符代替实际参数,selectionArgs就是占位符实际参数集;下面的几种参数都很类似,columns表示要查询的列所有名称集,selection表示WHERE之后的条件语句,可以使用占位符,groupBy指定分组的列名,having指定分组条件,配合groupBy使用,orderBy指定排序的列名,limit指定分页参数,distinct可以指定“true”或“false”表示要不要过滤重复值。 最后,他们同时返回一个Cursor对象,代表数据集的游标,有点类似于JDBC里面的的ResultSet结果集。对于Cursor对象,常用的方法有很多(大家也可以通过查考官方API文档进行查阅),常用方法如下: 1.c.move(int offset); //以当前位置为参考,移动到指定行 最后当我们完成了对数据库的操作后,记得调用SQLiteDatabase的close()方法释放数据库连接,否则容易出现SQLiteException。
其中DBHelper继承了SQLiteOpenHelper,作为维护和管理数据库的基类,DBManager是建立在DBHelper之上,封装了常用的业务方法,Person是我们的person表对应的JavaBean,MainActivity就是我们显示的界面。 下面我们先来看一下DBHelper: import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; /** * 维护和管理数据库 * * @author [*昨日重现*] lhy_ycu@163.com * @since version 1.0 */ public class DBHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "test.db"; private static final int DATABASE_VERSION = 1; public DBHelper(Context context) { super(context,DATABASE_NAME,DATABASE_VERSION); } // 数据库第一次被创建时onCreate会被调用 /** * @param db * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase) */ @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub db.execSQL("create table student(_id integer primary key autoincrement,name text,age integer,info text);"); } // 如果DATABASE_VERSION值改变了,系统发现现有数据库版本不同,即会调用onUpgrade /** * @param db * @param oldVersion * @param newVersion * @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase,* int,int) */ @Override public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion) { // TODO Auto-generated method stub db.execSQL("altertablestudentADDCOLUMNothertext"); } }
正如上面所述,数据库第一次创建时onCreate方法会被调用,我们可以执行创建表的语句,当系统发现版本变化之后,会调用onUpgrade方法,我们可以执行修改表结构等语句。 public class Student { private int id; private String name; private int age; private String info; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } @Override public String toString() { return "Student [id=" + id + ",name=" + name + ",age=" + age + ",info=" + info + "]"; } } 然后,我们需要一个DBManager,来封装我们所有的业务方法,代码如下: import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; /** * DBManager是建立在DBHelper之上,封装了常用的业务方法 * * @author [*昨日重现*] lhy_ycu@163.com * @since version 1.0 */ public class DBManager { private DBHelper helper; private SQLiteDatabase db; public DBManager(Context context) { helper = new DBHelper(context); // 因为getWritableDatabase内部调用了mContext.openOrCreateDatabase(mName,mFactory); // 所以要确保context已初始化,我们可以把实例化DBManager的步骤放在Activity的onCreate里 db = helper.getWritableDatabase(); } /** * 添加学生 * * @param student */ public void add(Student student) { db.beginTransaction();// 开启事务 try { db.execSQL("insert into student values(null,new Object[] { student.getName(),student.getAge(),student.getInfo() }); db.setTransactionSuccessful();// 设置事务成功完成 } catch (SQLException e) { e.printStackTrace(); } finally { db.endTransaction();// 结束事务 } } /** * 更新年龄和基本信息 * * @param student */ public void update(Student student) { ContentValues values = new ContentValues(); values.put("age",student.getAge()); values.put("info",student.getInfo()); db.update("student","name = ?",new String[] { student.getName() }); values.clear(); } /** * 删除年龄大的 * * @param student */ public void delete(Student student) { db.delete("student","age >= ?",new String[] { student.getAge() + "" }); } /** * 查询所有学生 * * @return */ public List<Student> query() { List<Student> list = new ArrayList<Student>(); Cursor c = db.rawQuery("select * from student",null); while (c.moveToNext()) { Student student = new Student(); student.setId(c.getInt(c.getColumnIndex("_id"))); student.setName(c.getString(c.getColumnIndex("name"))); student.setAge(c.getInt(c.getColumnIndex("age"))); student.setInfo(c.getString(c.getColumnIndex("info"))); list.add(student); } c.close(); return list; } /** * 关闭数据库 */ public void closeDB() { db.close(); } } 我们在DBManager构造方法中实例化DBHelper并获取一个SQLiteDatabase对象,作为整个应用的数据库实例;在添加Student信息时,我们采用了事务处理,确保数据完整性;最后我们提供了一个closeDB方法,释放数据库资源,这一个步骤在我们整个应用关闭时执行,这个环节容易被忘记,所以大家要注意。下面开始编写我们的布局文件和MainActivity界面: <LinearLayout 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:orientation="vertical" > <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="add" android:text="add" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="update" android:text="update" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="delete" android:text="delete" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="query" android:text="query" /> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> </LinearLayout>MainActivity文件: public class MainActivity extends Activity { private DBManager mgr; private ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.listview); mgr = new DBManager(this);// 初始化DBManager } public void add(View view) { Student student = new Student(); student.setName("张三"); student.setAge(22); student.setInfo("good boy"); mgr.add(student); } public void update(View view) { Student student = new Student(); student.setAge(21); student.setName("张三"); student.setInfo("bad boy"); mgr.update(student); } public void delete(View view) { Student student = new Student(); student.setAge(18); mgr.delete(student); } public void query(View view) { List<Student> students = mgr.query(); List<Map<String,String>> list = new ArrayList<Map<String,String>>(); for (Student student : students) { HashMap<String,String> map = new HashMap<String,String>(); map.put("name",student.getName()); map.put("info",student.getAge() + " years old," + student.getInfo()); 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); } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); // 应用的最后一个Activity关闭时释放DB mgr.closeDB(); } }最后我们来看下运行结果:
如果是在手机上运行,我们可以使用Root Explorer查看test.db数据库详情;如果在运行在模拟器上,可以使用SQLite Expert查看;当然你也可以用开始讲的SQLite命令行操作,这里就不再演示了。
结束语以上就是SQLite应用详解的所有内容。相信通过这篇博客,大家对SQLite已经有了一个更深刻的认识。
sqlite3可执行工具、驱动、分析器、客户端工具下载 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |