JDBC
HelloWorld
package org.westos.demo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* @author lwj
* @date 2020/8/11 9:02
*/
public class MyTest {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
/*
JDBC:Java DataBase Connection
Java连接数据库
由Java定义一套操作数据库的接口/规范(java.sql、javax.sql),由各个数据库厂商来实现这些接口(这些实现类称为数据库驱动),
我们只需要在代码中引入对应数据库的驱动即可。
*/
/*
JDBC入门:
1、导入数据库驱动(jar包); https://mvnrepository.com/artifact/mysql/mysql-connector-java/5.1.47 在maven中下载jar包
项目中新建lib目录,引入jar包,导入依赖Add as library
2、加载驱动;
3、获取连接对象Connection;
4、获取操作对象Statement;
5、执行SQL;
6、释放资源
*/
Class.forName("com.mysql.jdbc.Driver");
//加载驱动
String url = "jdbc:mysql://localhost:3306/jdbc?useSSL=false";
String username = "root";
String password = "xxxxxx";
Connection connection = DriverManager.getConnection(url, username, password);
//获取连接对象
Statement statement = connection.createStatement();
//获取操作对象
//定义SQL语句
String sql = "insert into users values(null, '张三', '123456', '1999-09-09')";
int i = statement.executeUpdate(sql);
//返回受影响的行数
System.out.println(i);
//1
statement.close();
connection.close();
//释放资源
}
}
1、准备数据库环境
CREATE DATABASE jdbc;
CREATE TABLE IF NOT EXISTS users(
id INT NOT NULL AUTO_INCREMENT,
username VARCHAR(20) NOT NULL,
PASSWORD VARCHAR(20) NOT NULL,
birthday DATE NOT NULL,
PRIMARY KEY(id)
);
2、找jdbc jar包的方法
https://mvnrepository.com/artifact/mysql/mysql-connector-java
根据数据库版本选择不同的jar包版本
3、在IDEA中配置MySQL连接,绑定之后写SQL语句会有提示
4、配置项目中sql字符串的类型为MySQL代码
5、查看代码执行结果
加载驱动
package org.westos.demo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* @author lwj
* @date 2020/8/11 9:58
*/
public class MyTest2 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
//加载驱动,Driver类的静态代码块已经新建了驱动对象,并且注册到DriverManager类中
/*
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
*/
String url = "jdbc:mysql://localhost:3306/jdbc?useSSL=false";
// jdbc协议格式
String username = "root";
String password = "xxxxxx";
Connection conn = DriverManager.getConnection(url, username, password);
//DriverManager:驱动管理类,getConnection()返回java.sql.Connection接口的实现类
System.out.println(conn);
//com.mysql.jdbc.JDBC4Connection@25f38edc
Statement statement = conn.createStatement();
System.out.println(statement);
//获取操作对象,com.mysql.jdbc.StatementImpl@1a86f2f1
String sql = "update users set birthday = '1999-10-10' where id = 1";
int i = statement.executeUpdate(sql);
//executeUpdate()对应sql中的增删改语句,返回的是int类型,受影响的行数
System.out.println(i);
//1
statement.close();
conn.close();
//释放资源
}
}
查询语句
1、准备实体类user
package org.westos.bean;
import java.util.Date;
/**
* @author lwj
* @date 2020/8/11 10:38
* 实体类中的属性名、类型和表中的字段名、类型保持一致
*/
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//java.util.Date
public User() {
}
public User(int id, String username, String password, Date birthday) {
this.id = id;
this.username = username;
this.password = password;
this.birthday = birthday;
}
//getter()、setter()、toString()
}
2、JDBC查询数据库
package org.westos.demo;
import org.westos.bean.User;
import java.sql.*;
import java.util.ArrayList;
/**
* @author lwj
* @date 2020/8/11 10:27
*/
public class MyTest3 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql:///jdbc?useSSL=false", "root", "xxxxxx");
Statement statement = conn.createStatement();
String sql = "select id, username, password, birthday from users";
ResultSet resultSet = statement.executeQuery(sql);
ArrayList<User> users = new ArrayList<>();
//返回结果集
while (resultSet.next()) {
int id = resultSet.getInt("id");
//根据columnLabel字段别名获取
String username = resultSet.getString("username");
String password = resultSet.getString(3);
//根据columnIndex获取
Date birthday = resultSet.getDate("birthday");
//返回java.sql.Date类型,并不是SE阶段的java.util.Date
Date date_birthday = new Date(birthday.getTime());
User user = new User();
user.setId(id);
user.setUsername(username);
user.setPassword(password);
user.setBirthday(date_birthday);
users.add(user);
}
//遍历集合
users.forEach(System.out::println);
/*
User{id=1, username='张三', password='123456', birthday=1999-10-10}
User{id=2, username='李四', password='123456', birthday=1999-09-09}
User{id=3, username='王五', password='123456', birthday=1999-09-09}
*/
resultSet.close();
statement.close();
conn.close();
}
}
Statement及其弊端
- 用于向数据库发送SQL语句,完成增删改查操作
- executeUpdate(sql),对应增删改DML,返回表中受影响的行数
- executeQuery(sql),对应查询语句DQL,返回查询出来的结果集,用ResultSet对象接收
- next()遍历ResultSet
package org.westos.demo;
import java.sql.*;
import java.util.Scanner;
/**
* @author lwj
* @date 2020/8/11 11:11
*/
public class MyTest4 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//模拟登陆,引入PreparedStatement
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = sc.nextLine();
System.out.println("请输入密码:");
String password = sc.nextLine();
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql:///jdbc?useSSL=false", "root", "xxxxxx");
Statement statement = conn.createStatement();
String sql = "select * from users where username = '" + username + "' and password = '" + password + "'";
//拼sql串
ResultSet resultSet = statement.executeQuery(sql);
if (resultSet.next()) {
System.out.println("登陆成功");
} else {
System.out.println("登陆失败");
}
}
}
SELECT * FROM users WHERE username = '张三' AND PASSWORD = '123456';
/*
id username password birthday
1 张三 123456 1999-10-10
*/
SQL注入
-- SQL注入(手动拼接sql)
SELECT * FROM users WHERE username = 'xxx' AND PASSWORD = 'xxxxxx' OR '1' = '1';
/*
id username password birthday
1 张三 123456 1999-10-10
2 李四 123456 1999-09-09
3 王五 123456 1999-09-09
*/
PreparedStatement
package org.westos.demo;
import java.sql.*;
import java.util.Scanner;
/**
* @author lwj
* @date 2020/8/11 11:38
*/
public class MyTest5 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = scanner.nextLine();
System.out.println("请输入密码:");
String password = scanner.nextLine();
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql:///jdbc?useSSL=false", "root", "xxxxxx");
String sql = "select * from users where username = ? and password = ?";
PreparedStatement preparedStatement = conn.prepareStatement(sql);
// PreparedStatement预编译操作对象,防止SQL注入
preparedStatement.setString(1, username);
preparedStatement.setString(2, password);
//对SQL中的参数进行赋值
System.out.println(preparedStatement.toString());
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
System.out.println("登陆成功");
} else {
System.out.println("登陆失败");
}
resultSet.close();
preparedStatement.close();
conn.close();
}
}
SELECT * FROM users WHERE username = 'xxx' AND PASSWORD = 'xxx\' or \'1\' = \'1';
PreparedStatement的巧妙之处在于:(setString填充参数时),两端加单引号,将参数内的一些特殊字符(换行,单双引号,斜杠等)做转义处理,这样就很大限度的避免了sql注入。
当填充参数为int类型时,
package org.westos.demo;
import java.sql.*;
/**
* @author lwj
* @date 2020/8/11 12:11
*/
public class MyTest6 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql:///jdbc?useSSL=false", "root", "xxxxxx");
String sql = "select * from users where id = ?";
PreparedStatement preparedStatement = conn.prepareStatement(sql);
preparedStatement.setInt(1, 1);
System.out.println(preparedStatement.toString());
//com.mysql.jdbc.JDBC42PreparedStatement@42110406: select * from users where id = 1
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getString("username"));
//张三
}
resultSet.close();
preparedStatement.close();
conn.close();
}
}