这是我参与更文挑战的第5天,活动详情查看:更文挑战
一、 JDBC
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try{
//1.加载驱动到JVM
Class.forName("com.mysql.jdbc.Driver");
//2.创建数据库连接
Connection conn = DriverManage.getConnection(URL,USERNAME,PWD);
//3.创建 prepareStatement 目的是实现增删改查
String sql = "select user_id,user_name,credits from t_user where credits > ?";
st = conn.prepareStatement(sql);//这里使用PreparedStatement
st.setInt(3);
//4.向数据库发送SQL命令
rs=st.executeQuery();
//5.使用ResultSet处理数据库的返回结果
while (rs.next()) {
System.out.println(rs.getLong("user_id") + " "+rs.getString("user_name") + " " + rs.getString("credits"));
}
} catch (Exception e){
} finally {
//6.关闭资源
try {
rs.close();
st.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
二、SQL优化
- 1.利用关联查询,连接等,避免子查询嵌套
- 2.增加适当冗余的字段,提高查询性能(必须考虑数据的一致性)
- -- 用表空间换取查询时间 --(反数据库范式设计)
- 遵循:
- 不是频繁修改的字段
- 不是varchar超长的字段
- 不是唯一索引的字段
- 3.满足数据库三大范式
- 第一范式:表的每一列都是不可分割的原子数据项
- 第二范式:表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)
- 第三范式:确保数据表中的每一列数据都和主键直接相关,而不能间接相关
三、索引优化
- 单张表索引数量不能超过5个
- mysql优化器在选择如何优化查询时,会对每一个可能用到的索引进行评估,生成最优的执行计划,索引太多会在这里浪费大量时间。
- 保证索引正常可用
四、如何防止sql注入
1. 白黑名单
- 避免 sql injection攻击的传统方法之一
- 把它作为一个 合法性检查 问题来处理
- 只接受白名单中的字符,避免在黑名单中的恶意数据
2. sql预编译
- sql预编译
prepareStatement setParamter方式- 静态SQL执行 --
statement - 动态SQL执行 --
prepareStatement - 库存储过程 --
CallableStatement - sql预编译?
- 一条sql语句的执行需要经过语义解析,制定执行计划,执行并返回结果
- 程序在第一次操作数据库前,sql语句已经被数据库进行了 语义解析、制定了执行计划
- 当运行时,直接执行编译后的sql 直接执行 执行计划 不会再进行语义解析, 执行参数的替换
- 静态SQL执行 --
- mybatis 如何防止 注入?
- 参数传递 增加
jdbcType--- 也是在进行预编译
- 参数传递 增加
- ‘#’和‘$’的区别
#{} 参数占位符 -- sql 预编译 变量替换后,#{} 对应的变量自动加上单引号 '' 能防止sql 注入
${} 字符串替换 -- sql 拼接 变量替换后,${} 对应的变量不会加上单引号 '' 不能防止sql 注入
3. java代码
- 不要字符串拼接
- 使用正则表达式 过滤传入的参数