SQLite数据库的使用
2016-07-13 14:06
399 查看
SQLite数据库
轻量级关系型数据库创建数据库需要使用的api:SQLiteOpenHelper(抽象类,sqlite打开帮助器)
创建MyOperHelper类,继承自SQLiteOperHelper
必须定义一个构造方法:
//arg1:数据库文件的名字 //arg2:游标工厂(传null,使用默认) //arg3:数据库版本(比如刚开始三个字段,然后需要四个版本号,这里给高。这一不能降级) public MyOpenHelper(Context context, String name, CursorFactory factory, int version){}
数据库被创建时会调用:onCreate方法
数据库升级时会调用:onUpgrade方法
我们可以用上文介绍的测试框架,用下边方法测试数据库创建和升级
创建数据库
//创建OpenHelper对象 MyOpenHelper oh = new MyOpenHelper(getContext(), "person.db", null, 1); //获得数据库对象,如果数据库不存在,先创建数据库,后获得,如果存在,则直接获得 SQLiteDatabase db = oh.getWritableDatabase();
getWritableDatabase():打开可读写的数据库
getReadableDatabase():在磁盘空间不足时打开只读数据库,否则打开可读写数据库
创建的数据库文件可以使用SQLite Expert.exe查看。这个工具很好用。
在创建数据库时创建表
public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub db.execSQL("create table person (_id integer primary key autoincrement, name char(10), phone char(20), money integer(20))");//primary主键,autoincrement自增长 }
//(SQLite是简化的字符串,这里的char,integer,是给程序员看的,其实内部都是String,传值时不会检查,但如果传的是错误的数据类型,也不会保存)
//如果下边传的是(‘张三’, ‘159874611’, “abc”),查表,存的实际是0,但不会保存
数据库的增删改查
SQL语句
insert into person (name, phone, money) values (‘张三’, ‘159874611’, 2000);delete from person where name = ‘李四’ and _id = 4;
update person set money = 6000 where name = ‘李四’;
select name, phone from person where name = ‘张三’;
执行SQL语句实现增删改查
//插入 db.execSQL("insert into person (name, phone, money) values (?, ?, ?);", new Object[]{"张三", 15987461, 75000}); //查找 Cursor cs = db.rawQuery("select _id, name, money from person where name = ?;", new String[]{"张三"});
* 测试方法执行前会调用此方法
protected void setUp() throws Exception { super.setUp(); // 获取虚拟上下文对象 oh = new MyOpenHelper(getContext(), "people.db", null, 1); }
* 这里是我的测试源码
//数据库测试 public class TestCase extends AndroidTestCase { //此时测试框架还没有初始化完毕,没有虚拟上下文对象 // private MyOpenHelper oh = new MyOpenHelper(getContext(), "people.db", null, 1); private MyOpenHelper oh; private SQLiteDatabase db; public void test(){ //getContext():获取一个虚拟的上下文 MyOpenHelper oh = new MyOpenHelper(getContext(), "people.db", null, 1); //如果数据库不存在,先创建数据库,再获取可读可写的数据库对象,如果数据库存在,就直接打开 SQLiteDatabase db = oh.getWritableDatabase(); //如果存储空间满了,那么返回只读数据库对象 // SQLiteDatabase db = oh.getReadableDatabase(); } //测试框架初始化完毕之后,在测试方法执行之前,此方法调用 @Override protected void setUp() throws Exception { super.setUp(); oh = new MyOpenHelper(getContext(), "people.db", null, 1); db = oh.getWritableDatabase(); } //测试方法执行完毕之后,此方法调用 @Override protected void tearDown() throws Exception { // TODO Auto-generated method stub super.tearDown(); db.close(); } public void insert(){ // db.execSQL("insert into person (name, salary, phone)values(?, ?, ?)", new Object[]{"老婆[1]", "13000", 138438}); // db.execSQL("insert into person (name, salary, phone)values(?, ?, ?)", new Object[]{"儿子", 14000, "13888"}); db.execSQL("insert into person (name, salary, phone)values(?, ?, ?)", new Object[]{"小小", 14000, "13888"}); } public void delete(){ db.execSQL("delete from person where name = ?", new Object[]{"小小"}); } public void update(){ db.execSQL("update person set phone = ? where name = ?", new Object[]{186666, "儿子"}); } public void select(){ Cursor cursor = db.rawQuery("select name, salary from person", null); while(cursor.moveToNext()){ //通过列索引获取列的值 String name = cursor.getString(cursor.getColumnIndex("name")); String salary = cursor.getString(1); System.out.println(name + ";" + salary); } } public void insertApi(){ //把要插入的数据全部封装至ContentValues对象 ContentValues values = new ContentValues(); values.put("name", "夜煞部落"); values.put("phone", "15999"); values.put("salary", 16000); db.insert("person", null, values); } public void deleteApi(){ int i = db.delete("person", "name = ? and _id = ?", new String[]{"儿子", "3"}); System.out.println(i);//返回值i是影响的行的数量 } public void updateApi(){ ContentValues values = new ContentValues(); values.put("salary", 26000); int i = db.update("person", values, "name = ?", new String[]{"夜煞部落"}); System.out.println(i); } public void selectApi(){ Cursor cursor = db.query("person", null, null, null, null, null, null, null); while(cursor.moveToNext()){ String name = cursor.getString(cursor.getColumnIndex("name")); String phone = cursor.getString(cursor.getColumnIndex("phone")); String salary = cursor.getString(cursor.getColumnIndex("salary")); System.out.println(name + ";" + phone + ";" + salary); } } public void transaction(){ try{ //开启事务 db.beginTransaction(); ContentValues values = new ContentValues(); values.put("salary", 12000); db.update("person", values, "name = ?", new String[]{"小小"}); values.clear(); values.put("salary", 16000); db.update("person", values, "name = ?", new String[]{"儿子"}); int i = 3/0;//如果没有执行下行代码,SQL语句回滚 //设置 事务执行成功 db.setTransactionSuccessful(); } finally{ //关闭事务,同时提交,如果已经设置事务执行成功,那么sql语句就生效了,反之,sql语句回滚 db.endTransaction(); } }
}
使用api实现增删改查
插入//以键值对的形式保存要存入数据库的数据 ContentValues cv = new ContentValues(); cv.put("name", "刘能"); cv.put("phone", 1651646); cv.put("money", 3500); //返回值是改行的主键,如果出错返回-1 long i = db.insert("person", null, cv);
删除
//返回值是删除的行数 int i = db.delete("person", "_id = ? and name = ?", new String[]{"1", "张三"});
修改
ContentValues cv = new ContentValues(); cv.put("money", 25000); int i = db.update("person", cv, "name = ?", new String[]{"赵四"});
查询
//arg1:要查询的字段 //arg2:查询条件 //arg3:填充查询条件的占位符 Cursor cs = db.query("person", new String[]{"name", "money"}, "name = ?", new String[]{"张三"}, null, null, null); while(cs.moveToNext()){ // 获取指定列的索引值 String name = cs.getString(cs.getColumnIndex("name")); String money = cs.getString(cs.getColumnIndex("money")); System.out.println(name + ";" + money); }
事务
保证多条SQL语句要么同时成功,要么同时失败最常见案例:银行转账
事务api
try { //开启事务 db.beginTransaction(); ........... //设置事务执行成功 db.setTransactionSuccessful(); } finally{ //关闭事务 //如果此时已经设置事务执行成功,则sql语句生效,否则不生效 db.endTransaction(); }
把数据库的数据显示至屏幕
任意插入一些数据定义业务bean:Person.java
读取数据库的所有数据
Cursor cs = db.query("person", null, null, null, null, null, null); while(cs.moveToNext()){ String name = cs.getString(cs.getColumnIndex("name")); String phone = cs.getString(cs.getColumnIndex("phone")); String money = cs.getString(cs.getColumnIndex("money")); //把读到的数据封装至Person对象 Person p = new Person(name, phone, money); //把person对象保存至集合中 people.add(p);
把集合中的数据显示至屏幕
LinearLayout ll = (LinearLayout) findViewById(R.id.ll); for(Person p : people){ //创建TextView,每条数据用一个文本框显示 TextView tv = new TextView(this); tv.setText(p.toString()); //把文本框设置为ll的子节点 ll.addView(tv);
}
分页查询
Cursor cs = db.query("person", null, null, null, null, null, null, "0, 10");
ListView
就是用来显示一行一行的条目的MVC结构
M:model模型层,要显示的数据 ————people集合
V:view视图层,用户看到的界面 ————ListView
c:control控制层,操作数据如何显示 ————adapter对象
每一个条目都是一个View对象
BaseAdapter
必须实现的两个方法第一个
//系统调用此方法,用来获知模型层有多少条数据 @Override public int getCount() { return people.size(); }
第二个
//系统调用此方法,获取要显示至ListView的View对象 //position:是return的View对象所对应的数据在集合中的位置 @Override public View getView(int position, View convertView, ViewGroup parent) { System.out.println("getView方法调用" + position); TextView tv = new TextView(MainActivity.this); //拿到集合中的元素 Person p = people.get(position); tv.setText(p.toString()); //把TextView的对象返回出去,它会变成ListView的条目 return tv; }
屏幕上能显示多少个条目,getView方法就会被调用多少次,屏幕向下滑动时,getView会继续被调用,创建更多的View对象显示至屏幕
条目的缓存
当条目划出屏幕时,系统会把该条目缓存至内存,当该条目再次进入屏幕,系统在重新调用getView时会把缓存的条目作为convertView参数传入,但是传入的条目不一定是之前被缓存的该条目,即系统有可能在调用getView方法获取第一个条目时,传入任意一个条目的缓存MainActivity.java
public class MainActivity extends Activity { List<Person> personList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); personList = new ArrayList<Person>(); //把数据库的数据查询出来 MyOpenHelper oh = new MyOpenHelper(this); SQLiteDatabase db = oh.getWritableDatabase(); Cursor cursor = db.query("person", null, null, null, null, null, null, null); while(cursor.moveToNext()){ String _id = cursor.getString(0); String name = cursor.getString(1); String salary = cursor.getString(2); String phone = cursor.getString(3); Person p = new Person(_id, name, phone, salary); personList.add(p); } LinearLayout ll = (LinearLayout) findViewById(R.id.ll); //把数据显示至屏幕 for (Person p : personList) { //1.集合中每有一条元素,就new一个textView TextView tv = new TextView(this); //2.把人物的信息设置为文本框的内容 tv.setText(p.toString()); tv.setTextSize(18); //3.把textView设置为线性布局的子节点 ll.addView(tv); } } }
相关文章推荐
- 实现postfix支持mysql方法
- 几张图看懂列式存储
- Redis学习笔记一——初始Redis
- oracle自定义函数按照某个分隔符拆分字符串
- mysql group by 查询语句
- MySQL事务及锁
- 随机获取Mysql数据表的一条或多条记录
- mysql表名忽略大小写设置
- mysql将多张表COUNT的数据相加
- Oracle Instant Client(即时客户端) 安装与配置
- mysql commit rollback autocommit
- 如果使用EntityFramework6链接Mysql
- MYSQL C API 入门教程
- mysql导入excel数据。 需要选项对应数据库
- Oracle删除后,重装方案有哪些?删除后重装出错?多次安装后出错?如何完全删除Oracle?
- sql server的日期格式转化形式
- Oracle 存储过程实例集锦
- 如何在win7上安装oracle?????安装出错怎么办????
- MySQL定时任务(每天凌晨3点钟执行)
- oracle将一个用户下的所有表复制到以一个用户下