一、数据库基础
1、安装SQLite
在官网下载所需的数据库插件。下载完成后,解压到C:\sqlite目录下,把路径配置到环境变量--->系统变量的path下,即可。
检验是否安装成功,如下图,出现数据库版本说明安装成功。
安装后可直接在命令行输入数据库操作命令,查看数据库内容,没有安装的话,需要在AndroidStudio中用adb命令进入所在目录,查看数据库内容。所以,安装不安装影响不大,反正都可以用。
2、数据库基本命令
创建数据库 sqlite3 database_name.db
创建表 CREATE TABLE table_name(column_name_1 data_type_1,column_name_2 data_type_2,...);
在数据库中插入数据 INSERT INTO table_name(column_name_1,column_name_2,...) VALUES (values_1,values_2,...);
读取数据库中的数据 SELECT columns FROM table_name; (从数据库中选择定数据)
database.png
语句解析:
jiexi.pngSQL语句特别提示:
1)所有数据库语句都以“ ; ”(分号)结束,如果没有“ ; ”的情况下会出现“ ... ”提示用户继续输入内容。
2)数据库关键字不区分大小写,但是为了方便查看,数据库结构化语句一般是用大写
SQL的其他命令(注意,这些命令不用" ;"结束,并且严格区分大小写)
这些命令不用记忆,当使用时,直接.help即可,查找自己所需的命令
.header <on|off>
.help 帮助命令,可以查看所有的命令
.mode <mode> 设置输出模式(asci,csv,column,html,insert,line,list,tabs,tcl)
.open <filename> 关闭当前数据库,打开fliename对应的数据库
.quit 退出命令行
.schema >table_name> 显示创建表的语句
.tables 列出表名
二、Android中使用数据库
官方文档
数据库使用场景:数据量大,数据有一定的格式
1、首先创建数据库前需明确创建数据库的名字、表名、以及各列的名字及数据类型,(ps,补充数据库的数据类型)
NULL null空
INTEGER 整型
REAL 浮点型
TEXT 文本类型
BOLB 二进制类型
2、Contract类,存储数据库的结构即架构,将数据库中的表名、列名抽象成常量定义在Contract类中。Contract类的优点
1)后期的更新维护会更方便
2)生成SQL指令时,避免拼写错误
3)为了定义存储数据库结构,即架构,并且规定去哪里查询数据库常量
创建Contract类的步骤:
a、创建外部类XxxContract
b、创建内部类XxxEntry实现BaseColumns接口
c、为表名和列名定义字符串常量
具体的代码:
public final class BookContract {
private BookContract(){}
//内部类BookEntry ,为数据库中表的每一列定义常量值
public static final class BookEntry implements BaseColumns{
public static final String TABLE_NAME = "book";
public static final String _ID = BaseColumns._ID; // 自增长的id
public static final String COLUMN_BOOK_AUTHOR = "author";
public static final String COLUMN_BOOK_NAME = "name";
public static final String COLUMN_BOOK_PRICE = "price";
public static final String COLUMN_BOOK_PAGES = "pages";
}
}
3、创建数据库的步骤:
1)创建一个类继承SQLiteOpenHelper
2)创建数据库名字和数据库版本的常量
3)创建构造函数
4)实现onCreate()方法
5)实现onUpgrade()方法
public class MySQLiteOpenHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "bookStore.db";
public static final int DATABASE_VERSION = 1;
//创建表
private static final String SQL_CREATE_BOOKSTORE_TABLE = "CREATE TABLE" +
BookContract.BookEntry.TABLE_NAME + "(" +
BookContract.BookEntry._ID + "INTEGER PRIMARY KEY AUTOINCREMENT," +
BookContract.BookEntry.COLUMN_BOOK_NAME + "TEXT," +
BookContract.BookEntry.COLUMN_BOOK_AUTHOR + "TEXT" +
BookContract.BookEntry.COLUMN_BOOK_PAGES + "INTEGER" +
BookContract.BookEntry.COLUMN_BOOK_PRICE + "REAL"
+ ");";
//删除表
private static final String SQL_DELETE_ENTRIES = "DROP TABLE IF EXITS" + BookContract.BookEntry.TABLE_NAME;
/**
* 构造函数四个参数:
* 第一个参数:Contxt,上下文对象,对数据库进行操作
* 第二个参数:数据库名,创建数据库时使用的名称
* 第三个参数:允许在查询数据时返回一个自定义的Cursor,普通情况下传入null
* 第四个参数:当前数据库版本号,可用于数据库升级操作
*/
public MySQLiteOpenHelper(Context context, SQLiteDatabase.CursorFactory factory) {
super(context, DATABASE_NAME, factory, DATABASE_VERSION );
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(SQL_CREATE_BOOKSTORE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL(SQL_DELETE_ENTRIES);
onCreate(sqLiteDatabase);
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}
至此,已经创建了bookStore.db数据库,创建了表book,可通过adb命令来查看数据库内容,在AndroidStudio Terminal中输入adb shell进入设备控制台,然后用cd命令进入data/data/packagename(你自己的包名)可以看到自己建立的数据库,然后用sqlite3 数据名,打开数据库,此时就可以对数据库进行管理了,.table查看当前的表,.schema查看下建表语句
database.png4.对数据库进行增删改查操作
为了访问数据库bookStore.db,需实例化SQLiteOpenHelper的子类:
new MySQLiteOpenHelper(context);
Android中SQLiteDatabase提供了对应的增删改查方法。
1)在数据库中插入数据
通过ContentValues对象的put()方法,放入要存储的数据,然后用insert()方法插入到数据库中。
public void insert(Book book){
//获取数据库对象
SQLiteDatabase db = myHelper.getWritableDatabase();
ContentValues values = new ContentValues();
Log.e("SQL",book.getBookAuthor() + "-----" + book.getBookName() + "----"
+ book.getBookPrice() + "------" +book.getPages());
values.put(BookContract.BookEntry.COLUMN_BOOK_NAME, book.getBookName());
values.put(BookContract.BookEntry.COLUMN_BOOK_PRICE, book.getBookPrice());
values.put(BookContract.BookEntry.COLUMN_BOOK_PAGES, book.getPages());
values.put(BookContract.BookEntry.COLUMN_BOOK_AUTHOR, book.getBookAuthor()) ;
/*
insert(String table, String nullColumnHack, ContentValues values)
参数:String table 要插入数据的表的名称
String nullColumnHack 我们知道数据库中除主键外其他的值可以为null,此参数表示该表的该字段不能为null,此处传入null表示插入的表的字段值可以为空
ContentValues values 要插入的数据,是一个数据集
返回值 long 最新插入的行的ID,如果发生错误,返回-1
*/
long id = db.insert(BookContract.BookEntry.TABLE_NAME, null, values);
book.setId(id);
db.close();
}
2)从数据库中读取数据
从数据库读取数据,需要使用query()方法,传递需要查询的条件。查询后返回一个Cursor对象
Cursor类:
Cursor代表数据库中各行内容的对象,返回的Cursour对象包含了查询结果的所有内容。注意Cursor使用完毕后必须关闭,否则会出现内存泄漏。
具体使用,示例代码:
查询数据库中的所有数据
public List<Book> queryAll() {
SQLiteDatabase db = myHelper.getReadableDatabase();
Cursor cursor = db.query(BookContract.BookEntry.TABLE_NAME, null, null, null, null, null, null);
Log.e("SQL", "数据库的数据总数为" + cursor.getCount());
List<Book> list = new ArrayList<>();
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
Book book = new Book();
book.setBookName(cursor.getString(1));
book.setBookAuthor(cursor.getString(2));
book.setBookPrice(cursor.getFloat(3));
book.setPages(cursor.getInt(4));
list.add(book);
}
}
cursor.close();
db.close();
return list;
}
根据某个项查询(这里根据book Name来查找
public List<Book> queryByInput(String[] queryStr) {
List<Book> books = new ArrayList<>();
SQLiteDatabase db = myHelper.getReadableDatabase();
//select name,author from tables where pages= 100
// 根据查询条件获取具体的列
String[] projection = new String[]{
BookContract.BookEntry.COLUMN_BOOK_NAME,
BookContract.BookEntry.COLUMN_BOOK_AUTHOR,
BookContract.BookEntry.COLUMN_BOOK_PAGES,
BookContract.BookEntry.COLUMN_BOOK_PRICE
};
String selection = BookContract.BookEntry.COLUMN_BOOK_NAME + "=?";
String[] selectionArgs = queryStr;
Cursor cursor = db.query(BookContract.BookEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, null);
try {
while (cursor.moveToNext()) {
Book book = new Book();
book.setBookName(cursor.getString(cursor.getColumnIndex(BookContract.BookEntry.COLUMN_BOOK_NAME)));
book.setBookAuthor(cursor.getString(cursor.getColumnIndex(BookContract.BookEntry.COLUMN_BOOK_NAME)));
book.setBookPrice(cursor.getFloat(cursor.getColumnIndex(BookContract.BookEntry.COLUMN_BOOK_PRICE)));
book.setPages(cursor.getInt(cursor.getColumnIndex(BookContract.BookEntry.COLUMN_BOOK_PAGES)));
books.add(book);
}
} finally {
cursor.close();
}
return books;
}
3)删除数据库中的信息
SQL Injection(SQL注入):随着B/S模式应用开发的发展,使用这
种模式编写应用程序的程序员越来越多,但由于程序员的水平及经验参差不齐,相当大一部分程序员在编写代码时没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患。用户提交一段数据库查询代码,根据程序返回的结构,获得某些想得知的数据,这就是所谓的SQL注入。
public int delete(String name) {
SQLiteDatabase db = myHelper.getWritableDatabase();
// delete(表名,where语句,要查的字段)
int count = db.delete(BookContract.BookEntry.TABLE_NAME, BookContract.BookEntry.COLUMN_BOOK_NAME + " = ?" , new String[]{name});
// db.execSQL("DELETE FROM " + BookContract.BookEntry.TABLE_NAME +" WHERE id = " + id + ";");
Log.e("SQL",BookContract.BookEntry.TABLE_NAME + BookContract.BookEntry.COLUMN_BOOK_NAME + " = ?" + new String[]{name});
db.close();
return count;
}
4)更新数据库
当需要修改数据库中的某些数据时,使用update()方法。update结合了插入与删除语法。
public int update(Book book,String name) {
SQLiteDatabase db = myHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(BookContract.BookEntry.COLUMN_BOOK_NAME, book.getBookName());
values.put(BookContract.BookEntry.COLUMN_BOOK_AUTHOR, book.getBookAuthor());
values.put(BookContract.BookEntry.COLUMN_BOOK_PRICE, book.getBookPrice());
values.put(BookContract.BookEntry.COLUMN_BOOK_PAGES, book.getPages());
int count = db.update(BookContract.BookEntry.TABLE_NAME, values,
BookContract.BookEntry.COLUMN_BOOK_NAME + " = ?",
new String[]{name});
// Log.e("SQL", "update" + book.getId() + book.getBookName() + book.getBookAuthor() + book.getBookPrice() + book.getPages());
db.close();
return count;
}
网友评论