黑马程序员技术交流社区
标题:
【石家庄校区】个人笔记-高级SQL-JDBC-SQL注入
[打印本页]
作者:
在路上的Mr.Li
时间:
2018-1-11 15:53
标题:
【石家庄校区】个人笔记-高级SQL-JDBC-SQL注入
本帖最后由 小石姐姐 于 2018-1-12 11:10 编辑
【石家庄校区】个人笔记-高级SQL-JDBC-SQL注入
第三阶段主要内容
- 主要内容
- day01:MySQL数据库 SQL语句
- day02:高级SQL-JDBC-SQL注入
- day03:加载本地配置
- =============================
- day04:DBCP连接池
- day05:管家婆案例A
- day06:管家婆案例B
第2天笔记
一 重点
1 在SQLyog中录入代码:Tab键可以自动补全.
2 保存代码:cltrl + s
3 导入代码:cltrl + o
4 存储字符串的类型: varchar(必须有字数) char(必须有字数)
5 双击表是输入表名
6 右键 => 打开表 F11
7 注释选中内容 ctrl+shift+c
8 取消注释内容 ctrl+shift+r
9 替换:cltrl + h
10 # DISTINCT去重,按照多列的组合,而不是单列
SELECT DISTINCT 列名1, 列名2 FROM 表名;
11 BETWEEN...AND...: 在一个范围内(包含头和尾),
12 IN (): 在列表中, 满足列表中一个即可
13 IS NULL: 是空
14 LIKE 通配符: 模糊查询
通配符种类
%: 一个百分号可以表示任意个字符. 比如王%, 王大锤, 王五
_: 一个下划线可以表示一个字符. 比如王_, 只能匹配王五
15 逻辑运算符
AND: 与. 两边条件同时成立才成立
OR: 或. 两边条件只要有一个成立就成立
NOT: 非, 取相反结果
NOT BETWEEN ... AND ...: 不在范围内
NOT IN: 不在列表中
NOT LIKE: 不匹配
IS NOT NULL: 非空
日期也是可以比较的
16 select * from zhangwu where zname like '%支出%';#模糊查询 %:多个字符 _:一个字符
二 代码
- 1 排序格式:默认升序: SELECT 列名1, 列名2 FROM 表名 ORDER BY 列名;
- 2 指定顺序: SELECT 列名1, 列名2 FROM 表名 ORDER BY 列名 ASC|DESC; A-Z
- 3 使用WHERE条件: SELECT 列名1, 列名2 FROM 表名 WHERE 条件 ORDER BY 列名 ASC|DESC;
ASC: 默认. 升序. 1~9, A~Z
DESC: 降序. 9~1, Z~A
- 4 WHERE在前, ORDER BY在后, 否则报错.因为先拿到数据再排序.
- 5 排序可以按照多列, 如先按a列降序, 如果a列中有相同的值, 则按b列降序
SELECT * FROM table where 条件 ORDER BY a DESC, b DESC;
一般排序是数字,英文,日期,一般不对中文进行排序
- 6 聚合函数
格式:
SELECT 函数(列) FROM 表名 ...;
常用的5个聚合函数
COUNT(列名): 计算指定列的记录行数.
注意: 不会计算NULL值
SUM(列名): 计算指定列的数值总和
如果数据类型不是数值, 则结果为: 0
MAX(列名): 获取指定列的数值中的最大值
MIN(列名): 获取指定列的数值中的最小值
AVG(列名): 计算指定列的数值中的平均值
如果数据类型不是数值, 则结果为: 0
NULL与任何数的运算结果都是NULL: SELECT (NULL + 10)结果为NULL
- 7 分组查询(把值相同的合并到一起)
GROUP BY 列名 HAVING 条件, 是SELECT的子句, 用于将查询出的结果归类分组显示
格式:SELECT 列1, 列2 FROM 表名 [WHERE 条件] GROUP BY 列名 HAVING 条件;
HAVING关键字的作用: 对查询结果进行分组显示后, 再次按条件过滤
必须跟随聚合函数
被分组的列要在select后面
- 总结_单表查询
-- CREATE DATABASE mybase;#创建数据库
-- USE mybase;#选择要操作的数据库
-- CREATE TABLE users(#创建表格
-- uid INT PRIMARY KEY AUTO_INCREMENT,#主键 自增
-- usersuname VARCHAR(20),
-- uaddress VARCHAR(200)
-- );
-- DROP DATABASE users;#删除数据库
-- INSERT INTO users VALUES ('3','老张','建安大街')#添加数据[不指定列名, 给所有列添加值]
-- INSERT INTO users(usersuname,uaddress) VALUES ('老张1','建安大街'),('老张2','建安大街'),('老张3','建安大街')#添加数据[常见方式,添加多个]
-- UPDATE users SET usersuname = '小陈',uaddress = '棉二生活区' WHERE uid = 2;#修改数据 不等于<> 与或非 and or not
-- DELETE FROM users WHERE uid = 2#删除数据[自增计数器会继续]
-- TRUNCATE TABLE users WHERE uid = 2#删除表再重建[自增计数器重置]
-- SELECT 列名1, 列名2 FROM 表名;# 查询指定字段
-- SELECT * FROM 表名;# 查询所有字段
-- SELECT DISTINCT 列名1, 列名2 FROM 表名;# DISTINCT去重,按照多列的组合,而不是单列
-- SELECT 列名 AS 别名 FROM 表名;# AS给字段取别名观察查询结果的字段名是否变化)
-- SELECT zmoney, zmoney+1000 FROM zhangwu;# 给每条zmoney字段都增加1000(观察zmoney和zmoney+1000的区别)
-- SELECT * FROM zhangwu WHERE zname = '吃饭支出';# 查询指定条件的数据
-- SELECT * FROM zhangwu WHERE zname LIKE '%支出%' ORDER BY zmoney DESC;#模糊查询 %:多个字符 _:一个字符 ;降序排序 DESC;升序排序 ASC
-- SELECT AVG(zmoney),SUM(zmoney) from zhangwu;#调用平均数函数,COUNT,SUM,AVG MAX,MIN
-- SELECT COUNT(*)AS'count1' from zhangwu;#调用行数函数并使用别名
-- SELECT lie1, AVG(lie2)AS'lie_AVG' FROM biao1 WHERE tiaojian1 GROUP BY lie2 HAVING tiaojian2 ORDER BY lie_AVG DESC;#按条件1过滤,然后分组,最后按照条件2过滤,再最后排序
- 8 HAVING和WHERE的区别
过滤时机不同
WHERE是在分组前对结果进行过滤
HAVING是在分组后对结果进行再次过滤
是否可跟随聚合函数不同
WHERE后不可使用聚合函数
HAVING后可以使用聚合函数
条件可用字段不同
HAVING条件中的字段必须是SELECT条件或GROUP BY条件中使用过的字段
WHERE条件中可以使用表的所有字段
- 9 JDBC(J=>java DB=>数据库database C=>连接Connection)
- JDBC使用的六个步骤: 注册驱动=>获得连接=>创建执行=>执行SQL=>处理结果=>释放资源(不能在工作中使用,因为会遭到注入攻击)
- 注意:所有导的包都是java.sql.*!!!!
- Statement类
ResultSet executeQuery(String sql): 执行SELECT查询, 返回查询结果到ResultSet对象中.
ResultSet接口
boolean next(): 将结果集的指针向下移动一行, 并返回是否还有下一条记录
注意: 没有调用该方法之前, ResultSet的光标在第一条记录之前, 只有调用一次next方法后, 指针才指向第一条记录
int getInt(int column): 获取第column列的int类型的数据
int getInt(String columnName): 获取指定列名的int类型的数据
String getString(int column): 获取第column列的String类型数据
String getString(String columnName): 获取指定列名的String类型的数据
Object getObject(String columnName): 获取指定列名的任何类型数据
void close(): 释放结果集资源
- PreparedStatement接口
- 防止注入攻击 (注册驱动=>获得连接=>创建执行=>执行SQL=>处理结果=>释放资源(以后使用此方法))
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");//源码中的静态代码块中实现了注册,所以使用反射技术,获取字节码对象即可,记住"com.mysql.jdbc.Driver",mysql.com是官网,jdbc是项目,Driver是类名(驱动)
// 2. 获取连接对象
String url = "jdbc:mysql://localhost:3306/day02_04"; // 默认使用localhost:3306
//记住格式:"jdbc:mysql://"+ip+":3306/"+数据表名称
//ip => 127.0.0.1 localhost CWP 实际的IP
String username = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url, username, password);
// 3. 获取预编译的执行平台
String sql = "SELECT * FROM users WHERE uname = ? AND upwd = ?;";//使用占位符?代替参数!!!!!!
PreparedStatement preparedStatement = connection.prepareStatement(sql);
// 4. 设置参数并执行语句
preparedStatement.setObject(2, "1' OR '1=1"); // 尝试注入
ResultSet resultSet = preparedStatement.executeQuery();
// 5. 处理结果
System.out.println("用户名\t密码");
while (resultSet.next()) {
System.out.println(resultSet.getString("uname") + "\t" + resultSet.getString("upwd"));// getObject或者getString可以代替所有
}
// 6. 释放资源
resultSet.close();
preparedStatement.close();
connection.close();
- 修改记录
// 3. 获取预编译的执行平台
String sql = "UPDATE sort SET sname = ?, sprice = ? WHERE sid = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
// 设置修改参数
preparedStatement.setObject(1, "汽车用品");
// 执行语句
int rows = preparedStatement.executeUpdate();
System.out.println(rows);
// 释放资源
preparedStatement.close();
connection.close();
- 执行查询
// 3. 获取预编译的执行平台
String sql = "SELECT * FROM sort;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.println(
resultSet.getString("sid") + "\t"
+ resultSet.getString("sname") + "\t"
+ resultSet.getString("sprice") + "\t"
+ resultSet.getString("sdesc")
);
}
// 释放资源
preparedStatement.close();
connection.close();
作者:
wheat
时间:
2018-1-11 21:59
不错哦哦
作者:
李冬
时间:
2018-1-15 09:43
不明觉厉
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2