一.SQLite介绍
1.SQLite是一个嵌入式关系型数据库。
2.SQLite存储时支持物种数据类型:NULL,INTERER,REAL(浮点数据),TEXTE(字符串文本)和BLOG(二进制对象)。注:
虽然SQL支持的类型只有五种,但实际上sqlite3也接受varchar(n)、char(n)、decimal(p,s) 等数据类型,只不过在运算或保存时会转成对应的五种数据类型。
3.SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么.特殊情况是定义为INTEGER PRIVATE KEY 类型的字段只能存储64位整数4.SQLite 在解析CREATE TABLE 语句时,会忽略CREATE TABLE 语句中跟在字段名后面的数据类型信息,如下面语句会忽略 name字段的类型信息:数据长度声明是没有用的,即数据长度是没有限制的。但为了增加代码的可读性还是应该加上字段的信息描述
CREATE TABLE diary (_id integer primary keyautoincrement, title varchar(20),content varchar(1000),createtime)
复习标准SQL语句
查询语句:
select * from 表名 where 条件子句 group by 分组字句 having... order by 排序子句
插入语句:
insert into 表名(字段列表) values(值列表)。
修改语句:
update 表名 set 字段名=值 where 条件子句。
删除语句:
delete from 表名 where 条件子句。
二.开发数据库应用的步骤
1.创建数据库
2.编写代码实现增删改查操作
三.使用SQLiteOpenHelper对数据库进行管理
为了实现对数据库进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabasedb, int oldVersion, int newVersion),前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结构。当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法获取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库时才会被调用,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。onUpgrade()方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号,而数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的变更,修改了数据库表结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为2。
四.案例联系-个人日记开发
步骤1.使用SQLiteOpehHelper来完成数据哭的创建
新建包:org.sql.db
新建类:DbHelper
代码如下:
public class DbHelper extends SQLiteOpenHelper {
//数据库的名称可以没有后缀 private static final String sql_NAME="mydb";
private static final int sql_Version=1;
//父类提供的默认构造器
public DbHelper(Context context) {
//// 第三个参数CursorFactory指定在执行查询时获得一个游标实例的工厂类,如果设置为null,代表使用系统默认的工厂类
// 从数据库中查询出来的结果是需要通过这个游标进行访问的
super(context, sql_NAME, null, sql_Version);
// TODO Auto-generated constructor stub
}
/**
* 数据库第一次被创建出来的时候才会被调用,只会调用1次完成数据库中表的创建 SQLiteDatabase类主要是为了操作数据库的
*/
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table diary(_id integer primary key autoincrement,title varchar(20),content varchar(1000),createtime)");
}
//数据库的版本发生改变时,一般是软件升级时才用
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
步骤2.配置好单元测试的环境
在AndroidManifest.xmlwen文件中添加如下代码(具体添加位置同上一篇)
<uses-library android:name="android.test.runner" />
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="cn.bzu.mydiary" >
</instrumentation>
步骤3.编写单元测试代码,测试数据库是否创建成功
public class SqldbTest extends AndroidTestCase {
public void testOncreat(){
DbHelper dbhelper=new DbHelper(getContext());
dbhelper.getWritableDatabase();
}
把生成的数据库文件导出,进入DDMS观察存放位置:data/data/应用的包名/databases/diary.db
如何观察数据库中建立的表呢?
打开数据库:借助于第三方工具SQLiteDeveloper(注册数据库)
导出数据库后,借助于第三方工具注册数据库 查看数据及其表是否创建成功
步骤4.编写实体类
新建包:org.sql.entity
新建类:Diary
具体代码如下:
package org.sql.entity;
public class Diary {
//属性变量最好与数据库中的字段值一一对应
private Integer id;
private String content;
private String title;
private String createtime;
public Diary() {
super();
}
public Diary(String content, String title, String createtime) {
super();
this.content = content;
this.title = title;
this.createtime = createtime;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCreatetime() {
return createtime;
}
public void setCreatetime(String createtime) {
this.createtime = createtime;
}
public String toString(){
return "Disry[title:"+title+",content:"+content+",createtime:"+createtime+"]";
}
}
步骤4.定义数据库访问类DiaryDao,实现增删改查功能
新建包:org.sql.Dao
新建类:DiaryDao
package org.sql.Dao;
import java.util.ArrayList;
import java.util.List;
import org.sql.db.DbHelper;
import org.sql.entity.Diary;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class DiaryDao {
private DbHelper dbhelper;
public DiaryDao(Context context){
dbhelper=new DbHelper(context);
}
//插入数据
public void save(Diary diary){
SQLiteDatabase db=dbhelper.getWritableDatabase();
String sql="insert into diary(title,content,createtime)values(?,?,?)";
db.execSQL(sql, new String[]{diary.getTitle(),diary.getContent(),diary.getCreatetime()});
}
//查找数据
public List<Diary> getAllDiaries(){
List<Diary> diaries=new ArrayList<Diary>();
SQLiteDatabase db=dbhelper.getReadableDatabase();
String sql="select * from diary";
Cursor cursor=db.rawQuery(sql, null);
while(cursor.moveToNext()){
String title=cursor.getString(cursor.getColumnIndex("title"));
String content=cursor.getString(cursor.getColumnIndex("content"));
String createtime=cursor.getString(cursor.getColumnIndex("createtime"));
Diary diary=new Diary(content, title, createtime);
diaries.add(diary);
}
return diaries;
}
//删除数据
public void deleteDiary(Integer id){
// 如果要对数据进行更改,就调用此方法,以读写的方式打开数据库
SQLiteDatabase db=dbhelper.getWritableDatabase();
String sql="delete from diary where id=?";
db.execSQL(sql,new Object[]{id});
}
//更新数据
public void updateDiary(Diary diary){
SQLiteDatabase db=dbhelper.getWritableDatabase();
String sql="update diary set title=?,content=?,createtime=? where _id=?";
db.execSQL(sql, new Object[]{diary.getTitle(),diary.getContent(),diary.getCreatetime(),diary.getId()});
}
//根据id查询数据
public Diary find(Integer id){
Diary diary = null;
//得到游标,最多只有一条数据
/*
* 注意下面的方法并不是以只读的方式打开数据库的,在方法内部首先调用getWritableDatabase()
* 如果磁盘空间满了,就只能读不能写,调用getWritableDatabase()失败,此时会以只读的方式打开数据库*/
SQLiteDatabase db=dbhelper.getReadableDatabase();
String sql="select * from diary where _id=?";
Cursor cursor=db.rawQuery(sql, new String[]{id.toString()});
//如果移动成功代表存在
if(cursor.moveToFirst()){
//只能根据列的索引来获得相应的字段
String title=cursor.getString(cursor.getColumnIndex("title"));
String content=cursor.getString(cursor.getColumnIndex("content"));
String createtime=cursor.getString(cursor.getColumnIndex("createtime"));
diary=new Diary(content, title, createtime);
}
return diary;
}
}
步骤5.编写对应功能的单元测试方法
新建类:DiaryDaoTest
package org.sql.sqlTest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.sql.Dao.DiaryDao;
import org.sql.entity.Diary;
import android.test.AndroidTestCase;
public class DiaryDaoTest extends AndroidTestCase {
//插入
public void testSave(){
DiaryDao diaryDao=new DiaryDao(getContext());
Diary diary=new Diary("我是破坏王", "配音谢娜", getcurrentTime());
//diary=new Diary("迪斯尼乐园米老鼠与唐老鸭", "最爱", getcurrentTime());
//diary=new Diary("致我们终将逝去的青春","《致青春》,导演赵薇",getcurrentTime());
//diary=new Diary("5.26,是他们演唱的最后一场《MAMA》。虽说等新专等了很久,但还是忘不了那首曾经陪我们一年多的歌。到时候会不会有很多人忘记这首歌,原因是听了很久。我不敢保证。或许多年以后,许多行星饭就只听新歌,忘...... ", "鹿晗", getcurrentTime());
diaryDao.save(diary);
}
//查找
public void testgetAllDiaries(){
DiaryDao diaryDao=new DiaryDao(getContext());
List<Diary> diaries=diaryDao.getAllDiaries();
System.out.println(diaries);
}
public String getcurrentTime(){
SimpleDateFormat format= new SimpleDateFormat("yyyy年MM月dd日 hh:MM:ss");
return format.format(new Date());
}
//删除
public void testDelete(){
DiaryDao diaryDao=new DiaryDao(getContext());
diaryDao.deleteDiary(2);
}
//更新
public void testUpdate(){
DiaryDao diaryDao=new DiaryDao(getContext());
Diary diary=new Diary("我是米你", "迪斯尼乐园", getcurrentTime());
diary.setId(1);
diaryDao.updateDiary(diary);
}
//根据id查找数据测试
public void testFind(){
DiaryDao diaryDao=new DiaryDao(getContext());
Diary diary=diaryDao.find(1);
System.out.println(diary);
}
}
步骤6.将查询到的数据以列表的形式进行显示
所用控件ListView
(1)定义Items.xml的显示界面:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:id="@+id/title"
android:layout_width="200dip"
android:layout_height="wrap_content"
android:textSize="20sp" />
<TextView
android:id="@+id/create"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp" />
</LinearLayout>
(2)在main.xml定义ListView控件
<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"
android:background="@drawable/png5"
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=".MainActivity" >
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
<TextView
android:id="@id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nullcontent" />
</LinearLayout>
(3)把数据绑定到ListViewl列表中并对指定listView的items界面
package com.example.sqlist;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.sql.Dao.DiaryDao;
import org.sql.entity.Diary;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
public class MainActivity extends Activity {
private ListView listview;
DiaryDao diaryService ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//查询数据
diaryService = new DiaryDao(this);
List<Diary> diaries=diaryService.getAllDiaries();
//查找控件
listview=(ListView) findViewById(R.id.listview);
//提供适配器
List<Map<String,Object>> data=new ArrayList<Map<String,Object>>();
for(Diary diary:diaries){
Map<String,Object> map=new HashMap<String, Object>();
map.put("title", diary.getTitle());
map.put("content", diary.getContent());
map.put("create", diary.getCreatetime());
data.add(map);
}
SimpleAdapter adapter=new SimpleAdapter(this, data, R.layout.items, new String[]{"title","create"}, new int[]{R.id.title,R.id.create});
listview.setAdapter(adapter);
(4)增加点击列表的时间处理方法
//点击列表的事件处理
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
listview=(ListView)parent;
Map<String,Object> item=(Map<String, Object>) listview.getItemAtPosition(position);
String title=(String) item.get("title");
//String content=diaryService.find(position);
String create=(String) item.get("create");
//实现页面跳转
Intent intent=new Intent();
Bundle bundle=new Bundle();
bundle.putString("title", title);
bundle.putString("create", create);
intent.putExtras(bundle);
intent.setClass(MainActivity.this,ContentRActivity.class);
startActivity(intent);
// Toast.makeText(MainActivity.this,title+create, Toast.LENGTH_LONG).show();
}
} );
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
(5)跳转页面的接收代码
package com.example.sqlist;
import java.util.List;
import org.sql.Dao.DiaryDao;
import org.sql.entity.Diary;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class ContentRActivity extends Activity {
private TextView TITLE;
private TextView CONTENT;
private TextView CREATE;
private String title;
private String content;
private String create;
Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content_r);
TITLE = (TextView)findViewById(R.id.Atitle);
CONTENT = (TextView) findViewById(R.id.content);
CREATE = (TextView) findViewById(R.id.Acreate);
intent = getIntent();
Bundle bundle = intent.getExtras();
DiaryDao diaryService = new DiaryDao(this);
List<Diary> diaries=diaryService.getAllDiaries();
for(Diary diary:diaries){
if(bundle.get("title").equals(diary.getTitle()))
content= diary.getContent();
//Toast.makeText(this,content, Toast.LENGTH_LONG).show();
}
title = bundle.getString("title");
create = bundle.getString("create");
TITLE.setText("标题:"+title);
CONTENT.setText("内容:"+content);
CREATE.setText("创建时间"+create);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.content, menu);
return true;
}
}
(6)运行结果截图