JDBC_01
A.Java链接数据库(快速入门)
1.概述
Java DateBase Connective——Java链接数据库
使用Java代码操作数据库
JDBC其实就是一套操作数据库的规范(接口)
数据库厂商写的一套实现类,叫做数据库驱动
2.快速入门
在此主要将如何链接到数据库,后面再讲细节问题
a.导入驱动jar包
在工程目录下创建一个lib文件夹,将数据库驱动复制到文件夹下
右键该目录,选择Build Path——Add Builder Path
出现下图
b.注册驱动
使用反射机制 Class.forname("Driver的全路径名称");
加载该类时,就会自动完成注册,会执行静态代码块
static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } }
如果jar包是5.1以上的 加载驱动也可以省略不写(有配置文件可以自动加载)
c.创建连接对象 Connection
url连接地址:主协议:子协议://ip:端口号//数据库名
当连接本机数据库,ip可以写localhost或127.0.0.1,jar包版本高于5.1.1,ip,端口可省略
DriverManager 获取连接对象
d.定义sql
e.获取执行sql的对象 Statement
f.执行sql
excuteQuery(sql):执行DQL语句
excuteUpdate(sql):执行DML语句
g.处理结果
h.释放资源
代码如下:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; public class JDBCDemo01 { public static void main(String[] args) throws Exception { // 1.导入驱动jar包 // 2.注册加载驱动 // 如果jar包是5.1以上的 加载驱动也可以省略不写 Class.forName("com.mysql.jdbc.Driver"); // 3.获取连接对象 // DriverManager.getConnection(url,user,password) Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb_01", "root", "root"); // 4.定义sql语句 String sql = "insert into user values(106,'helloJDBC')"; // 5.获取操作对象 // Statement 用于执行静态sql语句,并返回它所生成结果的对象 Statement statement = conn.createStatement(); // 6.执行sql语句 int i = statement.executeUpdate(sql);// 返回的是影响数据库的行数 if (i != 0) { System.out.println("添加成功!"); } else { System.out.println("添加失败!"); } // 7.释放资源 statement.close(); conn.close(); } }
B.封装数据
1.查询数据
executeQuery(sql):执行DQL语句
executeUpdate(sql):执行DML语句
execute(sql):执行任意sql语句
ResultSet:结果集对象,用来封装查询出来的结果
ResultSet.getInt(); ResultSet.getString(); 根据列的数据类型选择
可传递表的列名或编号(从1开始),一般传递列名
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class JDBCDemo02 { public static void main(String[] args) throws Exception { // 加载驱动 Class.forName("com.mysql.jdbc.Driver"); // 获取连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb_01", "root", "root"); // 获取操作对象 Statement statement = conn.createStatement(); // 定义sql语句 String sql = "select * from user"; // 执行语句 ResultSet resultSet = statement.executeQuery(sql); // 获取每一条数据 while (resultSet.next()) { // 让指针下移 // 1)通过编号取数据,编号为列,从1开始 // int id = resultSet.getInt(1); // String username = resultSet.getString(2); // 2)通过列名拿数据 常用 int id = resultSet.getInt("id"); String username = resultSet.getString("username"); System.out.println(id + "---" + username); } // 释放资源 resultSet.close(); statement.close(); conn.close(); }
2.封装数据
我们从数据库中取数据,是想使用这些数据,而不是单纯的查看
所以,先封装到对象,再将对象放入集合中去
建立bean包存放JavaBean
创建对象存储数据(规则在代码中注释)
改进后的查询数据代码import java.io.Serializable; public class User implements Serializable { /** * JavaBean是一种规范要求 * 1.所有成员变量必须私有 * 2.必须提供无参构造 * 3.必须提供get/set方法 * 4.最好事先Serializable接口 * JavaBean作用:封装数据 */ // 为了给对象打个标记,保证对象在传递的时候是同一个对象 private static final long serialVersionUID = 1L; private int id;; private String username; public User() { super(); } public User(int id, String username) { super(); this.id = id; this.username = username; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Override public String toString() { return "User [id=" + id + ", username=" + username + "]"; } }
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.util.ArrayList; import org.xxx.bean.User; public class JDBCDemo02 { public static void main(String[] args) throws Exception { // 加载驱动 Class.forName("com.mysql.jdbc.Driver"); // 获取连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb_01", "root", "root"); // 获取操作对象 Statement statement = conn.createStatement(); // 定义sql语句 String sql = "select * from user"; // 执行语句 ResultSet resultSet = statement.executeQuery(sql); // 创建User对象 User user = null; // 创建集合存储对象 ArrayList<User> list = new ArrayList<>(); // 获取每一条数据 while (resultSet.next()) { // 让指针下移 // 通过列名拿数据 常用 int id = resultSet.getInt("id"); String username = resultSet.getString("username"); // 把数据封装到对象里 user = new User(id, username); // 把对象存储到集合里 list.add(user); } // 遍历集合 for (User u : list) { System.out.println(u); } // 释放资源 resultSet.close(); statement.close(); conn.close(); } }
C.sql注入
1.模拟用户登录
先在数据库中创建一个用户名单
登陆程序CREATE TABLE logic( username VARCHAR(50), PASSWORD VARCHAR(20) ); INSERT INTO logic VALUES('张三','123456');
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.util.Scanner; public class JDBCLogic { public static void main(String[] args) throws Exception { // 创建键盘录入对象 Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String username = sc.next(); System.out.println("请输入密码:"); String password = sc.next(); // 使用JDBC Class.forName("com.mysql.jdbc.Driver"); // 获取连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb_01", "root", "root"); // 获取操作对象 Statement statement = conn.createStatement(); // 定义sql,拼接字符串 String sql = "select * from logic where username='" + username + "' and password='" + password + "'"; // 执行sql语句 ResultSet resultSet = statement.executeQuery(sql); // 判断 if (resultSet.next()) { System.out.println("登陆成功!"); } else { System.out.println("登录失败!"); } // 释放资源 resultSet.close(); statement.close(); conn.close(); } }
2.sql注入
当在数据库查询或者在登陆程序里,输入用户名和密码都为1' or '1'='1,使拼接的sql成为下面语句时
发现也可以正常查询数据或者登陆成功,这种现象就叫做sql注入SELECT * FROM logic WHERE username = '1' OR '1' = '1' AND PASSWORD = '1' OR '1' = '1';
一般黑客可以利用特殊字符串的拼接,绕过数据库的校验
怎么预防呢?
3.预防sql注入
引入预编译操作对象代替获取操作对象
预编译操作对象:Connection prepareStatment(sql)
该方法可以避免使用字符串的拼接,提高代码的安全性。
a.定义sql使用通配符?避免字符串拼接
b.使用setString(通配符位置(从1开始), 值)给通配符赋值
这样,就解决了sql注入问题,可以再次验证import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Scanner; public class JDBCLogic { public static void main(String[] args) throws Exception { // 创建键盘录入对象 Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String username = sc.next(); System.out.println("请输入密码:"); String password = sc.next(); // 使用JDBC Class.forName("com.mysql.jdbc.Driver"); // 获取连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb_01", "root", "root"); // 定义sql 使用通配符?代替数据 String sql = "select * from logic where username=? and password = ?"; // 获取预编译操作对象 PreparedStatement statement = conn.prepareStatement(sql); // 给通配符?赋值,参数1为?的位置,从1开始,参数2为值 statement.setString(1, username); statement.setString(2, password); // 执行sql语句 ResultSet resultSet = statement.executeQuery(); // 判断 if (resultSet.next()) { System.out.println("登陆成功!"); } else { System.out.println("登录失败!"); } // 释放资源 resultSet.close(); statement.close(); conn.close(); } }