Go语言基础之16--Mysql基本操作
一、Mysql驱动及数据库连接
1.1 Golang中的Mysql驱动
A. https://github.com/go-sql-driver/mysql
B. Go本身不提供具体数据库驱动,只提供驱动接口和管理。(官方只是封装了接口并没有提供具体的实现)
C. 各个数据库驱动需要第三方实现,并且注册到Go中的驱动管理中。
1.2 Mysql驱动,注册示例
解释:
其实就是把mysql驱动注册到golang官方的接口中,然后在通过golang的接口去操作mysql具体实例了。驱动的名字叫mysql。
1.3 导入Mysql驱动
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
解释:
可能会好奇为什么导入"database/sql"后,为什么导入mysql驱动却要加"_"来忽略掉呢?其实真正的原因是因为init函数的原因,下面通过一个实例来了解一下:
写一个自定义的包:
目录结构如下:
custom_pkg:
custom.go:
package custom_pkg import (
"fmt"
) var Count int func init() {
fmt.Printf("hello world, i'm in init function\n")
}
custom2.go:
package custom_pkg import (
"fmt"
) func init() {
fmt.Printf("hello world, i'm in init function custom2\n")
}
custom_example:
main.go:
package main import (
"6/After_class/mysql/custom_pkg"
"fmt"
) func main() {
fmt.Printf("count=%d\n", custom_pkg.Count)
}
执行结果如下:
可以发现执行的结果是将导入的包的init函数执行了。
总结:葵花宝典
init函数名字是固定的,没有参数也没有返回值,其是包用来做初始化的,会自动执行(在包导入的时候执行),在一个包中这个函数可以有多个。所以之后我们就可以利用init函数做一些包初始化的逻辑。
了解:init函数执行顺序,先执行导入的包的init函数,在执行当前包的init函数。
所以说在倒入mysql驱动时为什么要加"_"来忽略掉呢?就是因为想要执行init函数。
1.4 连接数据库
先安装mysql驱动:
go get -u github.com/go-sql-driver/mysql
连接实例如下:
package main import (
"database/sql"
"fmt" _ "github.com/go-sql-driver/mysql"
) func main() {
dsn := "root:123456@tcp(127.0.0.1:3306)/golang" //连接数据库的配置
Db, err := sql.Open("mysql", dsn) //Open函数第一个参数就是驱动的名字(不能随意写的)
if err != nil { //有一个坑,如果连接数据库配置写错了,不会在此处报错
fmt.Printf("open mysql is failed,err:%v\n", err)
return
} err = Db.Ping() //ping一下没报错证明连接数据库成功
if err != nil {
fmt.Printf("ping is failed,err:%v\n", err)
return
} fmt.Printf("connect to db successful\n")
}
执行结果:
二、Mysql数据基本操作
首先准备环境先创建一张表
建表语句如下:
CREATE TABLE user (id bigint(20) NOT NULL AUTO_INCREMENT,name varchar(20) DEFAULT '',age int(11) DEFAULT '0',PRIMARY KEY (id
)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
2.1 sql查询
A. 单行查询, Db.QueryRow
B 多行查询, Db.Query
实例1:单行查询 Db.QueryRow
package main import (
"database/sql"
"fmt" _ "github.com/go-sql-driver/mysql"
) type User struct { //为要查询的表定义一个结构体(数据库定义的表要有1个结构体来封装,否则会十分混乱)
Id int64 `db:"id"` //数据库一般都是小写,所以我们需要借助tag来映射(结构体中字段名写什么就无所谓了,反正要做映射)
Name string `db:"name"`
Age int `db:"age"`
} func QueryRow(Db *sql.DB) {
id :=
row := Db.QueryRow("select id,name,age from user where id=?", id) //?是占位符,可以传入数值拼接成完整的sql语句发给mysql服务器,然后mysql返回数据集。 var user User
err := row.Scan(&user.Id, &user.Name, &user.Age) //Scan这里查询有2种错误 1、查询不到数据失败(网络原因等);2、查询过程中查询失败(和因为网络原因造成的错误区分开)
if err == sql.ErrNoRows { //对应第二种错误 ErrNoRows表示查询过程中是没发生错误的
fmt.Printf("not found data of id:%d\n", id)
return
} if err != nil { //对应第一种错误
fmt.Printf("scan failed, err:%v\n", err)
return
} fmt.Printf("user:%#v\n", user) } func main() {
dsn := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sql.Open("mysql", dsn)
if err != nil {
fmt.Printf("open mysql is failed,err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping is failed,err:%v\n", err)
return
} fmt.Printf("connect to db successful\n") QueryRow(Db)
}
执行结果:
实例2:多行查询, Db.Query
package main import (
"database/sql"
"fmt" _ "github.com/go-sql-driver/mysql"
) type User struct {
Id int64 `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} func Query(Db *sql.DB) {
id :=
rows, err := Db.Query("select id, name, age from user where id>?", id)
//rows返回的是1个结果集,这个rows结果集,用完之后,一定释放!rows.Close() 这个是消耗数据库连接资源的。
defer func() {
if rows != nil {
rows.Close()
}
}() if err == sql.ErrNoRows {
fmt.Printf("not found data of id:%d\n", id)
return
} if err != nil {
fmt.Printf("scan failed, err:%v\n", err)
return
} for rows.Next() { //多行数据通过写一个for循环来进行处理,有数据返回true接着执行,没数据返回false就退出 Next就如同一个游标,查到最后就会返回一个false,就查询结束退出循环了。
var user User
err := rows.Scan(&user.Id, &user.Name, &user.Age)
if err != nil {
fmt.Printf("scan failed, err:%v\n", err)
return
} fmt.Printf("user:%#v\n", user)
} } func main() {
dsn := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sql.Open("mysql", dsn)
if err != nil {
fmt.Printf("open mysql is failed,err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping is failed,err:%v\n", err)
return
} fmt.Printf("connect to db successful\n") Query(Db)
}
执行结果如下:
2.2 Mysql 插入、更新和删除
A. Db.Exec(query, args…interface{})(Result, error)
解释:插入、更新、删除都是Exec方法(sql语句,传入占位符对应的值)(返回结果集,错误)
B. 插入的主键id获取, Result. LastInsertId()
插入实例:
package main import (
"database/sql"
"fmt" _ "github.com/go-sql-driver/mysql"
) type User struct {
Id int64 `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} func Insert(DB *sql.DB) {
username := "user01"
age := result, err := DB.Exec("insert into user(name, age)values(?, ?)", username, age)
if err != nil {
fmt.Printf("exec failed, err:%v\n", err)
return
} id, err := result.LastInsertId() //获取最后一次插入的id
if err != nil {
fmt.Printf("last insert id failed, err:%v\n", err)
return
} affectRows, err := result.RowsAffected() //此次操作影响的行数
if err != nil {
fmt.Printf("affectRows failed, err:%v\n", err)
return
} fmt.Printf("last insert id:%d affect rows:%d\n", id, affectRows)
} func main() {
dsn := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sql.Open("mysql", dsn)
if err != nil {
fmt.Printf("open mysql is failed,err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping is failed,err:%v\n", err)
return
} fmt.Printf("connect to db successful\n") Insert(Db)
}
执行结果:
更新实例:
package main import (
"database/sql"
"fmt" _ "github.com/go-sql-driver/mysql"
) type User struct {
Id int64 `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} func Update(DB *sql.DB) {
username := "user02"
age :=
id :=
result, err := DB.Exec("update user set name=?, age=? where id=?", username, age, id)
if err != nil {
fmt.Printf("exec failed, err:%v\n", err)
return
} affectRows, err := result.RowsAffected()
if err != nil {
fmt.Printf("affectRows failed, err:%v\n", err)
return
} fmt.Printf("last update id:%d affect rows:%d\n", id, affectRows)
} func main() {
dsn := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sql.Open("mysql", dsn)
if err != nil {
fmt.Printf("open mysql is failed,err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping is failed,err:%v\n", err)
return
} fmt.Printf("connect to db successful\n") Update(Db)
}
执行结果:
数据库结果:
删除实例:
package main import (
"database/sql"
"fmt" _ "github.com/go-sql-driver/mysql"
) type User struct {
Id int64 `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} func Delete(DB *sql.DB) {
id :=
result, err := DB.Exec("delete from user where id=?", id)
if err != nil {
fmt.Printf("exec failed, err:%v\n", err)
return
} affectRows, err := result.RowsAffected()
if err != nil {
fmt.Printf("affectRows failed, err:%v\n", err)
return
} fmt.Printf("last delete id:%d affect rows:%d\n", id, affectRows)
} func main() {
dsn := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sql.Open("mysql", dsn)
if err != nil {
fmt.Printf("open mysql is failed,err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping is failed,err:%v\n", err)
return
} fmt.Printf("connect to db successful\n") Delete(Db)
}
执行结果如下:
数据库结果:
三、Mysql预处理
3.1 一般sql处理流程
1. 客户端拼接好sql语句
2. 客户端发送sql语句到mysql服务器
3. mysql服务器解析sql语句并执行, 把执行结果发送给客户端
3.2 预处理处理流程
1. 把sql分为两部分,命令部分和数据部分。
2. 首先把命令部分发送给mysql服务器, mysql进行sql预处理
3. 然后把数据部分发送给mysql服务器, mysql进行占位符替换
4. mysql服务器执行sql语句并返回结果给客户端
3.3 Mysql预处理优势
A. 同一条sql反复执行,性能会很高。
B. 避免sql注入问题
3.4 Mysql预处理实例
A. 查询操作,
1. Db.Prepare(sql string) (*sql.Stmt, error) stmt可以暂且理解为语句
2. Stmt.Query()
B. 更新操作(插入、更新、 delete),
1. Db.Prepare(sql string) (*sql.Stmt, error)
2. Stmt.Exec()
查询操作预处理实例:
package main import (
"database/sql"
"fmt" _ "github.com/go-sql-driver/mysql"
) type User struct {
Id int64 `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} func PrepareQuery(DB *sql.DB) {
//预处理第1步:发送sql语句命令部分
stmt, err := DB.Prepare("select id, name, age from user where id>?")
if err != nil {
fmt.Printf("prepare failed, err:%v\n", err)
return
} //预处理第2步:发送sql语句数据部分
id :=
rows, err := stmt.Query(id)
//这个rows结果集,用完之后,一定释放!rows.Close()
defer func() {
if rows != nil {
rows.Close()
}
if stmt != nil { //stmt记住也要释放
stmt.Close()
}
}()
if err == sql.ErrNoRows {
fmt.Printf("not found data of id:%d\n", id)
return
}
if err != nil {
fmt.Printf("scan failed, err:%v\n", err)
return
}
for rows.Next() {
var user User
err := rows.Scan(&user.Id, &user.Name, &user.Age)
if err != nil {
fmt.Printf("scan failed, err:%v\n", err)
return
} fmt.Printf("user:%#v\n", user)
}
} func main() {
dsn := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sql.Open("mysql", dsn)
if err != nil {
fmt.Printf("open mysql is failed,err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping is failed,err:%v\n", err)
return
} fmt.Printf("connect to db successful\n") PrepareQuery(Db)
}
执行结果如下:
更新操作预处理实例:(这里以insert举例)
package main import (
"database/sql"
"fmt" _ "github.com/go-sql-driver/mysql"
) type User struct {
Id int64 `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} func PrepareInsert(DB *sql.DB) {
stmt, err := DB.Prepare("insert into user(name, age)values(?, ?)")
if err != nil {
fmt.Printf("prepare failed, err:%v\n", err)
return
} result, err := stmt.Exec("user10111", )
if err != nil {
fmt.Printf("exec failed, err:%v\n", err)
return
} id, err := result.LastInsertId()
if err != nil {
fmt.Printf("last insert id failed, err:%v\n", err)
return
} affectRows, err := result.RowsAffected()
if err != nil {
fmt.Printf("affectRows failed, err:%v\n", err)
return
} fmt.Printf("last insert id:%d affect rows:%d\n", id, affectRows)
} func main() {
dsn := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sql.Open("mysql", dsn)
if err != nil {
fmt.Printf("open mysql is failed,err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping is failed,err:%v\n", err)
return
} fmt.Printf("connect to db successful\n") PrepareInsert(Db)
}
执行结果:
数据库结果:
四、Mysql事务
4.1 应用场景
1. 同时更新,多个表。
2. 同时更新多行数据。
4.2 事务的ACID
1. 原子性
2. 一致性
3. 隔离性
4. 持久性
4.3 Mysql的事务实例
A. Db.Begin(),开启一个事务
B. Db.Commit(),提交一个事务
C. Db.Rollback(),回滚一个事务
关于事务的实例如下:
package main import (
"database/sql"
"fmt" _ "github.com/go-sql-driver/mysql"
) type User struct {
Id int64 `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} func Transaction(Db *sql.DB) { //开启事务
tx, err := Db.Begin() //tx就是事务这次用来操作数据库的1个连接
if err != nil {
fmt.Printf("begin failed, err:%v\n", err)
return
} _, err = tx.Exec("insert into user(name, age)values(?, ?)", "user0101", ) //插入一条数据
if err != nil {
tx.Rollback()
return
} _, err = tx.Exec("update user set name=?, age=?", "user0101", )
if err != nil {
tx.Rollback() //如果有错误,则回滚
return
} err = tx.Commit() //提交事务
if err != nil {
tx.Rollback()
return
}
} func main() {
dsn := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sql.Open("mysql", dsn)
if err != nil {
fmt.Printf("open mysql is failed,err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping is failed,err:%v\n", err)
return
} fmt.Printf("connect to db successful\n") Transaction(Db)
}
执行结果如下:
数据库结果:
五、sqlx库介绍与使用
5.1 介绍
sqlx是在数据库层面的驱动进行封装的。主要做的是对查询的优化
github地址:
https://github.com/jmoiron/sqlx
安装:
go get github.com/jmoiron/sqlx
5.2 好处
A. 使用更简单
B. 支持多数据库, mysql、 postgresql、 oracle、 sqlite
5.3 开发与使用
A. 查询, sqlx.DB.Get(查单行)和sqlx.DB.Select(查多行)
B. 更新、插入和删除, sqlx.DB.Exec
C. 事务, sqlx.DB.Begin()、 sqlx.DB.Commit、 sqlx.DB.rollback
5.3.1 查询
查询这里对go语言原生sql方法做了优化,封装了接口,所以用sqlx做查询较为方便,不需要像原生一样去考虑结果集close问题、for循环遍历问题、append问题,sqlx帮我们把上述问题都做了(其底层借助反射机制封装了接口)。
单行查询:sqlx.DB.Get
实例:
package main import (
"database/sql"
"fmt" _ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
) type User struct {
Id int64 `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} func QueryRow(Db *sqlx.DB) { //查询单行数据
id :=
var user User
err := Db.Get(&user, "select id, name, age from user where id=?", id)
if err == sql.ErrNoRows { //无数据报错
fmt.Printf("not record found\n")
return
}
if err != nil { //查询失败报错
fmt.Printf("get failed, err:%v\n", err)
return
} fmt.Printf("get user succ, user:%#v\n", user)
} func main() {
dns := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sqlx.Connect("mysql", dns) //sqlx.connect连接数据库
if err != nil {
fmt.Printf("open mysql failed, err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping failed, err:%v\n", err)
return
} fmt.Printf("connect to db succ\n")
QueryRow(Db)
}
执行结果:
多行查询:sqlx.DB.Select
实例:
package main import (
"fmt" _ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
) type User struct {
Id int64 `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} func Query(Db *sqlx.DB) {
var user []*User //多行数据存在切片里
id :=
err := Db.Select(&user, "select id, name, age from user where id>?", id)
if err != nil {
return
}
//fmt.Printf("user :%#v\n", user)
for _, v := range user {
fmt.Println(v)
}
} func main() {
dns := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sqlx.Connect("mysql", dns) //sqlx.connect连接数据库
if err != nil {
fmt.Printf("open mysql failed, err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping failed, err:%v\n", err)
return
} fmt.Printf("connect to db succ\n")
Query(Db)
}
执行结果:
5.3.2 更新、插入和删除 sqlx.DB.Exec
更新、插入、删除这里其实并没有做太多优化,做的就是对go原生sql方法的继承
插入实例:insert
package main import (
"fmt" _ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
) type User struct {
Id int64 `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} func Insert(Db *sqlx.DB) {
username := "harden"
age := result, err := Db.Exec("insert into user(name, age)values(?, ?)", username, age)
if err != nil {
fmt.Printf("exec failed, err:%v\n", err)
return
} id, err := result.LastInsertId()
if err != nil {
fmt.Printf("last insert id failed, err:%v\n", err)
return
} affectRows, err := result.RowsAffected()
if err != nil {
fmt.Printf("affectRows failed, err:%v\n", err)
return
} fmt.Printf("last insert id:%d affect rows:%d\n", id, affectRows)
} func main() {
dns := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sqlx.Connect("mysql", dns) //sqlx.connect连接数据库
if err != nil {
fmt.Printf("open mysql failed, err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping failed, err:%v\n", err)
return
} fmt.Printf("connect to db succ\n")
Insert(Db)
}
执行结果:
查看数据库:
更新实例:update
package main import (
"fmt" _ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
) type User struct {
Id int64 `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} func Update(Db *sqlx.DB) {
username := "user02"
age :=
id :=
result, err := Db.Exec("update user set name=?, age=? where id=?", username, age, id)
if err != nil {
fmt.Printf("exec failed, err:%v\n", err)
return
} affectRows, err := result.RowsAffected()
if err != nil {
fmt.Printf("affectRows failed, err:%v\n", err)
return
} fmt.Printf("last update id:%d affect rows:%d\n", id, affectRows)
} func main() {
dns := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sqlx.Connect("mysql", dns) //sqlx.connect连接数据库
if err != nil {
fmt.Printf("open mysql failed, err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping failed, err:%v\n", err)
return
} fmt.Printf("connect to db succ\n")
Update(Db)
}
执行结果:
查看数据库:
删除实例:delete
package main import (
"fmt" _ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
) type User struct {
Id int64 `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} func Delete(Db *sqlx.DB) {
id :=
result, err := Db.Exec("delete from user where id=?", id)
if err != nil {
fmt.Printf("exec failed, err:%v\n", err)
return
} affectRows, err := result.RowsAffected()
if err != nil {
fmt.Printf("affectRows failed, err:%v\n", err)
return
} fmt.Printf("last delete id:%d affect rows:%d\n", id, affectRows)
} func main() {
dns := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sqlx.Connect("mysql", dns) //sqlx.connect连接数据库
if err != nil {
fmt.Printf("open mysql failed, err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping failed, err:%v\n", err)
return
} fmt.Printf("connect to db succ\n")
Delete(Db)
}
执行结果:
查看数据库:
5.3.3 事务, sqlx.DB.Begin()、 sqlx.DB.Commit、 sqlx.DB.rollback
事务这里其实并没有做太多优化,做的就是对go原生sql方法的继承
实例:
package main import (
"fmt" _ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
) type User struct {
Id int64 `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} func Transaction(Db *sqlx.DB) { //开启事务
tx, err := Db.Begin() //tx就是事务这次用来操作数据库的1个连接
if err != nil {
fmt.Printf("begin failed, err:%v\n", err)
return
} _, err = tx.Exec("insert into user(name, age)values(?, ?)", "user0101", ) //插入一条数据
if err != nil {
tx.Rollback()
return
} _, err = tx.Exec("update user set name=?, age=?", "user0101", )
if err != nil {
tx.Rollback() //如果有错误,则回滚
return
} err = tx.Commit() //提交事务
if err != nil {
tx.Rollback()
return
}
} func main() {
dns := "root:123456@tcp(127.0.0.1:3306)/golang"
Db, err := sqlx.Connect("mysql", dns) //sqlx.connect连接数据库
if err != nil {
fmt.Printf("open mysql failed, err:%v\n", err)
return
} err = Db.Ping()
if err != nil {
fmt.Printf("ping failed, err:%v\n", err)
return
} fmt.Printf("connect to db succ\n")
Transaction(Db)
}
执行结果:
查看数据库:
六、sql注入分析
A. Select *from user where name = '%s', 构造name="1 ' or 1 = 1 or' "
B. 构造name=123' and (select count(*) from user ) > 10#
C. 构造name=123' union select *from user #
解决办法:避免手动拼接sql, 使用占位符或预处理!
Go语言基础之16--Mysql基本操作的更多相关文章
- Go语言基础之操作MySQL
Go语言操作MySQL MySQL是常用的关系型数据库,本文介绍了Go语言如何操作MySQL数据库. Go操作MySQL 连接 Go语言中的database/sql包提供了保证SQL或类SQL数据库的 ...
- Go语言基础之15--文件基本操作
一.文件读写 1.1 os.File os.File封装所有文件相关操作, 是一个自定义的struct. a. 打开一个文件进行读操作: os.Open(name string) (*File, er ...
- MySQL学习笔记_8_SQL语言基础复习
SQL语言基础复习 一.概述 SQL语句注释方式 1)以"#"开头直到行尾的所有内容都是注释 2)以"--"(--后还有一个空格)开头直到行尾的所有内容都是注释 ...
- Python进阶----数据库的基础,关系型数据库与非关系型数据库(No SQL:not only sql),mysql数据库语言基础(增删改查,权限设定)
day37 一丶Python进阶----数据库的基础,mysql数据库语言基础(增删改查,权限设定) 什么是数据库: 简称:DataBase ---->DB 数据库即存放数据的仓库, ...
- php面试题之三——PHP语言基础(基础部分)
三.PHP语言基础 1. strlen( )与 mb_strlen( )的作用分别是什么(新浪网技术部) strlen和mb_strlen都是用于获取字符串长度. strlen只针对单字节编码字符,也 ...
- D01-R语言基础学习
R语言基础学习——D01 20190410内容纲要: 1.R的下载与安装 2.R包的安装与使用方法 (1)查看已安装的包 (2)查看是否安装过包 (3)安装包 (4)更新包 3.结果的重用 4.R处理 ...
- D12——C语言基础学PYTHON
C语言基础学习PYTHON——基础学习D12 20180912内容纲要: 1.数据库介绍 2.RDMS术语 3.MySQL数据库介绍和基本使用 4.MySQL数据类型 5.MySQL常用命令 6.外键 ...
- D02——C语言基础学PYTHON
C语言基础学习PYTHON——基础学习D02 20180801内容纲要: 1 字符串的系列操作 2 集合 3 文件的读写 4 字符编码转换 5 小结 6 练习:三级菜单(有彩蛋) 1 字符串的系列操 ...
- 单片机教程4.C语言基础以及流水灯的实现
单片机教程4.C语言基础以及流水灯的实现 C语言,没接触过计算机编程语言的人会把它看的很神秘,感觉非常的难,而在我看来,C语言的逻辑和运算,就是小学水平,所以大家不要怕它,我尽可能的从小学数学逻辑方式 ...
- D03-R语言基础学习
R语言基础学习——D03 20190423内容纲要: 1.导入数据 (1)从键盘输入 (2)从文本文件导入 (3)从excel文件导入 2.用户自定义函数 3.R访问MySQL数据库 (1)安装R ...
随机推荐
- maven安装第三方jar包到本地仓库
添加项目依赖的时候,有些jar下载不下来,只有手动下载或安装到本地仓库了 首先下载所需要的jar,放到指定的文件夹 然后执行如下命令: mvn install:install-file -Dfile= ...
- Codeforces 960F 线段树
题意:https://blog.csdn.net/qq_39809664/article/details/79871282 思路:我们考虑LIS的状态转移,对于这个题,假设现在扫描到的边是(u, v, ...
- vue插件开发与发布
vue插件的规范 / plug.js Toast={}Toast.install=function(){ Vue.prototype.$toast=function(){ }} // 导出这个对象 e ...
- iBase4J项目笔记
目录: 1 数据库密码加密 2 service层概述 3 web层概述 4 后端CRUD 4.1 READ 4.2 UPDATE 4.3 CREATE 4.4 DELETE 5 facade层概述 1 ...
- ZROI2018普转提day7t2
传送门 分析 首先我们不难想到我们一定可以将每一个点分开算,然后看这个点被几个矩形包含 于是对于位置为$(i,j)$的点它被包含的次数为$i * (n-i+1) * j * (m-j+1)$ 这个式子 ...
- c++调用shell命令
system()这个函数就不说了,不能读取返回值. #include<cstdio> int main() { FILE *fp; ]={}; fp=popen("ssh roo ...
- Spring-访问静态资源文件的方法
转自: http://blog.163.com/zhangmihuo_2007/blog/static/27011075201453044959574?suggestedreading 如果你的Di ...
- JAVA基础语法动手动脑实践体会
一.运行EnumTest.java程序. public class EnumTest { public static void main(String[] args) { Size s=Size.SM ...
- [转]Apple耳机兼容非Mac设置
转至:https://jingyan.baidu.com/article/6079ad0e99858228ff86db19.html 不兼容情况描述: 听音乐貌似只能听见伴奏的声音 解决方法: 第一种 ...
- 读取XML文档存入泛型List<T>集合中
前一篇博文是<泛型List<T>转存为XML文档> http://www.cnblogs.com/insus/p/3277410.html 把一个List<T>集合 ...