1.将mysql-connector-java-8.0.20.jar包导入到libs文件夹中
2.注册驱动:Class.forName(“com.mysql.cj.jdbc.Driver”);
//自动去libs下遍历jar包,直到找到com.mysql.cj.jdbc.Driver
//由于加载类文件时会执行其中的静态代码块:java.sql.DriverManager.registerDriver(new Driver());如果驱动没有注册,则注册驱动
3.获取数据库连接对象connection:
Connection connection= DriverManager.getConnection(String url, String user, String password)
//connection是要操作的数据库对象;
//例子:jdbc:mysql://localhost:3306/db3
//如果连接本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称
4.tatement statement=connection.createStatement();
//statement是通过connection对象的createStatement产生,用于操作数据库;
5.statement.execute(sql);执行sql语句
//boolean execute(sql)是执行任意sql语句
//int executeUpdate(sql)是执行DML和DDL语句
//ResultSet executeQuery(sql)是执行DQL语句
public class JDBCDemo1 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.注册驱动DriverManager
Class.forName("com.mysql.cj.jdbc.Driver");//遍历libs目录,直到找到com.mysql,然后加载Driver类到内存中
//由于加载类文件时会执行其中的静态代码块:java.sql.DriverManager.registerDriver(new Driver());如果驱动没有注册,则注册驱动
//2.连接数据库Connection
Connection connection= DriverManager.getConnection("jdbc:mysql:///db3?serverTimezone=UTC","root","123456");
//功能:1.获取执行sql的对象,2.管理事务
//3.执行sql的对象Statement
String sql="select * from account";//将sql语句赋给字符串sql
Statement statement=connection.createStatement();//通过connection.createStatement()产生执行sql的对象statement
ResultSet resultSet = statement.executeQuery(sql);//通过executeUpdate()执行DML、DDL语句
//4.释放连接
statement.close();
connection.close();
}
}
PreparedStatement:执行sql的对象(用于替换Statement)
1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题
1. 输入用户随便,输入密码:‘1’ or 1=1(恒为真)
2. sql:select * from user where username = ‘lili’ and password = ‘a’ or ‘a’ = ‘a’
2. 解决sql注入问题:使用PreparedStatement对象来解决
原因:PreparedStatement不是将参数简单拼凑成sql,而是做了一些预处理,将参数转换为string,两端加单引号,将参数内的一些特殊字符(换行,单双引号,斜杠等)做转义处理,这样就很大限度的避免了sql注入。
3. 预编译的SQL:参数使用?作为占位符
4. 注意:后期都会使用PreparedStatement来完成增删改查的所有操作
1. 可以防止SQL注入
2. 效率更高
JDBC控制事务
1.事务四大性质:
原子性(不可分割),一致性(一个状态到另一个状态),隔离性(执行中不被其他事务干扰),持久性(改变是永久性的)
2.操作:开启,提交,回滚
开启:
conn.setAutoCommit(false);//关闭自动提交事务,开启事务
提交:
conn.commit();//用connection对象提交事务
回滚:
conn.rollback();//用connection对象回滚事务
问:Connection(数据库连接对象)可以管理事务,不同Connection的事务会出现脏读、不可重复读和幻读这些现象吗?如果会出现,请说出如何避免上述现象。
答:会出现。
首先应该设置mysql的隔离级别。然后在JDBC中,首先关闭自动提交事务:conn.setAutoCommit(false);用try 语句将可能发生异常的语句+conn.commit()语句保住,如果有在sql语句执行过程中发生了异常,就跳到catch语句的回滚:conn.rollback();中,如果没有发生异常,就提交事务。最后finally语句中关闭连接。
例题:
创建数据库表 user
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(32),
PASSWORD VARCHAR(32)
);
插入两条数据:
INSERT INTO USER VALUES(NULL,‘zhangsan’,‘123’);
INSERT INTO USER VALUES(NULL,‘lisi’,‘234’);
需求如下,请写出代码实现:
- 通过键盘录入用户名和密码
- 判断用户是否登录成功
提示:select * from user where username = “账号” and password = “密码”;
package com.yiliedu;
import java.sql.*;
import java.util.Scanner;
public class Entrance {
public static void main(String[] args){
String username1;
String password1;
Connection connection=null;
PreparedStatement prst=null;
ResultSet rs=null;
try{
Class.forName("com.mysql.cj.jdbc.Driver");//注册驱动
connection = DriverManager.getConnection("jdbc:mysql:///db3?serverTimezone=Asia/Shanghai", "root", "123456");//获取连接
String sql="select * from user where username=? and PASSWORD=? ";//设置sql语句
prst=connection.prepareStatement(sql); //获取prst对象
Scanner scanner=new Scanner(System.in);
System.out.println("请输入用户名");
username1=scanner.nextLine();
System.out.println("请输入密码");
password1=scanner.nextLine();
prst.setString(1,username1);
prst.setString(2,password1);
rs=prst.executeQuery();
if(rs.next()){//去数据库里查找,如果用户名和密码匹配,则rs对象就会被赋值
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
}catch(Exception e){
e.printStackTrace();
}finally {
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try{
connection.close();
}catch(SQLException e){
e.printStackTrace();
}
if(prst!=null){
try{
prst.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}
}