安卓基础笔记2之SQLit数据库
来源:互联网 发布:服装软件有哪些 编辑:程序博客网 时间:2024/06/03 11:17
知识点
SQLit数据库(安卓自带的)
- 常见数据库
- 创建一个工具类
- 纯sql方式操作数据库
- 添加
- 删除
- 更新
- 查询
- 面向对象的方式操作数据库
- 添加
- 删除
- 更新
- 查询
ListView(安卓核心控件)
- ListView(理解)
- ListView入门
- ListView优化
- 复杂的ListView
具体细节以及案例
- ##### 常见数据库
- Oracle:大型的数据库 ,性能最高
- Mysql:小型数据库 开源的 免费的
- DB2:大型数据库,收费
- Sqlite:微型,免费,美国军舰(Android自带)
- ###### 创建一个工具类继承SQLiteOpenHelper
要明白的:
-构造方法里传的三个参数分别是什么意思 作用是什么?
- 参数1:Context 上下文环境
- 参数2:name 数据库文件的名称(xxx.db)
- 参数3:factory 游标工厂,传入null使用系统默认的游标(可以理解为指向数据库中数据的指针)
参数4:version 数据库版本,==必须大于1==
- 作用:给创建的子类对象设置好数据库名字以及版本号
明白OnCreate()方法什么时候使用,使用的特点是什么
- ==当第一次创建数据库的时候调用==
- 特点: 由系统调用,且只会调用一次
思路:
- 在==onCrate方法==里创建表
- 创建表的SQL语句:
- ==create table 数据表名(_id integer primary key,列名2 数据类型 约束,列名3 数据类型 约束);==
- SQLite的主键会自动自增,不需要加auto_increment
- 在==onUpgrade==方法内升级数据库
- 修改表
- ==alter table t_user add c_money float==
代码
@Override public void onCreate(SQLiteDatabase db) {// 创建表结构 String sql = "create table t_user (_id integer primary key,t_name varchar(20),t_age integer ,t_gender varchar(20))"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { String sql = "alter table t_user add c_money float"; db.execSQL(sql); }
- ###### 使用SQLiteOpenHelper创建数据库文件
思路
- 先写UI,创建一个按钮,点击按钮触发创建数据库事件
创建工具类的对象(有参数的构造)
- MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this, DB_NAME, null, VERSION);
通过.getReadableDatabase()或.getWriteableDatabase()来获取数据库
- SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();
- 调用.close() 释放资源
// 创建数据库 public void create(View view) { // 创建工具类的对象 MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this, DB_NAME, null, VERSION); // 通过.getReadableDatabase()来获取数据库 SQLiteDatabase database = mySQLiteOpenHelper.getReadableDatabase(); // 释放资源 database.close(); Toast.makeText(this, "创建数据库成功", Toast.LENGTH_SHORT).show(); }
- #### 纯sql方式操作数据库
思路
添加,删除,更新都是调用execSQL(sql,Object[]{})方法,只是sql语句不一样
先写UI,创建一个按钮,点击按钮触发添加数据事件
获取操作的数据库
- ==MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this, DB_NAME, null, VERSION);==
- ==SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();==
- 用一个字符串接收添加数据的sql语句,一般会使用占位符的格式
- 调用的是 ==execSQL(sql,Object[]{})== 方法
- 释放资源
- 查询
- 先写UI,创建一个按钮,点击按钮触发添加数据事件
- 获取操作的数据库(跟添加,删除,更新一样)
- 用一个字符串接收添加数据的sql语句,一般会使用占位符的格式
- 调用 ==rewQuery(sql,String[]{})== 方法,返回值是Cursor 结果集
- 判断结果集里是否存在下一个符合条件数据,调用 ==moveToNext()== 方法,用while循环来遍历出要查询的数据
- 如果存在,通过字段索引,获取字段的内容,调用 ==getXxx()== 方法获取,索引从0开始
- ==注意:通过索引获取时,是根据你查询的结果为准==
- 释放资源
// 添加数据 public void insert(View view) { // 获取操作的数据库 MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this, DB_NAME, null, VERSION); SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase(); // 用一个字符串接收添加数据的sql语句,一般会使用占位符的格式 String sql = "insert into t_user (t_name,t_age,t_gender) values(?,?,?)"; database.execSQL(sql, new Object[] { "王莉莉" + new Random().nextInt(100), new Random().nextInt(108), "" + new Random().nextInt(2) }); // 释放资源 database.close(); Toast.makeText(this, "1成功", Toast.LENGTH_SHORT).show(); } // 删除数据 public void delete(View view) { // 获取操作的数据库 MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this, DB_NAME, null, VERSION); SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase(); // 用一个字符串接收添加数据的sql语句,一般会使用占位符的格式 String sql = "delete t_user where t_age>?"; database.execSQL(sql, new Object[] { "60" }); // 释放资源 database.close(); Toast.makeText(this, "2成功", Toast.LENGTH_SHORT).show(); } // 更新数据 public void update(View view) { // 获取操作的数据库 MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this, DB_NAME, null, VERSION); SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase(); // 用一个字符串接收添加数据的sql语句,一般会使用占位符的格式 String sql = "update t_user set t_name=? where t_age<?"; database.execSQL(sql, new Object[] { "王丽丽", 20 }); // 释放资源 database.close(); Toast.makeText(this, "3成功", Toast.LENGTH_SHORT).show(); } // 查询数据 public void select(View view) { // 获取操作的数据库 MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this, DB_NAME, null, VERSION); SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase(); // 用一个字符串接收添加数据的sql语句,一般会使用占位符的格式 String sql = "select * from t_user where t_age>?"; // 调用 rawQuery() 方法进行查询,第二个参数是string数组,返回的是一个Cursor 结果集 Cursor cursor = database.rawQuery(sql, new String[] { "50" }); // 判断结果集里是否存在下一个符合条件数据,调用moveToNext()方法,用while循环来遍历出要查询的数据 List<User> list = new ArrayList<User>(); while (cursor.moveToNext()) { // 如果存在,通过字段索引,获取字段的内容,调用getXxx()方法获取,索引从0开始 // 注意:通过索引获取时,是根据你查询的结果为准 String name = cursor.getString(0); int age = cursor.getInt(1); String gender = cursor.getString(2); User user = new User(); user.name = name; user.age = age; user.gender = gender; list.add(user); } Log.w("tag", list.toString()); textView.setText(list.toString()); // 释放资源 database.close(); Toast.makeText(this, "5成功", Toast.LENGTH_SHORT).show(); }
- #### 面向对象的方式操作数据库
- 思路:
- 添加数据
- 先写UI,创建一个按钮,点击按钮触发添加数据事件
- 获取操作的数据库
- 调用 ==insert()== 方法
- 参数1:表名
- 参数2:一般是null
- 参数3是一个ContenValues对象,这个类封装的是一个Map数组
- 调用put(key,values)方法,添加数据
- 返回值是插入的行数,==long== 类型的,如果插入为0,返回-1
-
- 添加数据
// 添加数据 public void insert(View v) { // 获取工具类的对象 MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this, DB_USER, null, VERSION); // 通过.getReadableDatabase()创建数据库 SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase(); // 调用insert方法,参数3是一个ContenValues对象,这个类封装的是一个Map数组 // insert 返回值是插入的行数,long类型的 ContentValues values = new ContentValues(); values.put("t_name", "王丽丽" + new Random().nextInt(20)); values.put("t_age", 20 + new Random().nextInt(10)); values.put("t_gender", "" + new Random().nextInt(2)); long len = database.insert("s_user", null, values); database.close(); Toast.makeText(this, "在" + len + "插入了数据", Toast.LENGTH_SHORT).show(); }
- 删除数据
- 先写UI,创建一个按钮,点击按钮触发添加数据事件
- 获取操作的数据库
- 调用 ==delete()== 方法
- 参数1:表名
- 参数2放的是where条件
- 参数3是参数2里面?的真实值
- 返回值是受影响的行数,返回类型 ==int==
- 释放资源 -
// 获取工具类的对象 MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this, DB_USER, null, VERSION); // 通过.getReadableDatabase()创建数据库 SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase(); // 调用delete()方法,参数2放的是where条件,参数3是参数2里面?的真实值,返回值是受影响的行数,返回类型int int len = database.delete("s_user", "t_age>?", new String[] { "20" }); database.close(); Toast.makeText(this, len + "受影响", Toast.LENGTH_SHORT).show(); }
- 更新数据
- 先写UI,创建一个按钮,点击按钮触发添加数据事件
- 获取操作的数据库
- 调用 ==update()== 方法
- 参数1:表名
- 参数2是一个ContenValues对象,这个类封装的是一个Map数组
- 调用put(key,values)方法,添加数据
- 参数3放的是where条件
- 参数4是参数3里面?的真实值
- 返回值是受影响的行数,返回类型 ==int==
- 释放资源
-
// 更新 public void update(View view) { // 获取工具类的对象 MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this, DB_USER, null, VERSION); // 通过.getReadableDatabase()创建数据库 SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase(); // 调用update()方法,参数2是一个ContenValues对象,这个类封装的是一个Map数组,参数3放的是where条件,参数4是参数2里面?的真实值,返回值是受影响的行数,返回类型int ContentValues values = new ContentValues(); values.put("t_money", "1000"); int len = database.update("s_user", values, "t_age>?", new String[] { "19" }); database.close(); Toast.makeText(this, len + "受影响", Toast.LENGTH_SHORT).show(); }
- 查询数据
- 先写UI,创建一个按钮,点击按钮触发添加数据事件
- 获取操作的数据库
- 调用 ==query()== 方法
- 参数1:表名
- 参数2:要查询的字段,放到字符串数组中
- 参数3放的是where条件
- 参数4是参数3里面?的真实值
- 参数5:null
- 参数6:null
- 参数7:排序表达式
- 返回值返回值是 Cursor 结果集
- 判断结果集里是否存在下一个符合条件数据,调用 ==moveToNext()== 方法,用while循环来遍历出要查询的数据
- 如果存在,通过字段索引,获取字段的内容,调用 ==getXxx()== 方法获取,索引从0开始
- ==注意:通过索引获取时,是根据你查询的结果为准==
- 释放资源 -
public void select(View view) { // 获取工具类的对象 MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this, DB_USER, null, VERSION); // 通过.getReadableDatabase()创建数据库 SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase(); // 调用了query()方法 参数2:要查询的字段,放到字符串数组中 // 参数3:就是where表达式 // 参数4:用于替换参数3中?号的真实的值,String[]数组中形式 // 参数5:null // 参数6:null // 参数7:排序表达式 // 返回类型是一个Cursor对象,结果集 Cursor cursor = database.query("s_user", new String[] { "*" }, "t_age>?", new String[] { "20" }, null, null, "t_age"); List<User> list = new ArrayList<User>(); while (cursor.moveToNext()) { String name = cursor.getString(1); int age = cursor.getInt(2); String gender = cursor.getString(3); User user = new User(); user.name = name; user.age = age; user.gender = gender; list.add(user); } database.close(); Toast.makeText(this, list.toString(), Toast.LENGTH_SHORT).show(); }
- ##### 数据库升级
- 思路:
- 更新数据库:
- ==注意,只能升版本,不能降版本==
- 先写UI,创建一个按钮,点击按钮触发添加数据事件
- 获取操作的数据库
- 设置版本号,必须大于上一个版本号
- 释放资源
- 更新数据库:
// 更新数据库 public void shengji(View view) { // 更新数据库:注意,只能升版本,不能降版本 // 获取工具类的对象 MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this, DB_USER, null, VERSION); // 通过.getReadableDatabase()创建数据库 SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase(); database.close(); Toast.makeText(this, "升级成功", Toast.LENGTH_SHORT).show(); }
- ###### 数据库事物(模拟转账)
- 对事物的理解:
- 同时执行的多个数据库操作,要么同时成功,要么同时失败,不能出现一个成功一个失败的情况,==事物就是为了确保安全性的==
- 思路:
- 先写UI,创建一个按钮,点击按钮触发添加数据事件
- 获取操作的数据库
- 开启事物,调用了 ==beginTransaction()== ;方法
- 提交事物, ==setTransactionSuccessful()==
- 关闭事务, ==endTransaction()==
- 释放资源
// 开启事物 public void change(View view) { // 获取工具类的对象 MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this, DB_USER, null, VERSION); // 通过.getReadableDatabase()创建数据库 SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase(); // 更新表中数据,进行模拟转账操作! // 开启事物,之后的代码都是在临时内存中执行的,并未真正的写入到数据库文件中 database.beginTransaction(); String sql = "update s_user set t_money = t_money-500 where t_name=?"; database.execSQL(sql, new Object[] { "jjjj" }); String sql2 = "update s_user set t_money = t_money+500 where t_name=?"; database.execSQL(sql2, new Object[] { "王丽丽" }); // 提交事物,事物只有提交了才会写到数据库中 database.setTransactionSuccessful(); // 使用完后关闭事务功能 database.endTransaction(); database.close(); Toast.makeText(this, "转账成功", Toast.LENGTH_SHORT).show(); }
- ###### ListView(理解)
- 对ListView的理解:
- ListView是一个可以放很多条目的控件,可以滑动,可以显示一个数据集,如果数据超出屏幕可以上下滑动
- ==注意,ListView的宽高必须设置为match_parent,不能使用wrap_content。只有加了id才能在布局中看到示例页面==
- 使用ListView一般都会使用适配器Adapter,在适配器一般会用Adapter的子类BaseAdapter
- ==getCount()==:ListView一共有多少个条目
- ==getView()==:设置每一个条目数据,==最后一定要返回对象==
- ==注意:界面上显示多少个条目该方法就调用多少次,之后滚出来一个条目就调用一次==。
- ==public View getView(int position, View convertView, ViewGroup parent)==
- 有三个参数
- 参数一:int position,放的是索引,跟集合的索引是一样的
- 参数二:View convertView 一个可以复用的view控件
- 参数三:一般是null
- getItem():返回每个条目的对象
- getItemId():返回当前条目位置。
- 对ListView的理解:
- 如果是操作是一个TextView,可以用 ==ArrayAdapter== ,这个类底层就已经实现好了,只需要用就行
- ###### ListView入门
思路:
- 在main xml中创建一个ListViewko 控件
- 在MainActivity写业务逻辑
- 创建一个成员集合,来存放数据
- 初始化ListView
- 设置快速滑动 调用 .setsetFastScrollEnabled(true);
- 设置适配器调用setAdapter()
- 参数传的一个Adapter一个子类BaseAdapter对象,
- 创建一个类去继承BaseAdapter,重写BaseAdapter的方法
- 在getCount()方法里获取总共的条目
- 在getView里创建一个textView(可以直接new一个)
- 定义一个字符串根据索引获取集合里的内容
- 调用 .setText()给TextView赋值
ListView优化
- 为了防止内存溢出
- 在getView()方法里复用convertView
view view=null; if(convertView==null){ view = View.inflate(MainActivity.this, R.layout.listview_my, null);//创建view时,调用inflate()方法,获取id时是获取view存在的xml中的xml名字:R.layout.listview_my }else { view = convertView; }
- ###### 复杂的ListView
- 思路:
- 先在main xml 创建一个ListView 控件
- 自己定义一个 xml 放的是存在ListView里面的布局
- 在MainActivity里面写业务逻辑
- 创建一个成员集合,来存放数据
- 初始化ListView
- 设置快速滑动 调用 ==.setsetFastScrollEnabled(true);==
- 设置适配器调用==setAdapter()==
- 参数传的一个Adapter一个子类BaseAdapter对象,
- 创建一个类去继承==BaseAdapter==,重写BaseAdapter的方法
- 在 ==getCount()== 方法里获取总共的条目
- 要用ListView优化->>>(上一个优化代码)
- 在getView里创建一个View
- 获取view资源
``` ImageView imageView = (ImageView) view.findViewById(R.id.image); TextView name = (TextView) view.findViewById(R.id.name); TextView ageTextView = (TextView) view.findViewById(R.id.age); TextView genderTextView = (TextView) view.findViewById(R.id.gender); ``` - **注意:获取View资源一定要调用==View的findViewById==(R.id.image)** - 调用 ==.setText()== 给TextView赋值 ``` name.setText(user.name); ageTextView.setText(user.age+""); genderTextView.setText(user.gender); ``` - 给条目添加图片
- 具体代码
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化listview listView = (ListView) findViewById(R.id.contects); for (int i = 0; i < 100; i++) { User user = new User(); user.name = "khk"+i; user.age = i; user.gender = "女"+i; alist.add(user); }// 设置滑动加速器 listView.setFastScrollEnabled(true);// 添加适配器 listView.setAdapter(new BaseAdapter() { @Override public View getView(int position, View convertView, ViewGroup parent) {// 获取view对象 View view =null; if (convertView==null) { view = View.inflate(MainActivity.this, R.layout.listview_my, null); }else { view = convertView; }// 根据索引获取数据 User user = alist.get(position);// 获取view资源 ImageView imageView = (ImageView) view.findViewById(R.id.image); TextView name = (TextView) view.findViewById(R.id.name); TextView ageTextView = (TextView) view.findViewById(R.id.age); TextView genderTextView = (TextView) view.findViewById(R.id.gender); name.setText(user.name); ageTextView.setText(user.age+""); genderTextView.setText(user.gender);// 给条目添加图片 switch (position%10) { case 0: imageView.setImageResource(R.drawable.iv0); break; case 1: imageView.setImageResource(R.drawable.iv1); break; case 2: imageView.setImageResource(R.drawable.iv2); break; case 3: imageView.setImageResource(R.drawable.iv3); break; case 4: imageView.setImageResource(R.drawable.iv4); break; case 5: imageView.setImageResource(R.drawable.iv5); break; case 6: imageView.setImageResource(R.drawable.iv6); break; case 7: imageView.setImageResource(R.drawable.iv7); break; case 8: imageView.setImageResource(R.drawable.iv8); break; case 9: imageView.setImageResource(R.drawable.iv9); break; default: break; } return view; } @Override public int getCount() {// 获取条目的个数 return alist.size(); } @Override public long getItemId(int position) { return 0; } @Override public Object getItem(int position) { return null; } }); }
- 计时器:
步骤:
- 在LinearLayout定义一个button和一个ListView控件
- 先分配button的空间,把ListView的高度设置match…
- 也可以设置权重
- 获取ListView和button
点击按钮获取当前时间
调用SimpleDataFormat里面format()方法
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String timeString = format.format(new Date());timeList.add(timeString);
定义一个集合接收时间字符串
- Adapter里有一个方法:notifyDataSetChange() ==让arraylistview(ListView)更新一下数据,重新调用Adapter的getCount和getview();==
- //list集合有一个add(adaption,String)让添加的数据加载第一条list.add(0,要添加的数据);
- 让ListView滚动到最后一个条目
- 方法一.
- 平滑 调用 ==smoothScrollToPosition(一般是放的最后一个条目的索引)== 方法
- 方法二.
- 不平滑 让ListView定位定位到哪个条目 调用 ==setSelection()==;
- 方法一.
- 在LinearLayout定义一个button和一个ListView控件
感受和问题
今天主要学了SQLite 和ListView控件 数据库存储数据的两种方式,出现了大量的新方法,虽然操作数据时很多都是相似的,但是大部分都是需要记得东西,感觉一下子接受这些东西有些吃力,可能手速还是跟不上,练习的时间总感觉不够用.
在练习的时候总会因为一些粗心犯了一些很低级的错误,在使用这些方法时容易记混里面参数的意思,在学习ListView时,感觉吃力很多,新单词有些多,容易记混使用方法
经过这些天的学习,明白了就业班和基础班的区别,相比之下在基础班节奏还是慢的,明白了不能拿在基础班的态度,对待就业班,努力的去改善自己的学习方法和节奏,也慢慢的去适应就业班,跟着节奏一点一点的往前跟,希望自己不要掉队,加油!!!
- 安卓基础笔记2之SQLit数据库
- 安卓应用版本升级时sqlit数据库升级
- 【Android】安卓学习笔记之操作SQLite数据库基础
- Android教程之SQlit数据库操作
- 安卓开发之java基础笔记【2】
- 安卓学习笔记之SQLite数据库
- 安卓数据库基础
- 安卓基础笔记
- sqlit数据库操作总结
- 安卓学习笔记基础篇之环境配置
- 安卓开发之java基础篇笔记【1】
- 安卓开发之java基础笔记【3】
- 安卓开发之java基础笔记【4】
- 安卓开发之java基础笔记【5】
- 安卓开发之java基础笔记【6】
- 安卓开发之java基础笔记8常用API
- 安卓开发之java基础笔记十IO流
- 安卓基础笔记4之网络连接
- bios boot option 找不到u盘
- 取尺法 和区间调度
- python之列表推导式及嵌套列表解析学习
- 这个计算机网络= =
- Java8 Interface Lambda
- 安卓基础笔记2之SQLit数据库
- Android的ion相关学习(二)
- 解决My eclipse 工程发布时端口占用问题
- java插入数据后返回新插入数据的id字段(自增)
- 微信小程序填坑之路(四)--2016.12.21 更新
- Union和Union All到底有什么区别
- 与MySQL传统复制相比,GTID有哪些独特的复制姿势?
- IntelliJ IDEA 使用详解
- ipfilter sunOs防火墙的配置