mysql数据库原理及应用 sql语句(表 视图 触发器 增删改查) 函数 并发控制事务和锁 JDBC pymysql

数据库数据定义语句

在这里插入图片描述

建表

1. CREATE TABLE <表名>
(<列名> <数据类型>[ <列级完整性约束条件> ] 
[,<列名> <数据类型>[ <列级完整性约束条件>] ] 
    • … 
[,<表级完整性约束条件> ] );

...
 ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

2. 列级完整性约束条件
* PRIMARY KEY
* UNIQUE
* REFERENCES Course(Cno)

3. 表级完整性约束条件
CONSTRAINT `约束名` +
PRIMARY KEY (Sno,Cno),
FOREIGN KEY (Sno) REFERENCES Student(Sno),
CHECK(Grade<=100 AND Grade>=0)
...
+
ON DELETE RESTRICT ON UPDATE RESTRICT/cascade,


4. 模式与基本表
每一个基本表都属于某一个模式,一个模式包含多个基本表
 定义基本表所属模式:
 方法一:在表名中明显地给出模式名
CREATE TABLE S-T.Student(......); /*模式名为S-T*/
 方法二:在创建模式语句中同时创建表
CREATE SCHEMA S-T AUTHORIZATION WANG
CREATE TABLE Student(......);

5. 修改删除基本表
ALTER ALTER TABLE <表名>
[ ADD <新列名> <数据类型> [ 完整性约束 ] ]
[ DROP [COLUMN]<列名> [CASCADE | RESTRICT ] ]
[ ADD <表级完整性约束名> ]
[ DROP CONSTRAINT <完整性约束名> [CASCADE | RESTRICT ] ]
[ ALTER COLUMN<列名> <数据类型> ];

DROP TABLE <表名>[RESTRICT| CASCADE];

选择

SELECT [ALL | DISTINCT] <目标列表达式>[,<目标列表达式>] …
FROM <表名或视图名>[, <表名或视图名> ] …
[ WHERE <条件表达式> ]
[ GROUP BY <列名1> [ HAVING <条件表达式> ] ]
[ ORDER BY <列名2> [ ASC | DESC ] ];

...
LIMIT 10;
select name as rename
from table1 as t11,table1 as t12,table2 as t2

连接方式

在这里插入图片描述
在这里插入图片描述

常用
SELECT * FORM TABLE_A  A  INNER JOIN TABLE_B B ON A.KEY = B.KEY
SELECT * FORMTABLE_A  A LEFT JOIN TABLE_B B ON A.KEY = B.KEY
SELECT * FROM TABLE_A A FULL OUTER JOIN TABLE_B B ON A.KEY = B.KEY

用户变量

SELECT train.TID
FROM train,(SELECT @tmpday1:=FDay FROM diagnoserecord WHERE diagnoserecord.PCardID=@pcardid1) as tablerename(columnrename)
WHERE  train.SDate BETWEEN  DATE_SUB(@tmpday1 ,INTERVAL 100 day)and '@tmpday1');

where +条件表达式

查询条件 谓 词
比 较    =,>,<,>=,<=,!=,<>,!>,!<;NOT
确定范围 BETWEEN AND,NOT BETWEEN AND
确定集合 IN,NOT IN
字符匹配 LIKE,NOT LIKE
空 值 IS NULL,IS NOT NULL  注意is null 不能写 =null
多重条件(逻辑运算) AND,OR,NOT
ANY或ALL谓词的子查询
EXISTS/NOT EXISTS
where exits(..)

字符匹配
[NOT] LIKE ‘<匹配串>’[ESCAPE‘ <换码字符>’]
百分号% 代表任意长度的字符串
下划线__ 代表任意一个字符
ESCAPE 是将百分号% 或下划线__转回其本意
mysql查询以字符串开头的数据可以有:
0、 Cname LIKE ‘DB\_%i_ _ ’ ESCAPE '\' ;
1、select * from a where a.name like 'H%'
2、select * from a where left(a.name, 1)='H';
mysql查询不以某个字符串开头:
select * from a where left(a.name, 1)<>'H';

聚集函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S4vjWSP9-1598122428644)(2020-08-21-18-14-47.png)]

集合并交查

select ...
union
select...
– 并操作UNION
– 交操作INTERSECT
– 差操作EXCEPT

增删改

插入数据

INSERT INTO <表名> [(<属性列1>[,<属性列2>]…)]
VALUES (<常量1>[,<常量2>]….),(多列逗号分隔)
| SELECT 子查询;

修改数据

UPDATE <表名> 
SET <列名>=<表达式>[, <列名>=<表达式>]…
[WHERE <条件>];

删除数据

DELETE
FROM <表名>
[WHERE <条件>];

mysql常用函数

字符串函数

CANCAT(S1,S2,…Sn) 连接 S1,S2,…Sn 为一个字符串
INSERT(str,x,y,instr) 将字符串 str 从第 x 位置开始,y 个字符长的子串替换为字符串 instr
LOWER(str) 将字符串 str 中所有字符变为小写
UPPER(str) 将字符串 str 中所有字符变为大写
LEFT(str ,x) 返回字符串 str 最左边的 x 个字符
RIGHT(str,x) 返回字符串 str 最右边的 x 个字符
LPAD(str,n ,pad) 用字符串 pad 对 str 最左边进行填充,直到长度为 n 个字符长度
RPAD(str,n,pad) 用字符串 pad 对 str 最右边进行填充,直到长度为 n 个字符长度
LTRIM(str) 去掉字符串 str 左侧的空格
RTRIM(str) 去掉字符串 str 行尾的空格
REPEAT(str,x) 返回 str 重复 x 次的结果
REPLACE(str,a,b) 用字符串 b 替换字符串 str 中所有出现的字符串 a
STRCMP(s1,s2) 比较字符串 s1 和 s2
TRIM(str) 去掉字符串行尾和行头的空格
SUBSTRING(str,x,y) 返回从字符串 str x 位置起 y 个字符长度的字串

数值函数

ABS(x) 返回 x 的绝对值
CEIL(x) 返回大于 x 的最大整数值
FLOOR(x) 返回小于 x 的最大整数值
MOD(x,y) 返回 x/y 的模
RAND() 返回 0 到 1 内的随机值
ROUND(x,y) 返回参数 x 的四舍五入的有 y 位小数的值
TRUNCATE(x,y) 返回数字 x 截断为 y 位小数的结果

时间日期函数

CURDATE() 返回当前日期
CURTIME() 返回当前时间
NOW() 返回当前的日期和时间
UNIX_TIMESTAMP(date) 返回日期 date 的 UNIX 时间戳
FROM_UNIXTIME 返回 UNIX 时间戳的日期值
WEEK(date) 返回日期 date 为一年中的第几周
YEAR(date) 返回日期 date 的年份
HOUR(time) 返回 time 的小时值
MINUTE(time) 返回 time 的分钟值
MONTHNAME(date) 返回 date 的月份名
DATE_FORMAT(date,fmt) 返回按字符串 fmt 格式化日期 date 值
DATE_ADD(date,INTERVAL expr type) 返回一个日期或时间值加上一个时间间隔的时间值
DATEDIFF(expr,expr2) 返回起始时间 expr 和结束时间 expr2 之间的天数

常用dateformate 中的格式

'%Y,%m,%d'
%S,%s 两位数字形式的秒(00,01,...,59)
%i 两位数字形式的分(00,01,...,59)
%H 两位数字形式的小时,24 小时(00,01,...,23)
%h,%I 两位数字形式的小时,12 小时(01,02,...,12)
%k 数字形式的小时,24 小时(0,1,...,23)
%l 数字形式的小时,12 小时(1,2,...,12)
%T 24 小时的时间形式(hh:mm:ss)
%r 12 小时的时间形式(hh:mm:ssAM 或 hh:mm:ssPM)
%p AM 或 PM
%W 一周中每一天的名称(Sunday,Monday,...,Saturday)
%a 一周中每一天名称的缩写(Sun,Mon,...,Sat)
%d 两位数字表示月中的天数(00,01,...,31)
%e 数字形式表示月中的天数(1,2,...,31)
%D 英文后缀表示月中的天数(1st,2nd,3rd,...)
%w 以数字形式表示周中的天数(0=Sunday,1=Monday,...,6=Saturday)
%j 以 3 位数字表示年中的天数(001,002,...,366)
%U 周(0,1,52),其中 Sunday 为周中的第一天
%u 周(0,1,52),其中 Monday 为周中的第一天
%M 月名(January,February,...,December)
90
%b 缩写的月名(January,February,...,December)
%m 两位数字表示的月份(01,02,...,12)
%c 数字表示的月份(1,2,...,12)
%Y 4 位数字表示的年份
%y 两位数字表示的年份
%% 直接值“%”

dateadd datediff中

HOUR 小时 hh
MINUTE 分 mm
SECOND 秒 ss
YEAR 年 YY
MONTH 月 MM
DAY 日 DD
YEAR_MONTH 年和月 YY-MM
DAY_HOUR 日和小时 DD hh
DAY_MINUTE 日和分钟 DD hh:mm
DAY_ SECOND 日和秒 DD hh:mm:ss
HOUR_MINUTE 小时和分 hh:mm
HOUR_SECOND 小时和秒 hh:ss
MINUTE_SECOND 分钟和秒 mm:ss

流程函数

IF(value,t f) 如果 value 是真,返回 t;否则返回 f
IFNULL(value1,value2) 如果 value1 不为空返回 value1,否则返回 value2
CASE WHEN [value1] 
THEN[result1]…ELSE[default]END
如果 value1 是真,返回 result1,否则返回 default
CASE [expr] WHEN [value1] 
THEN[result1]…ELSE[default]END
如果 expr 等于 value1,返回 result1,否则返回 default

其它函数

DATABASE() 返回当前数据库名
VERSION() 返回当前数据库版本
USER() 返回当前登录用户名
INET_ATON(IP) 返回 IP 地址的数字表示
INET_NTOA(num) 返回数字代表的 IP 地址
PASSWORD(str) 返回字符串 str 的加密版本
MD5() 返回字符串 str 的 MD5 值

视图

CREATE VIEW <视图名> [(<列名> [,<列名>]…)]
AS <子查询>
[WITH CHECK OPTION];
可选check option表示创建后 增改仍需满足where限制条件
可多表,可带avg 等表达式

DROP VIEW <视图名> [CASCADE];使用CASCADE级联删除语句,把
该视图和由它导出的所有视图一起删除

增删改同表操作
视图的更新最终要转换为对基本表的更新。
为防止用户通过视图更新,对不属于视图范围内的基本表数据进行更新操作,
在定义视图时加上WITH CHECK OPTION操作

SHOW TABLE STATUS [FROM db_name] [LIKE 'pattern']查看视图

安全性

用户表示 存取控制 视图 审计 加密 这里主要存取控制中自主存取

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vYGayMKU-1598122428657)(2020-08-22-17-48-20.png)]

GRANT <权限>[,<权限>]...
[ON <对象类型> <对象名>]
TO <用户>[,<用户>]...
[WITH GRANT OPTION];

GRANT UPDATE(Sno), SELECT
ON TABLE Student TO U4,u2;

REVOKE <权限>[,<权限>]...
[ON <对象类型> <对象名>]
FROM <用户>[,<用户>]...[CASCADE | RESTRICT];

也可以先给角色权限,再把角色给用户或角色
CREATE ROLE CREATE ROLE <角色名> <角色名> 

GRANT <权限>[,<权限>]… 
ON <对象类型>对象名
TO <角色>[,<角色>]…

REVOKE <权限>[,<权限>]…
ON <对象类型> <对象名>
FROM <角色>[,<角色>]…

GRANT <角色1>[,<角色2>]…
TO <角色3>[,<用户1>]… 
[WITH ADMIN OPTION]

FLUSH PRIVILEGES; 刷新权限

强制存取控制主要 向上写 向下读

触发器

eg:

DROP TRIGGER IF EXISTS TrigerBuy;
CREATE TRIGGER TrigerBuy
AFTER UPDATE ON buy
FOR EACH ROW
BEGIN
	IF  old.bstatus=0 AND new.bstatus=1  -- 审核通过
	THEN 
		set @lacknum=(SELECT IFNULL(lnum,0) FROM lack WHERE lno=new.bgno); -- 查缺货数量,不缺为0
		if @lacknum=0 
				 then UPDATE inventory set inum=inum+new.bnum WHERE ino=new.bgno;  -- 不缺货 增库存
		else set @changenum=new.bnum-@lacknum;
				 if @changenum>=0  -- 缺货 新货凑够发货 更新库存,删缺货表记录,缺货单状态改为1完成
						then 
									UPDATE inventory set inum=@changenum WHERE ino=new.bgno;
								  UPDATE sell set sstatus=1 WHERE sgno=new.bgno and sstatus=2;
								  DELETE FROM lack WHERE lno=new.bgno;
				 else UPDATE lack set lnum=-@changenum WHERE lno=new.bgno; -- 缺货还不够发货,增库存 减缺货量
						  UPDATE inventory set inum=inum+new.bnum WHERE ino=new.bgno;
				 end if;
		end if;	
	END IF;
END;	
CREATE TRIGGER <触发器名> 
{ BEFORE | AFTER } <触发事件>
ON <表名>
FOR EACH { ROW | STATEMENT } [WHEN <触发条件>]
<触发动作体>

DROP TRIGGER <触发器名> ON <表名>;

触发事件INSERT、DELETE、UPDATE  mysql只能选一,且不能
for each statement(只执行一次,for each row 多表所有行满足就执行)

存储过程

优化

自然连接算法:

嵌套循环
排序合并 有序表,性能高
索引连接 参与连接的表的连接属性上存在索引
哈希连接 连接属性哈希分桶。内存限制了不能太大

代数优化:高效表达式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-813paZB4-1598122428660)(2020-08-22-18-13-18.png)]

物理有优化:执行策略

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JOy7IJ6u-1598122428663)(2020-08-22-18-14-56.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qj7icJi7-1598122428666)(2020-08-22-18-15-47.png)]

基于代价优化:统计表信息,估计中间结果集大小,io代价。略

并发控制 锁 事务 故障恢复

A—— 原子性(Atomicity) C —— 一致性(Consistency)
I —— 隔离性(Isolation) D —— 持久性(Durability)

隔离级别

  1. Lost Update

    丢失更新:提交或者回滚一个事务,把其它事务已提交的更新的数据覆盖了。
    If the two transactions want to change the same columns, the second transaction will overwrite the first one, therefore losing the first transaction update.

  2. READ UNCOMMITED(未提交读)

    事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也成为脏读(Dirty Read)。很少使用READ UNCOMMITED.
    某事务读取了其他未提交事务更新的数据,随后未提交事务采取了撤消
    (Rollback)动作,导致该数据无效(“脏”数据)

  3. READ COMMITED (提交读,不可重复读)

    大多数数据库系统的默认隔离级别都是(但是MYSQL不是)一个事务从开始到提交之前,所做的任何修改对其他事务都 是不可见的。这个级别有时候也叫做不可重复的(nonerepeatable read),一事务读取数据后,另一并发事务增删改,因为两次执行同样的查询,可能会得到不一样的结果。

  4. REPEATABLE READ (可重复读)

    解决了脏读问题。该级别保证了在同一个事务中多次读取同样的记录的结果是一致的。但是可重复读隔离级别还是无法解决另一个幻读 (PhantomRead)的问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读 取该范围的记录时,会产生幻行(Phantom Row)。InnoDB和XtraDB 存储引擎通过多版并发控制(MVCC ,Multivesion Concurrency Control )解决了幻读问题。

  5. SERIALIZABLE(可串行化) 可重复读是Mysql 默认的事务隔离级别。

    SERIALIZABLE是最高的隔离级别。它通过强制事务串行,避免了前面说的幻读问题。简单的来说,SERIALIZABLE会在读的每一行数据上 都加上锁,所以可能导致大量的超时和锁征用问题。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况,才可考 虑用该级别。性能差


IsolationLevel	脏读(Dirty Read)不可重复读(Non Repeatable Read)	幻读(Phantom Read)
Read Uncommitted	Yes	Yes	Yes
Read Committed	    -	Yes	Yes
Repeatable Read 	-	-	Yes
Serializable        -	-	-

处理系统故障 ROLLBACK redo undo
检查点

基本锁:排它锁(exclusive locks,简称X锁)和共享锁
(share locks,简称S锁)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ODIRLf31-1598122428668)(2020-08-23-02-32-35.png)]

封锁粒度

关系数据库理论

结构设计

备份 引擎

java JDBC

最简单使用jdbc的示例步骤

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-niHDLBfZ-1598122428670)(2020-08-22-22-02-26.png)]

  1. 加载驱动程序:Class.forName(“JDBCDriverClass的完全限定名”); //反射

  2. 建立连接:使用DriverManager类的静态方法getConnectionConnection connection=DriverManager.getConnection(databaseURL);

  3. 创建语句:Statement statement=connection.createStatement();

  4. 执行语句:statement.execute(“SQL语句”);//增删改操作ResultSet resultSet=statement.executeQuery(“SQL语句”);//查询操作

  5. 处理ResultSet:遍历ResultSet的每条记录while (resultSet.next()) resultSet.getString(n);
    ResultSet获取列时,索引从1开始

    boolean next()
    throws SQLException 将结果集游标往下移动一行,这时ResultSet引用指向的就是当前游标(遍历到的当前记录)。如果已经到达结果集最后,将会返回false,有可能抛异常,必须捕捉
    X getX(String columnName或int columnIndex)
    throws SQLException 获得当前记录某个字段的值,X是指具体的数据类型,视数据库表中字段的具体情况而定,并且每个数据类型都有两种重载方法,一种是以字段名称为参数,另一种是以字段索引为参数(字段索引从1开始),有可能抛异常,必须捕捉

    JDBC查询的返回值总是ResultSet,即使我们写这样的聚合查询SELECT SUM(score) FROM …,也需要按结果集读取:
    ResultSet rs = …
    if (rs.next()) {
    double sum = rs.getDouble(1);
    }

  6. 关闭资源

jdbc中SQL语句拼接java变量

使用“+ +”
String sql = "select * from user where username='" + username + "' and password ='" + password + "' ";

sql注入举例

用户输入账户名 bob 密码 1234 然后查询自己信息
SELECT * FROM user WHERE login='bob' AND pass='1234'
如果用户输入 账户名 “bob' OR pass=” 密码 " OR pass='" 用以上拼接SQL语句后:
SELECT * FROM user WHERE login='bob' OR pass=' AND pass=' OR pass=''
成功不输入密码查询了。

插入自增表时获取自增主键

在创建PreparedStatement的时候,指定一个RETURN_GENERATED_KEYS标志位,表示JDBC驱动必须返回插入的自增主键,调用prepareStatement()时,第二个参数必须传入常量Statement.RETURN_GENERATED_KEYS,执行executeUpdate()方法后,必须调用getGeneratedKeys()获取一个ResultSet对象,这个对象包含了数据库自动生成的主键的值,读取该对象的每一行来获取自增主键的值。如果一次插入多条记录,那么这个ResultSet对象就会有多行返回值。如果插入时有多列自增,那么ResultSet对象的每一行都会对应多个自增值
eg:
try (Connection conn = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD)) {
    try (PreparedStatement ps = conn.prepareStatement(
            "INSERT INTO students (grade, name, gender) VALUES (?,?,?)",
            Statement.RETURN_GENERATED_KEYS)) {
        ps.setObject(1, 1); // grade
        ps.setObject(2, "Bob"); // name
        ps.setObject(3, "M"); // gender
        int n = ps.executeUpdate(); // 1
        try (ResultSet rs = ps.getGeneratedKeys()) {
            if (rs.next()) {
                long id = rs.getLong(1); // 注意:索引从1开始
            }
        }
    }
}


PreparedStatement 参数化的SQL语句 重复执行高效率 避免SQL注入 +batch

PreparedStatement preparedStatement=connection.prepareStatement( "insert into Student (firstName, mi, lastName)  values (?, ?, ?)"); 
在PreparedStatement对象中设置参数:
// setX(int parameterIndex,X value);   也可以不具体类型 serObject
parameterIndex是语句中参数的下标,从1开始preparedStatement.setString(1,"Jack”);
preparedStatement.setString(2,”A”);
preparedStatement.setString(3,"Ryan");
执行    
preparedStatement.executeUpdate();executeUpdate返回执行操作后受影响的记录数

方法有execute、executeUpdate和executeQuery ecuteBatch

batch批量处理

try (PreparedStatement ps = conn.prepareStatement("INSERT INTO students (name, gender, grade, score) VALUES (?, ?, ?, ?)")) {
    // 对同一个PreparedStatement反复设置参数并调用addBatch():
    for (Student s : students) {
        ps.setString(1, s.name);
        ps.setBoolean(2, s.gender);
        ps.setInt(3, s.grade);
        ps.setInt(4, s.score);
        ps.addBatch(); // 添加到batch
    }
    // 执行batch:
    int[] ns = ps.executeBatch();
    for (int n : ns) {
        System.out.println(n + " inserted."); // batch中每个SQL执行的结果数量
    }
}

CallableStatement 执行SQL存储过程

例子

public static void main(String[] args){
        String url = "jdbc:mysql://localhost:3306/javacourse";
        Connection conn = ConnectionFactory.create(url,"root","root");
        if(conn != null){
            try{
                //Create a callable statement
                CallableStatement stmt = conn.prepareCall(“{? = call studentFound(?,?)}”); //SQL转义语法,它通知驱动程序其中的代码应该被不同处理,调用存储过程studentFound
                Scanner input = new Scanner(System.in);
                System.out.print("Input first name:"); String firstName = input.nextLine();
                System.out.print("Input last name:"); String lastName = input.nextLine();
                stmt.setString(2, firstName);       //设置第一个输入参数(第2个问号),注意=左边的?序号为1
                stmt.setString(3, lastName);        //设置第二个输入参数(第3个问号),注意参数序号
                stmt.registerOutParameter(1, Types.INTEGER); //设置第一个参数(第一个?)的返回值类型
                stmt.executeUpdate();	 //执行存储过程
                int matches = stmt.getInt(1); 	//获取返回值,因为这里的返回内容不是记录,是标量(scalar),理解为只有一个字段,序号为1
                System.out.println(matches + " records matched");
                conn.close();
            } catch (SQLException e) {e.printStackTrace(); }
        }
}

CallableStatement对象中设置参数:

IN参数:
callableStatement.setX(parameterIndex, ...); //设置输入值
OUT参数:
    // registerOutParameter方法注册输出值的类型
callableStatement.registerOutParameter(parameterIndex, java.sql.Types.TINYINT); 		
callableStatement.executeQuery(); 
int x = callableStatement.getByte(parameterIndex); //获取OUT参数值
IN OUT参数:
callableStatement.setX(parameterIndex,  ...);	//设置输入值
// registerOutParameter方法注册输出值的类型		
callableStatement.registerOutParameter(n3, java.sql.Types.TINYINT); 
callableStatement.executeUpdate(); 
byte x = callableStatement.getByte(parameterIndex); //获取OUT参数值

获取元数据

Connection对象的getMetaData方法获得(数据库URL、用户名、JDBC驱动程序名称等)
ResultSet对象的getMetaData方法于获取(表的列数、列名、列类型等)

事务

Connection conn = openConnection();
try {
    // 关闭自动提交:获取到Connection连接后,总是处于“自动提交”模式,也就是默认一条语句一次提交
    conn.setAutoCommit(false);
    // 执行多条SQL语句:
    insert(); update(); delete();
    // 提交事务:
    conn.commit();
} catch (SQLException e) {
    // 回滚事务:
    conn.rollback();
} finally {
    conn.setAutoCommit(true);//把Connection对象的状态恢复到初始值
    conn.close();
}

隔离级别

参见 事务 故障恢复
MySQL的默认隔离级别是REPEATABLE READ
// 设定隔离级别为READ COMMITTED:
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

连接池

hikariCP

python pymysql库

连接数据库 执行操作

    conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        db='my_db',
        passwd='123123',
        charset='utf8'
    )
import pymysql
db = pymysql.connect('localhost', 'root', '123456', 'conv19_datas')
# return pymysql.connections.Connection
cursor = db.cursor()
cursor.execute('show tables;')
cursor.executemany(sql,data1) 
data = cursor.fetchone() # 获取一条记录
#'fetchall', 'fetchmany', 'fetchone'
db.close()

事务提交回滚

try:
    with conn.cursor() as cursor:
        sql="insert into sns_insight_log(LOG_DATE,BIZ_ID,MEDIA_TYPE,ITEM_NAME,DEC_VALUE,UPD_DATE) values(%s,%s,%s,%s,%s,%s)"
        cursor.executemany(sql,data)
        conn.commit()   #不带这个可能出错
except:
    conn.rollback()
finally:
    conn.close()

简单数据库操作举例

create database `my_db` default character set utf8 collate utf8_general_ci
'''
create table user (
    id int(16) AUTO_INCREMENT PRIMARY KEY,
    username varchar(32) not null,
    password varchar(32) not null
)
    ENGINE = MyISAM'''
insert into user (username, password) values ('teble', 'teble')
select id, username, password from user ORDER BY id DESC
update user set username = 'root', password = 'root' WHERE username = 'teble0'
cursor.execute("select Cname from Teacher LEFT JOIN  Course on Teacher.Tno=Course.Tno where Tname=%s",tname)
cs.execute("update Course set Cname=%s where Cno=%s ;",[a,b])
delete from user where username = 'teble1'

参数化接口

cur.execute(“SELECT * FROM %s WHERE city = %s”,[s1,s2])

cur.execute(“SELECT * FROM %s WHERE city = %s”,data)
批量data是嵌套的列表或元组 [(),()] [[],[]]都行

cursor.execute('insert into nudt(year,province) values (%s,"%s")' % (year,province))

sql = “INSERT INTO user VALUES(%(username)s, %(password)s, %(email)s)”
value = {“username”:zhangsan,
“password”:123456,
“email”:123456@ouvps.com}
cur.execute(sql, value)

SQLAlchemy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值