动态操作——SQL插入
-
1.1 自定义运算符:分析赋值原理,
-
1.2 实现运算符重载功能:Setter结构体
-
1.3 实现表达式
-
1.4 在Helper类添加infix拼接方法
-
2、在Table中添加insert方法。同时在QueryType中,添加Insert结构体
-
2.1在Table中添加insert方法
-
2.2在QueryType中,添加Insert结构体
-
3、执行SQL语句:提供run方法执行Insert语句
-
1、在Helper中提供可选类型:扩展系统Optional
-
2、在Setter文件中新增可选类型运算符重载,同时在Setter结构体中也需要添加构造方法重载
-
3、给我TableBuilder添加可选类型
插入流程
非空类型
1、新增一个Setter文件
1.1 自定义运算符:分析赋值原理,
let insert = users.insert(id <- "1", name <- "NSLog", email <- "nslog@qq.com", phone <- nil)
try! db.run(insert)
注意:"
<-
"调用的一个方法:
<-
运算符重载函数,插入对象数据
Swift 2.0写法
infix operator <- {
associativity none
precedence 130
}
Swift3.0写法
precedencegroup:表示运算符优先级组,例如
自定义运算符: “
<-
”
系统运算符: -、+、/、
…
系统原生运算符有优先级: (/、
)->高,(-、+)->低
precedencegroup ColumnAssignment {
//结合类型:left(左结合)、right(右结合)、none(无)->结合方向
associativity: left
//是否是赋值运算符
//let name = Expression<String>("name")
//let nameValue:Setter = name <- "NSLog"
assignment: true
//指定运算符优先级
//优先级要低于AssignmentPrecedence类型操作符
//AssignmentPrecedence->标记优先级
lowerThan: AssignmentPrecedence
//AssignmentPrecedence什么意思?
//在我们iOS系统里面(Swift语言中)
//1、2、3、4,不用数字表示,用的常量,枚举...(AssignmentPrecedence表示)
//前缀(prefix)、中缀(infix)、后缀(postfix)
//前缀(prefix),例如:++index
//中缀(infix),例如:a + b
//后缀(postfix),例如:index--
//自定义赋值运算符<-属于中缀
infix operator <- : ColumnAssignment
可将这些统一定义在Setter文件中
infix operator || : LogicalDisjunctionPrecedence
infix operator && : LogicalConjunctionPrecedence
infix operator < : ComparisonPrecedence
infix operator <= : ComparisonPrecedence
infix operator > : ComparisonPrecedence
infix operator >= : ComparisonPrecedence
infix operator == : ComparisonPrecedence
infix operator != : ComparisonPrecedence
infix operator === : ComparisonPrecedence
infix operator !== : ComparisonPrecedence
infix operator ~= : ComparisonPrecedence
infix operator ?? : NilCoalescingPrecedence
infix operator + : AdditionPrecedence
infix operator - : AdditionPrecedence
infix operator &+ : AdditionPrecedence
infix operator &- : AdditionPrecedence
infix operator | : AdditionPrecedence
infix operator ^ : AdditionPrecedence
infix operator * : MultiplicationPrecedence
infix operator / : MultiplicationPrecedence
infix operator % : MultiplicationPrecedence
infix operator &* : MultiplicationPrecedence
infix operator & : MultiplicationPrecedence
infix operator << : BitwiseShiftPrecedence
infix operator >> : BitwiseShiftPrecedence
infix operator ..< : RangeFormationPrecedence
infix operator ... : RangeFormationPrecedence
infix operator *= : AssignmentPrecedence
infix operator /= : AssignmentPrecedence
infix operator %= : AssignmentPrecedence
infix operator += : AssignmentPrecedence
infix operator -= : AssignmentPrecedence
infix operator <<= : AssignmentPrecedence
infix operator >>= : AssignmentPrecedence
infix operator &= : AssignmentPrecedence
infix operator ^= : AssignmentPrecedence
infix operator |= : AssignmentPrecedence
1.2 实现运算符重载功能:Setter结构体
public struct Setter {
//字段名称
let column: Expressible
//字段对应的值
let value: Expressible
//方法重载->方便调用
//参数一:字段名称
//参数二:字段对应的值->Expression<V>
fileprivate init<V : Value>(column: Expression<V>, value: Expression<V>) {
self.column = column
self.value = value
//方法重载->方便调用
//参数一:字段名称
//参数二:字段对应的值->V
fileprivate init<V : Value>(column: Expression<V>, value: V) {
self.column = column
self.value = value
}
1.3 实现表达式
let name = Expression<String>("name")
let nameValue:Setter = name <- "NSLog"
结果:
在Setter结构体中添加一个拼接方法
SQL语句:
insert into t_user values(name = 'NSLog')
拼接结果:
name = 'NSLog'
拼接结果得到这个字符串"name = ‘NSLog’"
将对象转为String类型
extension Setter : Expressible {
public var expression: Expression<Void> {
//拼接->infix中缀
//column = value
//其实:name = 'NSLog'
return "=".infix(column, value, wrap: false)
}
1.4 在Helper类添加infix拼接方法
SQL插入
func infix<T>(_ lhs: Expressible, _ rhs: Expressible, wrap: Bool = true) -> Expression<T> {
let expression = Expression<T>(" \(self) ".join([lhs, rhs]).expression)
guard wrap else {
return expression
return "".wrap(expression)
}
2、在Table中添加insert方法。同时在QueryType中,添加Insert结构体
2.1在Table中添加insert方法
在QueryType,扩展SQL插入
public func insert(_ value: Setter, _ more: Setter...) -> Insert {
return insert([value] + more)
fileprivate func insert(_ values: [Setter]) -> Insert {
let insert = values.reduce((columns: [Expressible](), values: [Expressible]())) { insert, setter in
(insert.columns + [setter.column], insert.values + [setter.value])
//clauses->其实就是SQL语句
//注意数组顺序不能够写错了,否则拼接结果是错误的
//INSERT INTO t_user VALUES (name = 'NSLog', sex = '男')
let clauses: [Expressible?] = [
Expression<Void>(literal: "INSERT"),
Expression<Void>(literal: "INTO"),
tableName(),
"".wrap(insert.columns) as Expression<Void>,
Expression<Void>(literal: "VALUES"),
"".wrap(insert.values) as Expression<Void>
//创建结构体
//compactMap->去除nil值
return Insert(" ".join(clauses.compactMap { $0 }).expression)
public func insert() -> Insert {
return Insert(" ".join([
Expression<Void>(literal: "INSERT INTO"),
tableName(),
Expression<Void>(literal: "DEFAULT VALUES")
]).expression)
}
2.2在QueryType中,添加Insert结构体
public struct Insert : ExpressionType {
public var template: String
public var bindings: [Binding?]
public init(_ template: String, _ bindings: [Binding?]) {
self.template = template
self.bindings = bindings
}
3、执行SQL语句:提供run方法执行Insert语句
extension Connection {
@discardableResult public func run(_ query: Insert) throws -> Int64 {
let expression = query.expression
return try sync {
//执行SQL语句,同时绑定在代码块里面
try self.run(expression.template, expression.bindings)
return self.lastInsertRowId
}
Setter中添加运用操作符
public func <-<V : Value>(column: Expression<V>, value: Expression<V>) -> Setter {
//初始化
return Setter(column: column, value: value)
public func <-<V : Value>(column: Expression<V>, value: V) -> Setter {
return Setter(column: column, value: value)
}
可选类型
1、在Helper中提供可选类型:扩展系统Optional
自定义类型协议:泛型设计
public protocol _OptionalType {
associatedtype WrappedType
extension Optional : _OptionalType {
public typealias WrappedType = Wrapped
}
2、在Setter文件中新增可选类型运算符重载,同时在Setter结构体中也需要添加构造方法重载
public struct Setter {
fileprivate init<V : Value>(column: Expression<V?>, value: Expression<V>) {
self.column = column
self.value = value
fileprivate init<V : Value>(column: Expression<V?>, value: Expression<V?>) {
self.column = column
self.value = value
fileprivate init<V : Value>(column: Expression<V?>, value: V?) {
self.column = column
self.value = Expression<V?>(value: value)
}
public func <-<V : Value>(column: Expression<V?>, value: Expression<V>) -> Setter {
return Setter(column: column, value: value)
public func <-<V : Value>(column: Expression<V?>, value: Expression<V?>) -> Setter {
return Setter(column: column, value: value)
public func <-<V : Value>(column: Expression<V?>, value: V?) -> Setter {
return Setter(column: column, value: value)
}
问题:到了这一步为啥还是报错?
原因:自定义可选类型没有使用,让我们的自定义表示支持可选类型,目前表达式是不支持可选类型。
解决:在Expression文件中,扩展表达式类型可选类型,即扩展ExpressionType
ExpressionType和系统Optional可以相互转换:强制类型转换
ExpressionType类型可以是可选类型
Expression
<String>
(String类型->对应的->UnderlyingType)
实际上就是规定Expression->DataType类型->_OptionalType可选类型
UnderlyingType.WrappedType->可选类型协议中具体值->必需是Value子类
规定了DataType类型允许是可选类型,同时类型范围必需是Value子类
高深->运用了面向协议 + 泛型类型
UnderlyingType表示类型可选(可以为nil)
WrappedType具体类型,例如:String、Int…
例如:String?,Int?,Double?
1、 UnderlyingType对应:?
2、 WrappedType对应:String
组合1+2:String? 两个约束条件
extension ExpressionType where UnderlyingType : _OptionalType, UnderlyingType.WrappedType : Value {
public static var null: Self {
return self.init(value: nil)
public init(value: UnderlyingType.WrappedType?) {
self.init("?", [value?.datatypeValue])
}
领悟Swift 泛型精髓
方法:反复看(至少5遍)
3、给我TableBuilder添加可选类型
@discardableResult public func column<V : Value>(_ name: Expression<V?>) -> TableBuilder {
return column(name, V.declaredDatatype)
jquery语言 jquery-ui
jQuery-UI组件EffectsjQuery UI介绍预设动画方法语法预设动画详解color动画类动画css样式覆盖规则语法jQuery UI介绍
jQuery UI
交互Interactions
小部件Widgets
效果库Effects