案例资源所在地址:
https://download.csdn.net/download/weixin_41957626/87150608?spm=1001.2014.3001.5503
1.前面学习的文件存储和SharedPreference存储的方式只能存储一些小型的数据但是对于复杂关系以及复杂数据结构的数据仅仅靠文件存储是不能进行实现的。
1.2SQLite简介
1.该类数据库是关系型的数据库实现的功能是MyuSQL数据库是十分相似的,但SQLite没有服务器进程所以把只能是单机版的,不能运行在服务端上。但是优点是小,非常的适合在移动设备上进行使用。除了服务器进程其余的和MySQL是四类的。SQL语句的支持的也是几乎是全部兼容的,仅仅是一小部分的语句是不同的。
2.常见的sql语句
查询:select 字段 from 表 where 条件 group by 分组 havintg 筛选
插入:insert into 表 字段 values 值
更新:update 表 set 字段=新值 (注意只能出现一个set,我老是写多个,要注意where条件)
删除:delete from 表 where 条件
最后会在增删改查中进行实现。
使用SQLiteHelper的作用,预先创建数据库表而不是手动的去创建。
可用于数据库的创建和数据库表的更新。
1.SQLiteHelper:是一个抽象的类,需要去继承,才能用的,需要重写构造方法和里面创建数据库和更新数据库的方法。这个类其实就是jdbc中Connection和Preparement的结合体。
2.Cursor:游标。类似JDBC中的result集合,是用来遍历结果集的。需要使用next指向下一条记录。
数据库存放的地方,data/data/项目名/database包下
1.自定义类继承SQLiteHelper重写其中的方法。
2.主要是重写里面的oncreate方法。
3.需要重写里面的构造方法,一般来说需要将游标设置为null,第一个参数是上下文,第二个是数据库的名称,第三个是游标,第四个是版本号。
1.打开数据库的方法?
以下两种方式得到的都是被SQLiteDatabase对象
只读方式:getReadableDatabase,如果打开的数据库满了,此时只能读不能写
可读可写的方式::getWritableDatabase,如果打开的数据库满了,此时只能读不能写,但是还是被会报错的。
注意打开的数据库需要进行关闭操作!调用close方法就可以。
实例:创建一个数据库帮助类
重写了一个构造方法
重写了oncreate方法,进行了数据库的创建
重写了onupgrade方法,进行数据库表的更新,多加了一个新的字段
//===数据库帮助类
public class MySQLitehelper extends SQLiteOpenHelper {
// 构造方法public MySQLitehelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);}
// 创建一个不需要游标的构造方法public MySQLitehelper(@Nullable Context context, @Nullable String name, int version) {super(context, name, null, version);}
// 创建数据库表的方法@Overridepublic void onCreate(SQLiteDatabase db) {//此方法再创建此类的对象后进行回调,编写一条可以执行的sql语句db.execSQL("create table student (id interger primary key autoincrement,name varchar(20),age varchar(10))");
}
// 更新数据库表表的方法@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {//当版本号发生更新的时候进行回调//一般是田家炳新的数据库字段的时候进行回调db.execSQL("alter table student add sex varchar(10)");}
}
//===数据库帮助类
public class MySQLitehelper extends SQLiteOpenHelper {
// 构造方法public MySQLitehelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);}
// 创建一个不需要游标的构造方法public MySQLitehelper(@Nullable Context context, @Nullable String name, int version) {super(context, name, null, version);}
// 创建数据库表的方法@Overridepublic void onCreate(SQLiteDatabase db) {//此方法再创建此类的对象后进行回调,编写一条可以执行的sql语句db.execSQL("create table student (id interger primary key autoincrement,name varchar(20),age varchar(10))");
}
// 更新数据库表表的方法@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {//当版本号发生更新的时候进行回调//一般是田家炳新的数据库字段的时候进行回调db.execSQL("alter table student add sex varchar(10)");}
}
该类的作用就是用来进行对数据库的增删改查操作的
1.创建的过程
创建一个自定义的helper对象
获取一个可读或者是可写的SQLiteDatabase对象
通过第二步获取的对象进行增删改查的操作
就是CRUD操作
1.create
2.query
3.update
4.delete
3.2.1close方法
作用:关闭数据库。
3.2.2query方法
1.作用:查询记录得到的对象是一个游标对象
参数分别是 表名,查询的字段集合,条件,动态条件, 分组, 筛选,排序
Cursor cursor= database.query("student",new String[]{"id,name,age"},null,null,null,null,null);
3.2.3insert方法
ContentValues是不能存储对象的,只能存储普通的键值对
1.通过execSQL的方式
2.通过直接进行insert的方式
3.参数
插入数据的返回值是查插入数据的行id,是long类型的值,值为-1的话就是显示插入错误
表名,为null的列明,要插入的数据,需要用到指定的类ContentValues进行数据的插入操作,采用的是键值对的形式进行存储的
ContentValues values=new ContentValues();values.put("name","张三");values.put("age","20");long x=database.insert("student",null,values);
3.2.4delete方法
1.参数:
参数:表名,删除条件,删除条件参数数组
返回值:删除的行数,为0为删除失败
2.作用:
int z= database.delete("student","id=?",new String[]{"1"});
3.2.5update方法
参数:
表名,更新的数据ContenValues,条件,where中传入的参数
返回值:int类型
2.作用:
ContentValues value=new ContentValues();values.put("name","李四");int y=database.update("student",value,"id=?",new String[]{"1"});
3.2.6execSQL
1.作用:执行原声的sql语句,后面的ContentProvider最常用。除了查询都是这一个方法。
execSQL的方式可以动态的输入参数的值。
3.2.7rawQuery方法
1.传入的值一个为sql语句 ,第二个是占位符中的条的值。条件可以设置为null。
占位符可以设置多个,可以通过占位符进行模糊查询。
3.2.8Cursor游标
1.简介:就是一个结果集合,可以对结果进行随机的访问,也可以理解为一个指针,每次执行一个next会从一个元组跳转到下一个元组上去
2.游标:指定定位的位置的那一刻返回元组数据。
常见的方法如下:
moveToPrevious:从当前行移动到上一行,返回值是false或者是true
moveToFirst:从当前行移动到第一行,返回值是false或者是true
moveToLast:从当前行移动到最后一行
moveToPosition(int position),从当前记录的指针移动到指定的位置处。
move(int offset):从当前位置往闪上或者是往下移动指定的位置,为正数表示向下移动,为负数表示向上移动。
3.游标获取参数的方法
getColumenName(int indx):给定指定的索引返回列名,从0开始。
getColumnIndex(String columnName):根据列名获取从0开始的索引,没有的话就返回-1.
getInt(int columnIndex):获取指定索引列的整数值
getString(int columnIndex):获取指定索引列的字符串
一般来说的话是通过getInt或者是getString获取指定列中的数据。
1.项目目录结构如下
2.实体类代码如下:
//实体类
public class Student {private int id;private String name;private String age;
public Student(int id, String name, String age) {this.id = id;this.name = name;this.age = age;}
public Student() {}
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public String getAge() {return age;}
public void setAge(String age) {this.age = age;}
@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", age='" + age + '\'' +'}';}
}
3.dao层下的代码如下。
1)接口的定义
//===定义相关操作数据库的方法
public interface StudentDao {
// 增加数据方法public void addStudent(Context context,Student student);//添加学生public List getStudents(Context context);//获取全部学生public void deleteStudent(Context context,Student student);//删除指定学生的信息public void updateStudent(Context context,Student student);//更新指定学生的信息
}
2)接口实现类的定义
//===操作数据库的实现类
public class StuidentDaoImpl implements StudentDao{
// 增加数据方法public void addStudent(Context context, Student student){//数据库帮助类MySQLitehelper mySQLitehelper=new MySQLitehelper(context,"syudentdb",1);SQLiteDatabase database=mySQLitehelper.getWritableDatabase();database.execSQL("insert into student(name,age) values(?,?)",new String[]{student.getName(),student.getAge()});};
//获取全部学生public List getStudents(Context context){MySQLitehelper mySQLitehelper=new MySQLitehelper(context,"syudentdb",1);SQLiteDatabase database=mySQLitehelper.getWritableDatabase();Cursor cursor=database.rawQuery("select * from student",null);//创建一个集合List list=new ArrayList<>();//创建一个集合//循环查询数据while(cursor.moveToNext()){Student student=new Student();student.setId(cursor.getInt(0));student.setName(cursor.getString(1));student.setAge(cursor.getString(2));list.add(student);}return list;};//获取全部学生public void deleteStudent(Context context,Student student) {MySQLitehelper mySQLitehelper=new MySQLitehelper(context,"syudentdb",1);SQLiteDatabase database=mySQLitehelper.getWritableDatabase();database.execSQL("delete from student where id=?",new String[]{student.getId()+""});}
//删除指定学生的信息public void updateStudent(Context context,Student student){MySQLitehelper mySQLitehelper=new MySQLitehelper(context,"syudentdb",1);SQLiteDatabase database=mySQLitehelper.getWritableDatabase();database.execSQL("update student set name=? ,age=? where id=?",new String[]{student.getName(),student.getAge(),student.getId()+""});};//更新指定学生的信息
}
4.SQLiteHelper数据库连接帮助类的定义
//===数据库帮助类
public class MySQLitehelper extends SQLiteOpenHelper {
// 构造方法public MySQLitehelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);}
// 创建一个不需要游标的构造方法public MySQLitehelper(@Nullable Context context, @Nullable String name, int version) {super(context, name, null, version);}
// 创建数据库表的方法@Overridepublic void onCreate(SQLiteDatabase db) {//此方法再创建此类的对象后进行回调,编写一条可以执行的sql语句db.execSQL("create table student (id INTEGER primary key autoincrement,name varchar(20),age varchar(10))");
}
// 更新数据库表表的方法@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {//当版本号发生更新的时候进行回调//一般是田家炳新的数据库字段的时候进行回调db.execSQL("alter table student add sex varchar(10)");}
}
5.主启动类的代码如下。
主要涉及到的方法是增删改查的方法。
public class MainActivity extends AppCompatActivity {
//定义控件元素EditText id;EditText name;EditText age;Button add,delete,update,query;ListView listView;
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//1.获取控件对象initView();//2.解析布局//布局文件的事件监听listViewListener();//调用增删改查的方法addListener();deleteListener();updateListener();quertyListener();}
// 方法:获取控件对象public void initView(){//获取控件对象id=findViewById(R.id.id);name=findViewById(R.id.name);age=findViewById(R.id.age);add=findViewById(R.id.add);delete=findViewById(R.id.delete);update=findViewById(R.id.update);query=findViewById(R.id.query);listView=findViewById(R.id.listview);//添加标题头的信息View view=LayoutInflater.from(this).inflate(R.layout.student_itemtitle,null);listView.addHeaderView(view);//设置学生的编号不可以被点击id.setClickable(false);id.setFocusable(false);id.setEnabled(false);//会变灰}
// 方法:设置add事件监听public void addListener(){add.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//获取学生的信息// String uid=id.getText().toString();测试采用的插入的方式是主键自增的方式String uname=name.getText().toString();String uage=age.getText().toString();Student student=new Student();student.setName(uname);student.setAge(uage);//创建操作数据库的类StudentDao studentDao=new StuidentDaoImpl();studentDao.addStudent(getApplicationContext(),student);Toast.makeText(MainActivity.this, "增加成功", Toast.LENGTH_SHORT).show();}});}
// 删除事件监听public void deleteListener(){delete.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//获取学生的信息String uid=id.getText().toString();//测试采用的插入的方式是主键自增的方式String uname=name.getText().toString();String uage=age.getText().toString();Student student=new Student();if (!uid.equals(""))//不能为空{//创建操作数据库的类student.setId(Integer.parseInt(uid));student.setName(uname);student.setAge(uage);StudentDao studentDao=new StuidentDaoImpl();studentDao.deleteStudent(getApplicationContext(),student);Toast.makeText(MainActivity.this, "删除成功", Toast.LENGTH_SHORT).show();}else{Toast.makeText(MainActivity.this, "删除失败!", Toast.LENGTH_SHORT).show();}}});}
// 更新事件监听public void updateListener(){update.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//获取学生的信息String uid=id.getText().toString();//测试采用的插入的方式是主键自增的方式String uname=name.getText().toString();String uage=age.getText().toString();Student student=new Student();if (!uid.equals(""))//不能为空{//创建操作数据库的类student.setId(Integer.parseInt(uid));student.setName(uname);student.setAge(uage);StudentDao studentDao=new StuidentDaoImpl();studentDao.updateStudent(getApplicationContext(),student);Toast.makeText(MainActivity.this, "修改成功", Toast.LENGTH_SHORT).show();}else{Toast.makeText(MainActivity.this, "删除失败!", Toast.LENGTH_SHORT).show();}}});}
// 查询事件监听public void quertyListener(){query.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {StudentDao studentDao=new StuidentDaoImpl();List list=studentDao.getStudents(getApplicationContext());//获取全部的学生的信息//调用显示界面的方法initListView(list);}});}//方法:显示界面的内容public void initListView(List list){//创建表一个只能保存map的集合List
6.列表项的布局文件
表头的布局文件
列表项的布局文件
主启动类的布局文件
1)表头的布局文件
2)列表项的布局文件
3)主启动类的布局文件
`
6.运行的效果图