一,JDBC
–1,代码
package cn.tedu;
import java.sql.*;
import java.util.Scanner;
//测试 JDBC
//JDBC用来把java程序和数据库连接起来,目的是通过java代码操作数据库
public class TestJdbc {
public static void main(String[] args) throws Exception {
// method();//普通方式
// method2();//暴露SQL注入问题
method3();//解决SQL注入问题
}
//需求:按照 用户名 和 密码 查询用户信息
private static void method3() throws Exception{
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
String url="jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf8";
String name="root";
String pwd="root";
Connection conn = DriverManager.getConnection(url,name,pwd);
//获取传输器Statement,执行SQL
// Statement st = conn.createStatement();//SQL注入攻击问题
// String sql = "select * from user where name='"+a+"' and pwd='"+b+"'";
//获取传输器PrepareStatement,执行SQL
//?叫做占位符,PreparedStatement只把SQL骨架发送给数据库
String sql = "select * from user where name=? and pwd=?";
PreparedStatement ps = conn.prepareStatement(sql);
//给SQL设置参数
ps.setString(1,"jack");//第一个?设置参数
ps.setString(2,"123");//第二个?设置参数
//执行SQL
ResultSet rs = ps.executeQuery();
//解析结果集
while(rs.next()){
for (int i = 1; i <= 3 ; i++) {
//按照索引查
System.out.println(rs.getString(i));
}
}
//释放资源
rs.close();
ps.close();
conn.close();
}
//暴露SQL注入问题--发生了SQL拼接
//需求:按照 用户名 和 密码 查询用户信息
private static void method2() throws Exception {
//中文查不出来数据:
//String url="jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf8";
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
String url="jdbc:mysql://localhost:3306/jdbctest";
String name="root";
String pwd="root";
Connection conn = DriverManager.getConnection(url,name,pwd);
//获取传输器Statement,执行SQL
Statement st = conn.createStatement();
//TODO 测试SQL注入攻击问题
//是指当用户只输入数据时,恶意包含了特殊的SQL语句,改变了SQL语义
//导致只需要名字不需要密码也可以查看所有数据(数据泄露)
//名字输入后面两种值,都会产生SQL攻击问题: jack'# 或者 jack' or '1=1
String a = new Scanner(System.in).nextLine();
String b = new Scanner(System.in).nextLine();
String sql = "select * from user where name='"+a+"' and pwd='"+b+"'";
//执行SQL
ResultSet rs = st.executeQuery(sql);
//解析结果集
while(rs.next()){
for (int i = 1; i <= 3 ; i++) {
//按照索引查
System.out.println(rs.getString(i));
}
}
//释放资源
rs.close();
st.close();
conn.close();
}
//使用JDBC查询user表的数据
private static void method() throws Exception {
//1,注册驱动(jar包)
Class.forName("com.mysql.jdbc.Driver");
//2,连接数据库
//getConnection(1,2,3)-1是要连接哪个数据-2是用户名-3是密码
Connection con = DriverManager.getConnection(
// "协议//服务器的名字:数据库的端口号/数据库名",
// "jdbc:mysql://localhost:3306/jdbctest",
"jdbc:mysql:///jdbctest",
//url简写(使用本机使用默认的端口号)
"root","root");
//3,获取传输器Statement
Statement st = con.createStatement();
//4,执行SQL
String sql = "select * from user";
ResultSet rs = st.executeQuery(sql);
//5,解析结果集
while(rs.next()){ //next()判断有数据吗
//有数据就一个一个解析id/name/pwd
for (int i = 1; i <= 3; i++) {
System.out.println( rs.getString(i) );//按索引查;
}
String id2 = rs.getString("id");//按索引查
String name2 = rs.getString("name");//按索引查
String pwd2 = rs.getString("pwd");//按索引查
System.out.println(id2+name2+pwd2);
}
//6,释放资源
rs.close();
st.close();
con.close();
}
}
--2,工具类
package cn.tedu;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBCUtils {
/**
* 获取 数据库的连接
* @return Connection
* @throws Exception
*/
public static Connection getConnection() throws Exception{
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
String url="jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf8";
String name="root";
String pwd="root";
Connection conn = DriverManager.getConnection(url,name,pwd);
return conn;
}
/**
* 关闭JDBC的资源
* @param rs 结果集
* @param ps 传输器
* @param conn 连接
*/
public static void close(ResultSet rs, PreparedStatement ps,Connection conn){
if(rs != null){//为了防止空指针异常
try{
rs.close();
}catch (Exception e){
e.printStackTrace();
}finally { //为了close时又异常
rs = null;
}
}
if(ps != null){//为了防止空指针异常
try{
ps.close();
}catch (Exception e){
e.printStackTrace();
}finally { //为了close时又异常
ps = null;
}
}
if(conn != null){//为了防止空指针异常
try{
conn.close();
}catch (Exception e){
e.printStackTrace();
}finally { //为了close时又异常
conn = null;
}
}
}
}
--3,改造代码
package cn.tedu;
import java.sql.*;
import java.util.Scanner;
//测试 JDBC
//JDBC用来把java程序和数据库连接起来,目的是通过java代码操作数据库
public class TestJdbc {
public static void main(String[] args) throws Exception {
// method();//普通方式
// method2();//暴露SQL注入问题
method3();//解决SQL注入问题
}
//需求:按照 用户名 和 密码 查询用户信息
private static void method3(){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//TODO 改造 调用工具类,获取和数据库的连接
conn = JDBCUtils.getConnection();
//获取传输器Statement,执行SQL
// Statement st = conn.createStatement();//SQL注入攻击问题
// String sql = "select * from user where name='"+a+"' and pwd='"+b+"'";
//获取传输器PrepareStatement,执行SQL
//?叫做占位符,PreparedStatement只把SQL骨架发送给数据库
String sql = "select * from user where name=? and pwd=?";
ps = conn.prepareStatement(sql);
//给SQL设置参数
ps.setString(1, "jack");//第一个?设置参数
ps.setString(2, "123");//第二个?设置参数
//执行SQL
rs = ps.executeQuery();
//解析结果集
while (rs.next()) {
for (int i = 1; i <= 3; i++) {
//按照索引查
System.out.println(rs.getString(i));
}
}
}catch (Exception e){
e.printStackTrace();
}finally{ //释放资源,一定要被执行 !!!
//调用工具,完成关闭资源
JDBCUtils.close(rs,ps,conn);
}
}
//暴露SQL注入问题--发生了SQL拼接
//需求:按照 用户名 和 密码 查询用户信息
private static void method2() throws Exception {
//中文查不出来数据:
//String url="jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf8";
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
String url="jdbc:mysql://localhost:3306/jdbctest";
String name="root";
String pwd="root";
Connection conn = DriverManager.getConnection(url,name,pwd);
//获取传输器Statement,执行SQL
Statement st = conn.createStatement();
//TODO 测试SQL注入攻击问题
//是指当用户只输入数据时,恶意包含了特殊的SQL语句,改变了SQL语义
//导致只需要名字不需要密码也可以查看所有数据(数据泄露)
//名字输入后面两种值,都会产生SQL攻击问题: jack'# 或者 jack' or '1=1
String a = new Scanner(System.in).nextLine();
String b = new Scanner(System.in).nextLine();
String sql = "select * from user where name='"+a+"' and pwd='"+b+"'";
//执行SQL
ResultSet rs = st.executeQuery(sql);
//解析结果集
while(rs.next()){
for (int i = 1; i <= 3 ; i++) {
//按照索引查
System.out.println(rs.getString(i));
}
}
//释放资源
rs.close();
st.close();
conn.close();
}
//使用JDBC查询user表的数据
private static void method() throws Exception {
//1,注册驱动(jar包)
Class.forName("com.mysql.jdbc.Driver");
//2,连接数据库
//getConnection(1,2,3)-1是要连接哪个数据-2是用户名-3是密码
Connection con = DriverManager.getConnection(
// "协议//服务器的名字:数据库的端口号/数据库名",
// "jdbc:mysql://localhost:3306/jdbctest",
"jdbc:mysql:///jdbctest",
//url简写(使用本机使用默认的端口号)
"root","root");
//3,获取传输器Statement
Statement st = con.createStatement();
//4,执行SQL
String sql = "select * from user";
ResultSet rs = st.executeQuery(sql);
//5,解析结果集
while(rs.next()){ //next()判断有数据吗
//有数据就一个一个解析id/name/pwd
for (int i = 1; i <= 3; i++) {
System.out.println( rs.getString(i) );//按索引查;
}
String id2 = rs.getString("id");//按索引查
String name2 = rs.getString("name");//按索引查
String pwd2 = rs.getString("pwd");//按索引查
System.out.println(id2+name2+pwd2);
}
//6,释放资源
rs.close();
st.close();
con.close();
}
}
二,Git
–1,概述
就是一个代码托管平台
本地仓库:就是自己电脑里磁盘里的一个位置,用来存代码(像workspace)
远程仓库:是指在Git上创建的仓库,用来存提交好的代码
使用步骤: add – commit – push
从workpace到暂存区 从暂存区到本地仓库 从本地仓库推送到Git服务器
–2,安装Git
下一步下一步就ok
检查–右键–Git Bash here–where git
–3,访问码云
–官网:https://gitee.com/ 注册一个账号(邮箱/名字/密码)
–创建本地仓库:准备要提交的数据(D:\workspace\gitcgb2103\1.txt)
–创建远程仓库:
Gitee上右上角头像旁边的+ --点新建仓库–起个名字–设置开源–创建
–在本地仓库上,执行Git命令:
git config --global user.name “你注册时的账户名”
git config --global user.email “你注册时的邮箱”
git config --list
git init
git add .
git commit -m “first commit”
git remote add origin https://gitee.com/cgblpx/cgb2103webday06.git
git push -u origin master
(第一次push要输入邮箱和密码)
git pull #拉取、下载
–检查数据是否成功的提交到了Gitee:
访问Gitee,看仓库里有没有推送的新数据
–4,日常操作
–把要提交的文件,拷贝到本地仓库
–git add .
–git commit -m “备注”
–git push -u origin master
–git pull / 克隆下载
三,SQL优化
–1,查询语句里,用字段名代替*
select id,name,age from user
–2,过滤条件尽量不要用or,难以避免
select id,name,age from user where id=1 or name=‘123’
–3,表设计时,字段的类型,最好用varchar代替char
–char是固定长度,可能浪费空间,varchar长度可变
–4,模糊查询,最好先确定前面的数据
select id,name,age from user where name like ‘t%’
–5,字段的值,尽量用数字不用字符串
–查的快,省空间,1个数字只占一个字符,但是一个汉字要占3个字符(utf8)
–6,查询的结果范围尽量小,数据量尽量少
select id,name,age from user where name=‘123’ and id=3
–7,给字段加索引
#如果name有索引,由于123这个值写的不规范,会导致索引失效
select id,name,age from user where name=123
–8,每个列都可以加索引,但是不能太多,最好不能超过5个
–9,对字段的值可以去重,使用distinct关键字,但是不要对太多列去重
select distinct * from user
–10,过滤条件里最好不要用!= <>
–11,尽量给null列设置默认值
–12,批量操作
–需要一次性删除多条(10000)时,最好分批删除(按照500个的方式删除多次)
–增加大量数据时,可以只发起一个insert语句,来减少事务的开启和结束
insert into user(id) values(1),(2),(3),(4),(5),(6),(7)
–13,group by
–尽量把数据的范围控制到最小然后再分组
select id,count() from user group by id having id > 100 #低效
select id,count() from user where id > 100 group by id #高效
–14,伪删除设计
真实的开发中,很少真正的删除数据,而是把要删除的数据改变状态1 -> 0