iOS H5 PHP
数据库管理系统
SQL: SQL 是Structured Query Language(结构化查询语言)的缩写,SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言.
常见的数据库:
My SQL : MySQL是一个精巧的SQL数据库管理系统优点:免费,轻量级
Oracle : 甲骨文公司的一款关系数据库管理系统.系统可移植性好,使用方便,功能强.
数据库特征:
以一定的方式存储在一起(表结构)
能为多个用户共享
具有尽可能少的冗余代码
与程序彼此独立的数据集合
数据库(Database)是按照数据结构来组织,存储和管理数据的仓库.
数据库分类
关系型数据库(主流)
对象型数据库
层次性数据库
常用关系型数据库: PC :Orcsle ,My SQL ,SQL Server.Access.DB2 ;嵌入式:SQLite;
表: 是数据库中一个非常重要的对象,是其他对象的基础.
字段: 表的”列”成为”字段” , 每个字段包含某一专题的信息.
记录: 是指对应于数据表中一行信息的一组完整的相关信息.
SQL语句
SQLite是无类型的数据库,可以保存任何类型的数据,对于SQLite来说对字段不指定类型是完全有效的.
SQLite近似类规则
SQLite字段约束条件:
NOT NULL -非空(必填选项)
UNIQUE - 唯一(不能重复)
PRIMARY KEY - 主键(一般设置为integer或NSString;特点:1: NOT NULL 不为空 2: UNIQUE 不重复,(唯一标识))
FOREIGN KEY - 外键(该字段作为另一个表的主键,链表查询)
AUTOINCREMENT - 自增量变量(一般设置Integer设置,它会自动根据上一条数据自增)
CHECK -条件检查(确保一列中所有值满足一定条件)
DEFAULT - 默认
表里可以没有主键,主键不是必填选项,当把一个字段设置为PRIMARY KEY 那么这个字段为必填选项 (不可为空,不能重复)
去
SQL语句:
建表命令: (Create table)
数据插入命令:(Insert)
数据库更新命令:(Update)
数据库删除命令:(Delete)
数据库检索命令:(Select)
字段类型一定要填
注:如果值是字符串或字符类型,需要用单引号括起来
update
update stu set gender = ‘ 女’ where gender = ‘男' ; 整列修改
update stu set gender = ‘ 女’ where name = ‘班长' ; 单条修改
delete
从stu里删除所有年龄为10的数据
查询select
查询一个表里所有数据当 select * from stu where name = ‘班长' ;
单例
#import"DataBaseHandle.h"
staticDataBaseHandle*dataBase =nil;
@interfaceDataBaseHandle()
@end
@implementationDataBaseHandle
//单例方法
+ (DataBaseHandle*)sharedDataBaseHandle{
if(dataBase==nil) {
dataBase= [[DataBaseHandlealloc]init];
}
returndataBase;
}
@property(nonatomic,copy)NSString* dbPath;
//懒加载
//获取路径 documents文件夹下的一个叫做person.sqlite
//重写getter方法
-(NSString*)dbPath{
if(_dbPath==nil) {
NSString*documentPathStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)objectAtIndex:0];
_dbPath= [documentPathStrstringByAppendingPathComponent:@"person.sqlite"];
}
return_dbPath;
}
数据库技术的实现
流程
Linux系统级的SQLite技术实现框架:Build Phases —>Link With Libraries —>添加 —>sqlite —>libsqlite3.0.tbd
引入头文件
打开数据库
对数据库,并进行操作(执行SQL命令 建表,增删改查)
关闭数据库
代码实现:
staticsqlite3*db =nil;
.h
#import
@interfaceDataBaseHandle :NSObject
+ (DataBaseHandle*)sharedDataBaseHandle;
//返回自身
//命名一般用share和default开头+类名
//打开数据库
-(void)openDB;
//关闭数据库
-(void)closeDB;
//创建表
-(void)createTable;
//插入一条数据
-(void)insertName:(NSString*)name
gender:(NSString*)gender
age:(NSInteger)age;
//通过UID更新一个数据
-(void)updateWithUID:(NSInteger)uid;
//通过UID删除一个数据
-(void)deleteWithUID:(NSInteger)uid;
//搜索全部
-(void)searchAll;
//根据name查询一条数据
-(void)searchWithName:(NSString*)name;
//根据gender查询一条数据
-(void)searchWithGender:(NSString*)gender;
//根据age查询一条数据
-(void)searchWithAge:(NSInteger)age;
@end
.m
打开数据库
//初始化一个数据库
-(void)openDB{
//打开数据库的函数,在数据库里所有字符串都要变成utf-8的格式
//第一个参数:路径名,第一次用self. (懒加载),再用直接打就行了
intresult =sqlite3_open(self.dbPath.UTF8String, &db);
if(result ==SQLITE_OK) {
NSLog(@"打开成功");
}else{
NSLog(@"打开失败");
}
}
执行SQL命令
1.创建表
-(void)createTable{
//创建一个person表,要求字段: UID integer (主键,自增) name text ,gender text ,age integer
NSString*createString =@"create table if not exists person(uid integer primary key autoincrement not null,name text,gender text,age integer)";
//参数1:数据库
//参数2:create语句(UTF8修饰)
//参数3:结果的回调函数
//参数4:回调函数的参数
//参数5:错误信息
intresult =sqlite3_exec(db, createString.UTF8String,NULL,NULL,NULL);
if(result ==SQLITE_OK) {
NSLog(@"创建成功");
}else{
NSLog(@"创建失败%d",result);
}
NSLog(@"_dbPath === %@",_dbPath);
}
2.插入一条数据
//插入一条数据.m
-(void)insertName:(NSString*)name
gender:(NSString*)gender
age:(NSInteger)age{
//插入数据的sql语句,数据不确定,所以在values里面使用'?'代替,之后向里面绑定
NSString*insertString =@"insert into person(name,gender,age)values(?,?,?)";
//伴随指针
sqlite3_stmt*stmt =nil;
//预执行SQL语句
//参数1:数据库
//参数2: SQL语句
//参数3:字节数;如果为负,表示取值取到碰到结束符号('\000','u000').
//参数4:伴随指针.会伴随着数据库的操作,获取之或者绑定值
//参数5:取值的时候如果取得不全,怎么余下的存入这里
intresult =sqlite3_prepare(db, insertString.UTF8String, -1, &stmt,NULL);
//如果预执行成功的话,那么就要往里面放数据了
if(result ==SQLITE_OK) {
//向预执行的SQL语句里面插入参数(取代'?'的位置)
//参数1:伴随指针
//参数2:确定替代'?'的位置,从1开始
//参数3:插入数据
//参数4:取得字节数
//参数5:回调函数
sqlite3_bind_text(stmt, 1, name.UTF8String, -1,NULL);
//
sqlite3_bind_text(stmt, 2, gender.UTF8String, -1,NULL);
// int用int64方法
sqlite3_bind_int64(stmt, 3, age);
//SQL语句已写全
//执行伴随指针,如果为SQLITE_DONE代表执行陈宫,并且成功的插入数据.
if(sqlite3_step(stmt) ==SQLITE_DONE) {
NSLog(@"插入成功");
}else{
NSLog(@"插入失败%d",result);
}
}
//最后,一定要记得释放掉伴随指针
sqlite3_finalize(stmt);
}
3.修改一条数据
//改
-(void)updateWithUID:(NSInteger)uid{
NSString*updateString =@"update person set name = '王军' where uid = ?";
//伴随指针
sqlite3_stmt*stmt =nil;
intresult =sqlite3_prepare(db, updateString.UTF8String, -1, &stmt,NULL);
if(result ==SQLITE_OK) {
sqlite3_bind_int64(stmt, 1, uid);
if(sqlite3_step(stmt) ==SQLITE_DONE) {
NSLog(@"修改成功");
}
}
sqlite3_finalize(stmt);
}
4.删除一条数据
//删
-(void)deleteWithUID:(NSInteger)uid{
NSString*deleteString = [NSStringstringWithFormat:@"delete from person where uid = %ld",uid];
intresult =sqlite3_exec(db, deleteString.UTF8String,NULL,NULL,NULL);
if(result ==SQLITE_OK) {
NSLog(@"删除成功");
}else{
NSLog(@"删除失败");
}
}
5.查询所有数据
//查
-(void)searchAll{
NSString*searchString =@"Select *from person";
//伴随指针
sqlite3_stmt*stmt =nil;
intresult =sqlite3_prepare(db, searchString.UTF8String, -1, &stmt,NULL);
if(result ==SQLITE_OK) {
//当不知道循环次数,用while
//当sqlite3_step(stmt) ==SQLITE_ROW的时候,代表还有下一条数据
while(sqlite3_step(stmt) ==SQLITE_ROW) {
//参数2 :参数位置从零开始的
intuid =sqlite3_column_int(stmt, 0);
NSLog(@"%d",uid);
NSString*name = [NSStringstringWithUTF8String:(constchar*)sqlite3_column_text(stmt, 1)];
NSString*gender =[NSStringstringWithUTF8String:(constchar*)sqlite3_column_text(stmt, 2)];
NSIntegerage =sqlite3_column_int(stmt, 3);
NSLog(@"%@",name);
NSLog(@"%@",gender);
NSLog(@"%ld",age);
}
}
}
6.按照name查询数据
-(void)searchWithName:(NSString*)name{
NSString*searchString =@"select uid,age,gender from person where name = ?";
//伴随指针
sqlite3_stmt*stmt =nil;
//
intresult =sqlite3_prepare(db, searchString.UTF8String, -1, &stmt,NULL);
if(result ==SQLITE_OK) {
sqlite3_bind_text(stmt, 1, name.UTF8String, -1,NULL);//注 :真正的为SQL语句中 ? 绑定(name.UTF8String)值
while(sqlite3_step(stmt) ==SQLITE_ROW) {
intuid =sqlite3_column_int(stmt, 0);
NSLog(@"%d",uid);
//NSString *name = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(stmt, 1)];
NSString*gender = [NSStringstringWithUTF8String:(constchar*)sqlite3_column_text(stmt, 2)];
NSIntegerage =sqlite3_column_int(stmt, 1);
//NSLog(@"%@",name);
NSLog(@"%@",gender);
NSLog(@"%ld",age);
}
}
sqlite3_finalize(stmt);
}
控制器
#import"ViewController.h"
#import"DataBaseHandle.h"
@interfaceViewController()
@end
@implementationViewController
- (void)viewDidLoad {
[superviewDidLoad];
DataBaseHandle*dataBase = [DataBaseHandlesharedDataBaseHandle];
[dataBaseopenDB];
[dataBasecreateTable];
[dataBaseinsertName:@"骚军"gender:@"男"age:38];
[dataBaseupdateWithUID:1];
[dataBasedeleteWithUID:2];
}
@end
SQLite语法:
执行sql语句 :sqlite3_exec()可以执行任何SQL语句,比如创表,更新,插入和删除操作.但是一般不用于它执行查询语句,因为它不会返回查询到的数据
预执行:
sqlite3_prepare( ) 这个函数将sql文本转换成一个准备语句(prepared statement)对象,同时返回这个对象的指针.他实际上并不执行(evaluate)这个SQL语句,他仅仅为执行准备这个sql语句. <参数 1 db :数据库指针 参数 2 zSql : sql语句, 使用UTF-8编码 参数 3 nByte : 字节数,如果为负,则函数取出zSql中从开始到第一个终止符’\000’或’u000’ 参数4 ppStmt : 伴随指针,能够使用sqlite3_steo( )执行的编译好的准备指针,如果错误发生,它被置为NULL 参数5 pzTail: 参数3没取完所有内容,剩下的存放到pzTail中 >
sqlite3_bind_*( ) 给宿主参数(host parameters) 绑定值(* 代表不同类型) <参数1 : 伴随指针 参数 2: 参数序号(从1开始) 参数3: 参数值 参数 4: 参数长度 参数 5 : 函数指针,SQLITE3执行完操作后回调此函数,通常用于释放字符串占用的内存>
sqlite3_step ( ) 一次或多次来执行前面sqlite3_prepare 创建的准备语句<>
sqlite3_column( ) 这个过程从执行sqlite3_step( )执行一个准备语句得到的结果集的当前行中返回一个列. 每次sqlite3_step得到一个结果集的列停下后,这个过程就可以被多次调用去查询这个行的各列的值. 对列操作是有多个函数,均以sqlite3_column为前缀 <参数 1 : 从sqlite3_prepare返回来的prepared statement对象的指针 参数 2 : 指定这一行中想要被返回的列的索引即(从0 开始)前面SQL语句字段顺序的索引 (如果SQL 写的* 则索引顺序即表格里字段的顺序, 如果不同则表示的是SQL语句中字段的顺序)>
sqlite3_finalize( ) 这个过程销毁前面被sqlite3_prepare创建的准备语句,每个准备语句都必须使用这个函数去销毁以防止内存泄露
#defineSQLITE_OK 0 /* 成功 | Successful result */
/*错误码开始*/
#defineSQLITE_ERROR 1 /* SQL错误 或 丢失数据库 | SQL error or missing database */
#defineSQLITE_INTERNAL 2 /* SQLite 内部逻辑错误 | Internal logic error in SQLite */
#defineSQLITE_PERM 3 /* 拒绝访问 | Access permission denied */
#defineSQLITE_ABORT 4 /* 回调函数请求取消操作 | Callback routine requested an abort */
#defineSQLITE_BUSY 5 /* 数据库文件被锁定 | The database file is locked */
#defineSQLITE_LOCKED 6 /* 数据库中的一个表被锁定 | A table in the database is locked */
#defineSQLITE_NOMEM 7 /* 某次 malloc() 函数调用失败 | A malloc() failed */
#defineSQLITE_READONLY 8 /* 尝试写入一个只读数据库 | Attempt to write a readonly database */
#defineSQLITE_INTERRUPT 9 /* 操作被 sqlite3_interupt() 函数中断 | Operation terminated by sqlite3_interrupt() */
#defineSQLITE_IOERR 10 /* 发生某些磁盘 I/O 错误 | Some kind of disk I/O error occurred */
#defineSQLITE_CORRUPT 11 /* 数据库磁盘映像不正确 | The database disk image is malformed */
#defineSQLITE_NOTFOUND 12 /* sqlite3_file_control() 中出现未知操作数 | Unknown opcode in sqlite3_file_control() */
#defineSQLITE_FULL 13 /* 因为数据库满导致插入失败 | Insertion failed because database is full */
#defineSQLITE_CANTOPEN 14 /* 无法打开数据库文件 | Unable to open the database file */
#defineSQLITE_PROTOCOL 15 /* 数据库锁定协议错误 | Database lock protocol error */
#defineSQLITE_EMPTY 16 /* 数据库为空 | Database is empty */
#defineSQLITE_SCHEMA 17 /* 数据结构发生改变 | The database schema changed */
#defineSQLITE_TOOBIG 18 /* 字符串或二进制数据超过大小限制 | String or BLOB exceeds size limit */
#defineSQLITE_CONSTRAINT 19 /* 由于约束违例而取消 | Abort due to constraint violation */
#defineSQLITE_MISMATCH 20 /* 数据类型不匹配 | Data type mismatch */
#defineSQLITE_MISUSE 21 /* 不正确的库使用 | Library used incorrectly */
#defineSQLITE_NOLFS 22 /* 使用了操作系统不支持的功能 | Uses OS features not supported on host */
#defineSQLITE_AUTH 23 /* 授权失败 | Authorization denied */
#defineSQLITE_FORMAT 24 /* 附加数据库格式错误 | Auxiliary database format error */
#defineSQLITE_RANGE 25 /* 传递给sqlite3_bind()的第二个参数超出范围 | 2nd parameter to sqlite3_bind out of range */
#defineSQLITE_NOTADB 26 /* 被打开的文件不是一个数据库文件 | File opened that is not a database file */
#defineSQLITE_ROW 100 /* sqlite3_step() 已经产生一个行结果 | sqlite3_step() has another row ready */
#defineSQLITE_DONE 101 /* sqlite3_step() 完成执行操作 | sqlite3_step() has finished executing */
/*错误码结束*/
bind (vt. 绑;约束;装订;包扎;凝固)
prepare(vt. 准备;使适合;装备;起草)
column(n. 纵队,列;专栏)
exec(n. 执行,执行程序;)