一、 JDBC概述
● java数据库连接
java数据库连接(Java DataBase Connectivity),简称 JDBC
是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它由一组用Java语言编写的类和接口组成。
有了JDBC,java开发人员只需要编写一次程序,就可以访问不同的数据库
Java定义者制定了JDBC规范
数据库开发商实现接口
程序员学习使用标准规范
● JDBC API
• 在项目中添加文件夹,命名为 lib ,然后将 .jar文件(架包)拉到 lib 文件夹下面
右键压缩包,选择 Add as Library
供程序员调用的接口与类,集成在java.sql包中
DriverManager类作用:管理各种不同的jDBC驱动
Connection 接口:与特定数据库的连接
Statement 接口:执行sql
PreparedStatement接口:执行sql
ResultSet接口:接收查询结果
二、 JDBC搭建
● 注册JDBC驱动程序
这需要初始化驱动程序,这样就可以打开与数据库的通信信道。
Class.forName(“com.mysql.cj.jdbc.Driver”); //反射实现
或者
DriverManager.registerDriver(new Driver());
● 建立与数据库连接
这需要使用DriverManager.getConnection()方法来创建一个 Connection对象,它代表一个物理连接的数据库
Connection conn = DriverManager.getConnection(URL,USER,PASS);
URL:jdbc:mysql://ip(127.0.0.1):端口(3306)/数据库名?serverTimezone=Asia/Shanghai
USER:用户名(root)
PASS:密码
● 获得Satement执行sql语句
Statement st = connection.createStatement();
Satement中的方法:
Int executeUpdate(String sql):用于执行ddl语句和dml(增,删,改)语句返回操作的行数
用于执行ddl语句返回0
用于执行dml语句返回操作的行数
ResultSet executeQuery(String sql); 用于执行查询语句,返回一个ResultSet 集合
● 获得PrepareStatement执行sql语句
在sql语句中参数位置使用占位符,使用setXX方法向sql中设置参数
PrepareStatement ps = connection.prepareStatement(sql);
PrepareStatement中的方法:
Int executeUpdate():用于执行ddl语句和dml(增,删,改)语句,返回操作的行数
用于执行ddl语句返回0
用于执行dml语句返回操作的行数
ResultSet executeQuery(); 用于执行查询语句 返回一个ResultSet 集合
● 关闭与数据库的链接通道
每次操作完成后关闭所有与数据库交互的通道
st.close();
rs.close();
conn.close();
ps.close();
通过Java实现为数据库添加数据
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo2 {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
Demo2 demo2 = new Demo2();
demo2.save("张三","男","2004-2-2","15288888888","汉中",1.75,2);
}
public void save(String name,String gender,String birthday,String phone,String address,double height,int majorid) throws ClassNotFoundException, SQLException {
//加载JDBC驱动程序
Class.forName("com.mysql.cj.jdbc.Driver");
//与建立连接
String url = "jdbc:mysql://127.0.0.1:3306/schooldb?serverTimezone=Asia/Shanghai";
String user = "root";
String password = "root";
Connection connection = DriverManager.getConnection(url,user,password);
//获得Satement执行sql语句
Statement st = connection.createStatement();
st.executeUpdate("insert into student(name,gender,birthday,phone,address,height,reg_time,majorid) value ('"+name+"','"+gender+"','"+birthday+"','"+phone+"','"+address+"','"+height+"',now(),'"+majorid+"')");
//关闭数据库连接
st.close();
connection.close();
}
}
三、 Statement 和 PreparedStatement
● 代码的可读性和可维护性
虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:
例如:
Statement:
Statement st = connection.createStatement();
st.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"' , '"+var2+"' , "+var3+" , '"+var4+"')");
PreparedStatement:
PreparedStatement ps = connection.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate();
● 极大地提高了安全性
防止sql注入攻击
如果使用Statement:
Stringsql= “ delete from user where id = ”+num;
当我们把[or 1=1]作为id传入进来,
delete from tb_name where id = 1 or 1 = 1;
而1’ = ‘1’肯定成立,则会删除所有内容
而如果你使用预编译语句,你传入的任何内容就不会和原来的语句发生任何匹配的关系
预编译模式中每个占位符处,只能插入一个值,而会过滤其他语句
四、 结果集处理
● PreparedStatement和Statement中的executeQuery()方法中会返回一个ResultSet对象,查询结果就封装在此对象中.
● 使用ResultSet中的next()方法获得下一行数据
● 使用getXXX(String name)方法获得值
● 单个查询
import java.sql.*;
public class Demo3 {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
Demo3 demo3 = new Demo3();
Student student = demo3.findStudentByNum(1);
System.out.println(student.getName());
}
public Student findStudentByNum(int num) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/schooldb?serverTimezone=Asia/Shanghai";
String user = "root";
String password = "root";
Connection connection = DriverManager.getConnection(url, user, password);
PreparedStatement ps = connection.prepareStatement("select num,name,gender,birthday,phone,reg_time from student where num = ?");
ps.setObject(1, num);
//查询操作
ResultSet rs = ps.executeQuery(); //将查询结果封装到ResultSet对象中
Student student = null;
while (rs.next()) {
student = new Student();
student.setNum(rs.getInt("num"));
student.setName(rs.getString("name"));
student.setGender(rs.getString("gender"));
student.setBirthday(rs.getDate("birthday"));
student.setPhone(rs.getString("phone"));
student.setRegTime(rs.getTimestamp("reg_time"));
}
return student;
}
}
● 多个查询
import java.sql.*;
import java.util.ArrayList;
public class Demo3 {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
Demo3 demo3 = new Demo3();
ArrayList<Student> students = demo3.findStudentByGender("男");
for(int i = 0;i<students.size();i++){
System.out.println(students.get(i).getName()+":"+students.get(i).getGender()+" "+students.get(i).getBirthday()+" "+students.get(i).getPhone());
}
}
//多个查询
public ArrayList<Student> findStudentByGender(String gender) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/schooldb?serverTimezone=Asia/Shanghai";
String user = "root";
String password = "root";
Connection connection = DriverManager.getConnection(url, user, password);
PreparedStatement ps = connection.prepareStatement("select num,name,gender,birthday,phone,reg_time from student where gender = ?");
ps.setObject(1, gender);
ArrayList<Student> students = new ArrayList<>();//创建学生集合,存储查询到的多个学生对象
ResultSet rs = ps.executeQuery();
while(rs.next()){
Student student = new Student();
student.setNum(rs.getInt("num"));
student.setNum(rs.getInt("num"));
student.setName(rs.getString("name"));
student.setGender(rs.getString("gender"));
student.setBirthday(rs.getDate("birthday"));
student.setPhone(rs.getString("phone"));
student.setRegTime(rs.getTimestamp("reg_time"));
students.add(student);//将学生对象存到集合
}
rs.close();
ps.close();
connection.close();
return students;
}
}