点击截图右边的加号
然后选择jar包 mysql-connector-java-5.1.17.jar 这个jar包让我们可以在java中操作mysql
接着点击右下角的apply应用和OK,之后就可以正常使用了
查询语句(查)
注释中包含:
- 连接里面的字段含义解释,url,user,password
- 查询语句的执行语句是executeQuery,返回的是包含一至多条数据的结果集
增删改操作的执行语句是executeUpdate,返回结果为1或者非1,为1 正确执行,非1 直接报错 - 获取结果集中的字段值,不同类型有不同的语句。String类型对应getString,int类型对应getInt
- getString语句的括号中可以写字段名或者索引值,索引从1开始,索引为1表示第一列
package mysql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/*
顺序:
1.加载驱动:使用反射来引用jdbc中的代码
2.获取连接
3.执行sql语句
*/
public class MYSQLTest1 {
public static void main(String[] args) throws Exception {
// 1,加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2,获取连接 ,DriverManager.getConnection返回一个对象,通过这个对象可以操作sql
//返回来的这个conn对象就相当于mysql服务
//jdbc:mysql://master:3306/show1 ,jdbc是固定值,mysql根据连接的数据库类型而定
//master是ip地址,我是在hosts文件里面将master与ip地址绑定了,所以可以直接写master
//3306是端口号,一般固定是这个数值,最后的show1是要连接的数据库的名字
//最后面的root和123456是mysql的用户名和密码
Connection conn = DriverManager.getConnection("jdbc:mysql://master:3306/show1", "root", "123456");
//3,执行mysql
//3.1 写具体的sql语句
String sql = "select * from stu";
//3.2 获取执行sql语句的执行器
Statement statement = conn.createStatement();
//3.3 利用执行器statement执行sql语句
//sql语句可以分为两大类,一类是查询语句,一类是增删改的修改语句
//查询语句的返回结果是一个结果集,里面可以包含多行查询到的数据,使用executeQuery
//修改语句的返回结果要么是1说明执行成功,要么不是1就会报错,使用executeUpdate
//这里先看查询语句,使用executeQuery
ResultSet resultSet = statement.executeQuery(sql);
//查看执行完的结果
//这里遍历结果集resultSet,不能用for和Iterator,只能用while+next()获取里面的每一条数据
while(resultSet.next()){
//根据不同的数据类型有不同的语句,比如String类型用getString,int类型用getInt
//而这些语句都有两种用法,一种是下面的第一行,直接用字段名来获取这一列的字段值
//第二种方法是第二行用索引值来获取数据,注意mysql字段的索引从1开始
String name = resultSet.getString("StudentName");
String string = resultSet.getString(2);
//name和String结果相同
System.out.println(name);
System.out.println(string);
System.out.println("-----------");
}
//关闭连接
resultSet.close();
statement.close();
conn.close();
}
}
插入语句(增)
注释中包含:
- sql语句中单引号与双引号的区别
sql语句中没有变量时,字段值统一用单引号。sql需要变量时,用" ’ “+变量名+” ’ "这样的写法在执行时被转换为 ‘ 变量 ’
package mysql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class MYSQLTest2 {
public static void main(String[] args) throws Exception{
//1.获取驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://master:3306/show1", "root", "123456");
//3.执行sql
//3.1 sql语句
//在sql的语句中尽量都用单引号,
//如果使用双引号,因为sql整个被双引号包括,如果双引号里面有双引号,就会发生双引号的匹配错误问题
String sql = "insert into stu values(10008,'tang',15,'0')";
//如果sql语句中有变量,就需要用到双引号
String name = "song";
String sql1 = "insert into stu values(10009,'"+name+"',34,'1')";
//'"+name+"'里面的第一个双引号与insert前的双引号匹配,第二个双引号与sql1语句最后面的双引号匹配
//双引号旁边还各有一个单引号是因为,sql语句中字符串应该用单引号包起来
//所以最后的sql语句的结果是insert into stu values(10009,'song',34,1)
System.out.println(sql1);
//3.2获取执行器
Statement statement = conn.createStatement();
//3.3 执行sql语句
int i1 = statement.executeUpdate(sql);
int i2 = statement.executeUpdate(sql1);
//i1,i2里面是执行的结果,如果正确执行,结果为1
System.out.println("i1 = "+i1+" --- "+" i2 = "+i2);
//关闭
statement.close();
conn.close();
}
}
i1和i2都为1说明执行成功,到navicat中查看一下
stu表中多出来两条数据,添加成功
删除语句(删)
package mysql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class MYSQLTest3 {
public static void main(String[] args) throws Exception {
//获取驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://master:3306/show1", "root", "123456");
//执行sql
String sql = "delete from stu where id=10009";
Statement statement = conn.createStatement();
int i = statement.executeUpdate(sql);
System.out.println(i);
//关闭
statement.close();
conn.close();
}
}
结果为1说明执行成功,查看一下表stu
最后一行被删去了
修改语句(改)
package mysql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class MYSQLTest4 {
public static void main(String[] args) throws Exception{
//获取驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://master:3306/show1", "root", "123456");
//执行sql
String sql = "update stu set StudentName='ning' where id=10008";
Statement statement = conn.createStatement();
int i = statement.executeUpdate(sql);
System.out.println(i);
//关闭
statement.close();
conn.close();
}
}
id为10008的这一行的StudentName被修改为ning
SQL注入问题
sql注入:参数中有mysql命令,而mysql把这些关键字当做命令去执行
比如登录一个网站时,需要输入用户名和密码。用户输入的用户名和密码会和数据库中存储的用户名和密码进行匹配,如果匹配正确则可以登录,匹配错误则登录失败
现在来模拟一下这个过程,先来建一下用户信息表
create table userInfo(
username varchar(255),
password int
)engine=innodb;
insert into userInfo values('root','123456');
select * from userInfo;
package mysql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
//SQL注入问题
public class LoginTest1 {
public static void main(String[] args) throws Exception {
//获取驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://master:3306/show1", "root", "123456");
//执行sql语句
//username和password假定为用户输入的用户名和密码
String username = "root";
String password = "123456";
//利用sql语句查询表中是否有root,123456的这一行数据
String sql = "select * from userInfo where username='"+username+"' and password='"+password+"'";
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
//查看结果
if(resultSet.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
//关闭
resultSet.close();
statement.close();
conn.close();
}
}
此时结果为
然后修改一下用户名
package mysql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
//SQL注入问题
public class LoginTest1 {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://master:3306/show1", "root", "123456");
//修改输入的用户名
String username = "root' or '1'='1 ";
String password = "123456";
String sql = "select * from userInfo where username='"+username+"' and password='"+password+"'";
System.out.println(sql);
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
if(resultSet.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
resultSet.close();
statement.close();
conn.close();
}
}
会发现即使用户名是错误的,依旧登录成功了。再来看看sql语句,发现无论username的值是什么都可以匹配到。原因就是用户名中包含关键字的话,传入sql语句中时,关键字没有被当作字符串处理,而是当sql的关键字处理。
为了避免这种情况,就需要改变获取执行器的语句
将conn.createStatement() 改为conn.prepareStatement(sql)
package mysql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
//解决SQL注入问题,将conn.createStatement()换成conn.prepareStatement()
public class LoginTest2 {
public static void main(String[] args) throws Exception{
//获取驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://master:3306/show1", "root", "123456");
//执行sql
String username = "root";
//conn.createStatement(sql)是将sql语句连带着参数一起传入执行器里面
//conn.prepareStatement()是先将sql语句的模板传进去,然后在利用setString传入参数
//传入的位置是 ? 所在的位置,为了确定传入哪个问号,问号有索引,从1开始
String sql = "select * from userInfo where username=?";
// 先将模板传入执行器ps
PreparedStatement ps = conn.prepareStatement(sql);
//然后将参数传入执行器ps
ps.setString(1,username);
//利用执行器执行sql语句
ResultSet resultSet = ps.executeQuery();
//查询结果
if(resultSet.next()){
System.out.println("成功");
}else{
System.out.println("失败");
}
//关闭
resultSet.close();
ps.clearParameters();
conn.close();
}
}
对比一下:
//conn.createStatement() 会造成sql注入问题
String username = "root' or '1'='1 ";
String sql = "select * from userInfo where username='"+username+"'";
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
//conn.prepareStatement(sql) 不会造成sql注入问题
String username = "root";
String sql = "select * from userInfo where username=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,username);
ResultSet resultSet = ps.executeQuery();
这里就可以发现 createStatement() 是将sql语句整个的包含参数一起传入执行器
而prepareStatement(sql) 是先将sql语句,参数以外的内容传入执行器,相当于先传入一个模板,参数的位置用 ? 来代替。然后再用 set语句将参数值传入 ?的位置,问号?也有索引,从1开始,用索引指定传入第几个问号中。
完整的网站登录检查
package mysql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Scanner;
public class LoginTest3 {
static Connection conn = null;
static{
try{
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://master:3306/show1", "root", "123456");
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String username = sc.next();
String password = sc.next();
String login = Login(username,password);
System.out.println(login);
}
//验证用户名是否正确
public static String Login(String username,String password) throws Exception{
String sql = "select * from userInfo where username=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,username);
ResultSet resultSet = ps.executeQuery();
//如果结果集为空,说明用户名错误,数据库的数据中没有叫这个的用户
if(!resultSet.next()){
return "登录失败";
}
//经过了上面的判断后还能继续执行,说明结果集不为空,应该接着比较密码是否正确,此时结果集里面是一行数据
//数据的用户名即为查询的用户名,还有密码password,这个密码是数据库里面的密码,是正确的密码
// 此时应该判断数据库的密码与用户输入的密码,即方法参数列表传入的密码是否一致
//先获取数据库的密码
String SQLpassword = resultSet.getString("password");
String message = LoginPassword(password,SQLpassword);
return message;
}
//比较密码是否正确
public static String LoginPassword(String password,String SQLpassword) throws Exception{
if(!password.equals(SQLpassword)){
return "用户输入密码与数据库密码不一致";
}
return "登录成功";
}
}