Chinaunix首页 | 论坛 | 博客
  • 博客访问: 900119
  • 博文数量: 322
  • 博客积分: 6688
  • 博客等级: 准将
  • 技术积分: 3626
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-19 11:26
文章分类

全部博文(322)

文章存档

2013年(5)

2012年(66)

2011年(87)

2010年(164)

分类: Java

2010-12-31 13:59:07

数据库的

DBActivity

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package org.wp.db;  
 
/** 
 * 嵌入式关系型数据库 
 * SQLite 
 * SQLite最大的特点是你可以保存任何类型的数据到任何字段中,无论这列声明的数据类型是什么 
 * 但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数 
 * 当向这种字段中保存除整数以外的数据时,将会产生错误 
 * 另外, SQLite 在解析CREATE TABLE 语句时,会忽略 CREATE TABLE 语句中跟在字段名后面的数据类型信息 
 *  
 * SQLite可以解析大部分标准SQL语句,如: 
 * 查询语句:select * from 表名  where 条件子句  group by 分组字句  having ... order by 排序子句 
 * 分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录 
 * select * from Account limit 5 offset 3 或者  select * from Account limit 3,5 
 * 插入语句:insert into 表名(字段列表) values(值列表) 
 * 更新语句:update 表名 set 字段名 = 值  where 条件子句 
 * 删除语句:delete from 表名 where 条件子句 
 *  
 */  
 
import org.wp.service.DataBaseOpenHelper;  
import android.app.Activity;  
import android.database.sqlite.SQLiteDatabase;  
import android.os.Bundle;  
 
public class DBActivity extends Activity {  
 
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
 
        /** 
         * 第一次调用getWritableDatabase()或getReadableDatabase()方法后 
         * SQLiteOpenHelper会缓存当前的SQLiteDatabase实例 
         * SQLiteDatabase实例正常情况下会维持数据库的打开状态 
         * 所以在你不再需要SQLiteDatabase实例时 
         * 请及时调用close()方法释放资源 ,一旦SQLiteDatabase实例被缓存 
         * 多次调用getWritableDatabase()或getReadableDatabase()方法得到的都是同一实例 
         */  
 
        DataBaseOpenHelper dataBaseOpenHelper = new DataBaseOpenHelper(  
                DBActivity.this);  
        SQLiteDatabase database = dataBaseOpenHelper.getWritableDatabase();  
        database.execSQL("insert into person(name, age) values(?,?)",  
                new Object[] { "张三", 9 });  
        database.close();  
    }  
}

DataBaseOpenHelper

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package org.wp.service;  
 
/** 
 * 在Android系统,为我们提供了一个名为SQLiteOpenHelper的类 
 * 该类用于对数据库版本进行管理,该类是一个抽象类,必须继承它才能使用 
 * 为了实现对数据库版本进行管理,SQLiteOpenHelper类有两种重要的方法 
 * 分别是onCreate(SQLiteDatabase db) 和  onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)  
 *   
 * 当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法 
 * 获取用于操作数据库的SQLiteDatabase实例的时候 
 * 如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()方法 
 * onCreate()方法在初次生成数据库时才会被调用 
 * 在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据 
 * onUpgrade()方法在数据库的版本发生变化时会被调用,数据库的版本是由程序员控制的 
 * 假设数据库现在的版本是1,由于业务的需要,修改了数据库表的结构,这时候就需要升级软件 
 * 升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为2 
 * 并且在onUpgrade()方法里面实现表结构的更新 
 * 当软件的版本升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断 
 * 然后作出相应的表结构及数据更新 
 *  
 * getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例 
 * 但getWritableDatabase()方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写 
 * 倘若使用的是getWritableDatabase()方法就会出错 
 *  
 * getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败 
 * 当打开失败后会继续尝试以只读方式打开数据库 
 *  
 */  
 
import android.content.Context;  
import android.database.sqlite.SQLiteDatabase;  
import android.database.sqlite.SQLiteOpenHelper;  
 
public class DataBaseOpenHelper extends SQLiteOpenHelper {  
 
    // 类没有实例化,是不能用作父类构造器的参数,必须声明为静态  
    private static final String DBNAME = "wp";// 数据库名称  
    private static final int VERSION = 1;// 数据库版本  
 
    public DataBaseOpenHelper(Context context) {  
        // 第三个参数CursorFactory指定在执行查询时获得一个游标实例的工厂类,设置为null,代表使用系统默认的工厂类  
        super(context, DBNAME, null, VERSION);  
    }  
 
    @Override  
    public void onCreate(SQLiteDatabase db) {  
        db.execSQL("create table person(personid integer primary key autoincrement,name varchar(20),age integer)");  
    }  
 
    @Override  
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
        db.execSQL("drop table if exists person");  
        onCreate(db);  
    }  
 
}

PersonService

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package org.wp.service;  
 
/** 
 * Android 提供了一个名为SQLiteDatabase的类 
 * 该类封装了一些操作数据库的API,使用该类可以完成对数据CRUD操作 
 */  
 
import java.util.ArrayList;  
import java.util.List;  
import org.wp.domain.Person;  
import android.content.Context;  
import android.database.Cursor;  
import android.database.sqlite.SQLiteDatabase;  
 
public class PersonService {  
    private DataBaseOpenHelper dataBaseOpenHelper;  
    private SQLiteDatabase database;  
 
    public PersonService(Context context) {  
        dataBaseOpenHelper = new DataBaseOpenHelper(context);  
    }  
 
    public void save(Person person) {  
        database = dataBaseOpenHelper.getWritableDatabase();  
        database.execSQL("insert into person(name,age) values(?,?)",  
                new Object[] { person.getName(), person.getAge() });  
        // database.close();  
    }  
 
    /** 
     * Java1.5 增加了新特性 可变参数 适用于参数个数不确定,类型确定的情况,Java把可变参数当做数组处理。 
     *  
     * @param ids 
     */  
    public void delete(Integer... ids) {  
        if (ids.length > 0) {  
            StringBuilder sb = new StringBuilder();  
            for (Integer id : ids) {  
                sb.append('?').append(',');  
            }  
            sb.deleteCharAt(sb.length() - 1);  
            database = dataBaseOpenHelper.getWritableDatabase();  
            database.execSQL(  
                    "delete from person where personid in(" + sb + ")",  
                    (Object[]) ids);  
        }  
    }  
 
    public void update(Person person) {  
        database = dataBaseOpenHelper.getWritableDatabase();  
        database.execSQL("update person set name=?,age=? where personid=?",  
                new Object[] { person.getName(), person.getAge(),  
                        person.getPersonid() });  
    }  
 
    public Person find(Integer id) {  
        database = dataBaseOpenHelper.getReadableDatabase();  
        /** 
         * Cursor是结果集游标,用于对结果集进行随机访问 使用moveToNext()方法可以将游标从当前行移动到下一行 
         * 如果已经移过了结果集的最后一行,返回结果为false,否则为true  
         * 另外Cursor 还有常用的 
         * moveToPrevious()方法 
         * 用于将游标从当前行移动到上一行,如果已经移过了结果集的第一行,返回值为false,否则为true  
         * moveToFirst()方法 
         * 用于将游标移动到结果集的第一行,如果结果集为空,返回值为false,否则为true  
         * moveToLast()方法 
         * 用于将游标移动到结果集的最后一行,如果结果集为空,返回值为false,否则为true 
         */  
        Cursor cursor = database.rawQuery(  
                "select * from person where personid=?", new String[] { String  
                        .valueOf(id) });  
        if (cursor.moveToNext()) {  
            return new Person(cursor.getInt(0), cursor.getString(1), cursor  
                    .getShort(2));  
        }  
        return null;  
    }  
 
    /** 
     *  
     * SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset     
     * LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数 
     * LIMIT 接受一个或两个数字参数。参数必须是一个整数常量 
     * 如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目 
     * 初始记录行的偏移量是 0(而不是 1): 
     * SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15    
     * 为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1  
     * SELECT * FROM table LIMIT 95,-1;     // 检索记录行 96-last.    
     * 如果只给定一个参数,它表示返回最大的记录行数目:    
     * SELECT * FROM table LIMIT 5; //检索前 5 个记录行    
     * 换句话说,LIMIT n 等价于 LIMIT 0,n。 
     *  
     */  
    public List<Person> getScrollData(int startResult, int maxResult) {  
        List<Person> persons = new ArrayList<Person>();  
        database = dataBaseOpenHelper.getWritableDatabase();  
        Cursor cursor = database.rawQuery("select * from person limit ?,?",  
                new String[] { String.valueOf(startResult),  
                        String.valueOf(maxResult) });  
        while (cursor.moveToNext()) {  
            persons.add(new Person(cursor.getInt(0), cursor.getString(1),  
                    cursor.getShort(2)));  
        }  
        return persons;  
    }  
 
    public long getCount() {  
        database = dataBaseOpenHelper.getReadableDatabase();  
        Cursor cursor = database.rawQuery("select count(*) from person ", null);  
        while (cursor.moveToNext()) {  
            return cursor.getLong(0);  
        }  
        return 0;  
    }  
}

OtherPersonService

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package org.wp.service;  
 
/** 
 * Insert()方法用于添加数据,各个字段的数据使用ContentValues进行存放 
 * ContentValues类似于MAP,相对于MAP,它提供了存取数据对应的 
 * put(String key, Xxx value)和getAsXxx(String key)方法  
 * key为字段名称,value为字段值,Xxx指的是各种常用的数据类型 
 * 如:String、Integer等 
 * long rowid = db.insert("person", null, values);//返回新添记录的行号,与主键id无关 
 *  
 */  
 
import java.util.ArrayList;  
import java.util.List;  
import org.wp.domain.Person;  
import android.content.ContentValues;  
import android.content.Context;  
import android.database.Cursor;  
import android.database.sqlite.SQLiteDatabase;  
 
public class OtherPersonService {  
    private DataBaseOpenHelper dataBaseOpenHelper;  
    private SQLiteDatabase database;  
 
    public OtherPersonService(Context context) {  
        dataBaseOpenHelper = new DataBaseOpenHelper(context);  
    }  
 
    /** 
     *  
     * database.insert(table, nullColumnHack, values); 
     * 不管第三个参数是否包含数据,执行Insert()方法必然会添加一条记录  
     * 如果第三个参数为空,会添加一条除主键之外其他字段值为Null的记录 
     * Insert()方法内部实际上通过构造insert语句完成数据的添加 
     * Insert()方法的第二个参数用于指定空值字段的名称 
     * 如果第三个参数values为Null或者元素个数为0 
     * Insert()方法必然要添加一条除了主键之外其它字段为Null值的记录 
     * 为了满足这条insert语句的语法,insert语句必须给定一个字段名 如:insert into person(name) values(NULL)  
     * 倘若不给定字段名 ,insert语句就成了这样: insert into person() values() 
     * 显然这不满足标准SQL的语法。对于字段名,建议使用主键之外的字段 
     * 如果使用了INTEGER类型的主键字段,执行类似insert into person(personid) values(NULL)的insert语句后该主键字段值也不会为NULL 
     * 如果第三个参数values不为Null并且元素的个数大于0 ,可以把第二个参数设置为null 
     *  
     * @param person 
     */  
    public void save(Person person) {  
        database = dataBaseOpenHelper.getWritableDatabase();  
        ContentValues values = new ContentValues();  
        values.put("name", person.getName());  
        values.put("age", person.getAge());  
        // 必须添加记录,除了主键之外,其他字段的值都为NULL  
        database.insert("person", "name", values);  
        // 第二个参数,构造合法的sql语句  
        // insert into person(name) values(null);  
    }  
 
    public void update(Person person) {  
        database = dataBaseOpenHelper.getWritableDatabase();  
        ContentValues values = new ContentValues();  
        values.put("name", person.getName());  
        values.put("age", person.getAge());  
        database.update("person", values, "personid=?", new String[] { String  
                .valueOf(person.getPersonid()) });  
    }  
 
    public Person find(Integer id) {  
        database = dataBaseOpenHelper.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) {  
            String[] strIds = new String[ids.length];  
            StringBuilder sb = new StringBuilder();  
            for (int i = 0; i < ids.length; i++) {  
                sb.append('?').append(',');  
                strIds[i] = String.valueOf(ids[i]);  
            }  
            sb.deleteCharAt(sb.length() - 1);  
            database = dataBaseOpenHelper.getWritableDatabase();  
            database.delete("person", "personid in(" + sb + ")", strIds);  
        }  
    }  
 
    /** 
     *  
     * query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)方法各参数的含义  
     * table:表名。相当于select语句from关键字后面的部分。如果是多表联合查询,可以用逗号将两个表名分开 
     * columns:要查询出来的列名。相当于select语句select关键字后面的部分 
     * selection:查询条件子句,相当于select语句where关键字后面的部分,在条件子句允许使用占位符"?" 
     * selectionArgs:对应于selection语句中占位符的值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常 
     * groupBy:相当于select语句group by关键字后面的部分  
     * having:相当于select语句having关键字后面的部分 
     * orderBy:相当于select语句order by关键字后面的部分,如:personid desc, age asc; 
     * limit:指定偏移量和获取的记录数,相当于select语句limit关键字后面的部分。 
     *  
     */  
 
    public List<Person> getScrollData(int startResult, int maxResult) {  
        List<Person> persons = new ArrayList<Person>();  
        database = dataBaseOpenHelper.getWritableDatabase();  
        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() {  
        database = dataBaseOpenHelper.getReadableDatabase();  
        Cursor cursor = database.query("person", new String[] { "count(*)" },  
                null, null, null, null, null);  
        while (cursor.moveToNext()) {  
            return cursor.getLong(0);  
        }  
        return 0;  
    }  
}

PersonServiceTest

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package org.wp.db;  
 
import java.util.List;  
import org.wp.domain.Person;  
import org.wp.service.OtherPersonService;  
import org.wp.service.PersonService;  
import android.test.AndroidTestCase;  
import android.util.Log;  
 
public class PersonServiceTest extends AndroidTestCase {  
    private static final String TAG = "PersonServiceTest";  
 
    public void testSave() throws Exception {  
        // PersonService personService = new PersonService(this.getContext());  
        OtherPersonService personService = new OtherPersonService(this  
                .getContext());  
        personService.save(new Person("某某某", (short) 23));  
    }  
 
    public void testFind() throws Exception {  
        // PersonService personService = new PersonService(this.getContext());  
        OtherPersonService personService = new OtherPersonService(this  
                .getContext());  
        Person person = personService.find(1);  
        Log.i(TAG, person.toString());  
    }  
 
    public void testUpdate() throws Exception {  
        // PersonService personService = new PersonService(this.getContext());  
        OtherPersonService personService = new OtherPersonService(this  
                .getContext());  
        Person person = personService.find(1);  
        person.setName("张三");  
        person.setAge((short) 11);  
        personService.update(person);  
        person = personService.find(1);  
        Log.i(TAG, person.toString());  
    }  
 
    public void testGetCount() throws Exception {  
        // PersonService personService = new PersonService(this.getContext());  
        OtherPersonService personService = new OtherPersonService(this  
                .getContext());  
        Log.i(TAG, String.valueOf(personService.getCount()));  
    }  
 
    public void testGetScrollData() throws Exception {  
        // PersonService personService = new PersonService(this.getContext());  
        OtherPersonService personService = new OtherPersonService(this  
                .getContext());  
        // for (int i = 0; i < 10; i++) {  
        // personService.save(new Person("某某某" + i, (short) (i + 1)));  
        // }  
        List<Person> persons = personService.getScrollData(0, 30);  
        for (Person person : persons) {  
            Log.i(TAG, person.toString());  
        }  
    }  
 
    public void testDelete() throws Exception {  
        PersonService personService = new PersonService(this.getContext());  
        personService.delete(1, 2, 3);  
    }  
 
}

Person

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package org.wp.domain;  
 
public class Person {  
 
    private Integer personid;  
    private String name;  
    private Short age;  
 
    public Person(Integer personid, String name, Short age) {  
        this.personid = personid;  
        this.name = name;  
        this.age = age;  
    }  
 
    public Person(String name, Short age) {  
        this.name = name;  
        this.age = age;  
    }  
 
    public Integer getPersonid() {  
        return personid;  
    }  
 
    public void setPersonid(Integer personid) {  
        this.personid = personid;  
    }  
 
    public String getName() {  
        return name;  
    }  
 
    public void setName(String name) {  
        this.name = name;  
    }  
 
    public Short getAge() {  
        return age;  
    }  
 
    public void setAge(Short age) {  
        this.age = age;  
    }  
 
    @Override  
    public String toString() {  
        return "personid=" + personid + ",name=" + name + ",age=" + age;  
    }  
 
}

main.xml

Xml代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package org.wp.domain;  
 
public class Person {  
 
    private Integer personid;  
    private String name;  
    private Short age;  
 
    public Person(Integer personid, String name, Short age) {  
        this.personid = personid;  
        this.name = name;  
        this.age = age;  
    }  
 
    public Person(String name, Short age) {  
        this.name = name;  
        this.age = age;  
    }  
 
    public Integer getPersonid() {  
        return personid;  
    }  
 
    public void setPersonid(Integer personid) {  
        this.personid = personid;  
    }  
 
    public String getName() {  
        return name;  
    }  
 
    public void setName(String name) {  
        this.name = name;  
    }  
 
    public Short getAge() {  
        return age;  
    }  
 
    public void setAge(Short age) {  
        this.age = age;  
    }  
 
    @Override  
    public String toString() {  
        return "personid=" + personid + ",name=" + name + ",age=" + age;  
    }  
 
}

strings.xml

Xml代码

1
2
3
4
5
6
 version="1.0" encoding="utf-8"?>  
>  
     name="hello">Hello World, DBActivity!>  
     name="app_name">数据库应用>  
     name="button">操作数据库>  
>

AndroidManifest.xml

Xml代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 version="1.0" encoding="utf-8"?>  
 xmlns:android=""  
    package="org.wp.db" android:versionCode="1" android:versionName="1.0">  
     android:icon="@drawable/icon" android:label="@string/app_name">  
         android:name="android.test.runner" />  
         android:name=".DBActivity" android:label="@string/app_name">  
            >  
                 android:name="android.intent.action.MAIN" />  
                 android:name="android.intent.category.LAUNCHER" />  
            >  
        >  
    >  
     android:minSdkVersion="7" />  
     android:name="android.test.InstrumentationTestRunner"  
        android:targetPackage="org.wp.db" android:label="Tests for My App" />  
>

原文作者:onewayonelife

阅读(720) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~