一、sqlite数据库
1.什么是数据库?
存储大量的相似结构的数据。本质上是一个高效率的文件管理系统。提供快速的增删改查和多并发操作。
常用的数据库有:MysqL,oracle,db2,sqlserver.
2.sqlLite数据库
android原生的数据库,轻量级(体积小,可移植性高,,功能完善,支持事务控制,被大量的嵌入到其它系统中作为数据库。),关系型数据库。
3.sqlite数据库的创建
(1)写一个类继承sqliterOpenHelper,实现未实现的方法
public class MysqLiterOpenHelper extents sqliterOpenHelper{
//参数说明:
/*
public MysqLiterOpenHelper(Content,name,factory,version)
Context:表示当前环境对象,里面有我们需要用到的常量和方法。有很多抽象方法,只定义具体功能,不实现。
name:数据库的名称,若为空则在内存中创建数据库。应用退出即销毁
factory:数据操作的游标,游标工厂,若为null则为默认工厂。
version:数据库的版本,从1开始。版本号必须是正整数且增加的。
*/
public MysqLiterOpenHelper(Content context){
super(content,"mydb.db",null,1);
}
//此方法会在第一次创建数据库时使用,可以用来初始化数据库表和表中的数据。
pubic void onCreate(sqllitDatabase db){
}
//此方法会在数据库更新时调用,用来更新已有的数据库。通常版本更新时会触发该操作。
public void onUpdate(sqlliterDatabase database,int oldVersion,int newVersion){
//根据版本不同执行不同的操作,注意没有break,即用户若从版本1开始更新则接下来版本中的更新命令也需要执行。巧妙的利用了switch的特性,很棒!
switch(oldVersion){
case 1:
db.execute...
case 2:
db.execute...
case 3:
db.execute...
default:
...
}
}
}
(2)创建继承类的对象。
//下面的语句不会创建数据库,只有操作的时候才会创建。
sqliterOpenHelper helper=new MysqLiterOpenHelper(this); //
//执行如下操作中某一条可以创建数据库,下面的方法其实拿到的是同一对象,若为getWritableDatabase则返回的数据加锁,若为getReadableDatabase则返回的数据库没有锁机制,可根据需要调用不同的方法。
sqliterDatabase database=helper.getWritableDatabase()
sqliterDatabase database=helper.getReadableDatabase()
sqliter数据的底层其实是在/data/data/[应用包名]/databases/xxx.xx文件中保存的数据。
三、数据库的CRUD
sqliter支持数据类型,但在底层的实现中是不区分数据类型也不检查数据长度,底层无论什么数据,都是用字符串来存储。虽然sqliter不检查数据类型,但在写sql时最好声明清楚数据类型,sql除了给应用程序看,还可以给人看,方便维护者知道数据类型和大小限制。
增删改用:
db.execsql();
若执行时需要用到多个参数则使用new Object[]{}进行参数数组的初始化。
查询用:
db.rawQuery();
若执行时需要用到多个参数则使用new String[]{}进行参数数组的初始化。
a.游标用完要关闭。
b.数据库连接后关闭,但在频繁的操作时也可以不关闭,在应用退出时关闭数据库。
(1)数据操作程序设计
public class UsersDao(){
private MysqLiterOpenHelper helper=null;
public UsersDao(Context content){
helper=new MysqLiterOpenHelper(context)
}
public static void add(User user){
sqliterDatabase db=helper.getWritableDatabase();
db.execsql("insert into users(name,phone) values(?,?)",new Object[]]{user.getName(),user,getPhone()});
db.close();
}
public static void del(String name){
sqliterDatabase db=helper.getWritableDatabase();
db.execsql("delete from users where name=?",new Object[]]{name});
db.close();
}
//从数据库中更新数据
public static void update(User user){
sqliterDatabase db=helper.getWritableDatabase();
db.execsql("update users set name =?,phone=?",user.getPhone()});
db.close();
}
public static User find(String name){
sqliterDatabase db=helper.getWritableDatabase();
//查询后返回的是游标。
Cursor cursor=db.rawQuery("select * from users where name =?",new String[]{name});
try{
if(cursor.moveToNext()){
User user=new User();
user.setName(crusor.getString(cursor.getColumnIndex("name")));
user.setPhone(cursor.getString(cursor.getColumnIndex("setPhone")));
return user;
}else{
return null;
}
}
finnaly{
cursor.close();
db.close();
}
}
}
(2)数据库的查看(两种方式)
a.使用工具sqlite Explorer 先导出文件,再导入到工具中查看
b.在命令行窗口使用sqlite3命令
adb shell
cd /data/data/[应用包名]/databases
sqlite3 xxx.db
sqlite3 xxx.db
(3)android数据库操作的两种方式:
a.android提供原生的sql语句进行增删改查
b.提供了android快捷方式的对数据库操作的增删改查。
insert
db.insert(tableName,nullColumnHack(如果不给值的话默认取的值,null),ContentValues);
ContentValues values=new ContentValues(); //ContentValues本质是hashMap
values.put("name",user.getName());
values.put("phone",user.getPhone());
db.insert("users",values);
update
ContentValues value=new ContentValues();
values.put("phone",user.getPhone());
db.update("users",value,"name=?",new String[]{user.getName()});
delete
db.delete("users",new String[]{name});
query
Cursor cursor=db.query("users",new String[]{name},null);
(4)两种方式的优缺点。
自己写sql:
优点:sal可以写的非常灵活,可以执行复杂的多表查询,子查询...
缺点:sql需要自己写,不是面向对象的,容易出错。
没有返回影响到的行数,需要自己想办法查询。
优点:sql不易写错,返回值有影响到行数。
缺点:执行较复杂的SQL查询比较麻烦。
(5)数据乱码
sqlite中用的是utf-8,cmd用的是gbk
在cmd窗口下:
chcp 65001; 修改当前代码页为65001,即utf-9 Change code page
如果还不行,则修改当前cmd窗口页面的字体为Lucia Console
(6)数据库的事务处理
开启事务:
db.setTransaction();
提交上事务:
db.setTranactionSucessful();
结束事务:
db.endTransaction();在结束事务之前,如果设置过事务成功,则事务提交,如果没设置过则事务回滚。
案例:银行转行案例。
public class MysqLiterOpenHelper extents sqlliteOpenHelper{
}
在数据库的操作中开启事务:
db.beginTransation();
try{
sql语句
db.setTranactionSucessful();
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException();
}finally{
//当结束事务时,如果检测没有执行db.setTransactionSucessful(),则将该语句将自动回滚事务。
db.endTransaction();
}
四、查询所有数据
(1)添加数据
UserDao dao=new UserDao();
TextView tv_content=null;
tv_content=findViewById(R.id.tv_content);
public void add(View view){
for(int x=0;x<10;x++){
dao.add(new User(x,"cs001"+x,"110"+x);
}
Toast.makeText(this,"ok",0).show();
}
(2)查询并封装数据
public List<User> findAll(){
sqliterDatabase db=helper.getWritableDatabase();
Cursor cursor=db.rawQuery("select * from users");
List<User> list=new ArrayList<User>();
while(cursor.moveToNext()){
User user=new User();
user.setName(cursor.getString(cursor.getColumnIndex("name")));
user.setPhone(cursor.getString(cursor.getColumnIndex("phone")));
list.add(user);
}
db.close();
return list;
}
public void findAll(View view){
List<User> list=dao.findAll();
StringBuffer buffer=new StringBuffer();
Toas.makeText(this,"共"+list.size()+"记录",0);
for(User user:list){
buffer.append(user.toString()+"\r\n");
}
String content=buffer.toString();
tv_content.setText(content);
}
由于内容过多,在TextView组件上设置滚动。
<ScrollView>
<TextView>
</TextView>
</ScrollView>
五、强大的ListView
该显示方式会动态显示当前页面中的内容,比如显示10条,只需用当前10条的内存,当滑动到下一条时则创建下一条的内存,移除当前页面的那条内容占据的内存讲被销毁。此方式的缺点:当虚拟机来不及创建新的内容时将导致应用异常退出。
ListView lv=null;
lv=findViewById(R.id.lv);
String[] arrs={"boy","girl","person"};
int count=Integer.MAX_VALUE;
lv.setAdapter(new BaseAdapter(){
public int getCount(){
return count
}
public View getView(){
TextView tv=new TextView(MainActivity.this);
int p=position%3;
tv.setText(arrs[p]);
return tv;
}
});
2.ListView显示
方式一:使用BaseAdapter
(1)布局文件:
在主布局文件中添加ListView组件。在自定义布局文件item.xml中添加需要在ListView中显示的类似TextView等组件。
(2)创建类MyAdapter继承BaseAdapter并重写BaseAdapter中的方法:
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@Override
public View getView(int position,View convertView,ViewGroup parent) {
View view=null;
if(convertView!=null){
view=convertView;
}else {
view=View.inflate(MainActivity.this,R.layout.item,null);
}
TextView tView=(TextView) view.findViewById(R.id.tv_showone);
ImageView iView=(ImageView) view.findViewById(R.id.iv_showone);
int p=position%3;
switch (p) {
case 0:
iView.setImageResource(R.drawable.apple);
tView.setText("中文");
break;
case 1:
iView.setImageResource(R.drawable.banana);
tView.setText("香蕉你个巴拉");
break;
case 2:
iView.setImageResource(R.drawable.watermelon);
tView.setText("英文");
break;
default:
break;
}
return view;
}
(3)调用继承的类对象
ListView lv_showOne=(ListView) findViewById(R.id.lv_showone);
ListView lv_showtow=(ListView) findViewById(R.id.lv_showtwo);
ListView lv_showthree=(ListView) findViewById(R.id.lv_showthree);
lv_showOne.setAdapter(new MyAdapter());
lv_showtow.setAdapter(new MyAdapter());
lv_showthree.setAdapter(new MyAdapter());
方式二:使用SimpleAdapter
使用SimpleAdapter可以更方便的实现类似上述的操作:
public void showAll(View view){
List<Map<String,String>> params = new ArrayList<Map<String,String>>();
for (int x = 0; x < 1000; x++) {
Map<String,String> map=new HashMap<String,String>();
map.put("name","sai001"+x);
map.put("addr","bj00"+x);
params.add(map);
}
for (int y = 0; y < params.size(); y++) {
SimpleAdapter adapter=new SimpleAdapter(this,params,new String[]{"name","addr"},new int[]{R.id.tv_showone,R.id.tv_showones});
lv_showOne.setAdapter(adapter);
}
}
关于SimpleAdapter:
android.widget.SimpleAdapter.SimpleAdapter(Context context,List<? extends Map<String,?>> data,int resource,String[] from,int[] to)
Parameters:
[context] The context where the View associated with this SimpleAdapter is running
[data] A List of Maps. Each entry in the List corresponds to one row in the list. The Maps contain the data for each row,and should include all the entries specified in "from"
[resource] Resource identifier of a view layout that defines the views for this list item. The layout file should include at least those named views defined in "to"
[from] A list of column names that will be added to the Map associated with each item.
[to] The views that should display column in the "from" parameter. These should all be TextViews. The first N views in this list are given the values of the first N columns in the from parameter.
原文链接:/sqlite/200140.html