学习目标:
学会JDBC学习内容:
提示:这里可以添加要学的内容
例如:
1、 JDBC概述
2、 JDBC搭建
3、 PreparedStatement和Statement
4、 查询
学习时间:
2021年7月8日学习产出:
1、 技术笔记 1 遍 2、CSDN 技术博客 1 篇JDBC概述
JDBC(Java DataBase Connectivity)java数据库连接
是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问, 它由一组用Java语言编写的类和接口组成。
有了JDBC,java开发人员只需要编写一次程序,就可以访问不同的数据库
三方的关系:
Java定义者制定了JDBC规范
数据库开发商实现接口
程序员学习所使用的规范标准
JDBC API:
供程序员调用的接口与类,集成在java.sql包中
JDBC搭建
在工程目录下新建 lib 目录,将需要的jar包复制到该目录下
将jar包引入工程
Build Path – configue build path
编写程序
Satement中的方法:
Int executeUpdate(String sql) 用于执行ddl语句和dml(增,删,改)语句 返回操作的行数
用于执行ddl语句返回0
用于执行dml语句返回操作的行数
ResultSet executeQuery(String sql); 用于执行查询语句 返回一个 ResultSet 集合
public class JDBCDemo1 {
/*
jdbc 搭建步骤
1.导入对应的数据库驱动包(jar)
2.加载mysql驱动 new 对象 反序列化(readObject() Object)
3.连接到数据库
4.发送sql到数据库
5.关闭数据库连接通道
*/
public static void main(String[] args) {
try {
Class.forName("com.mysql.cj.jdbc.Driver");//是使用java反射机制实现的创建对象
//DriverManager.registerDriver(new Driver());
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/school_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai", "root", "root");
// 返回的是mysql包中的一个实现了Connection接口的类的对象 com.mysql.cj.jdbc.ConnectionImpl@1e67b872
//创建
Statement st = connection.createStatement();
// System.out.println(st);com.mysql.cj.jdbc.StatementImpl@47f6473
st.executeUpdate("insert into course(name)values('php')");
st.close();
connection.close();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
}
单独写一个类出来,在主函数中调用也可以
url也可以在外面先定义了然后在里面直接调用,更方便读代码
public static void main(String[] args) {
JDBCDemo2 jd2 = new JDBCDemo2();
try {
jd2.saveStudent("tom","男","2000-1-1");
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("类找不到");
} catch (SQLException throwables) {
throwables.printStackTrace();
System.out.println("数据链接失败");
}
}
public void saveStudent(String name,String sex,String birthday) throws ClassNotFoundException, SQLException {
Connection connection = null;
Statement st = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/school_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai";
connection = DriverManager.getConnection(url,"root","root");
st = connection.createStatement();
int row = st.executeUpdate("INSERT INTO student(NAME,sex,birthday,reg_time)" +
" VALUES('"+name+"','"+sex+"','"+birthday+"',now())");
System.out.println(row);//返回操作的行数
}finally {
if(st!=null){
st.close();
}
if(connection!=null){
connection.close();
}
}
}
PrepareStatement中的方法:
Int executeUpdate() 用于执行ddl语句和dml(增,删,改)语句 返回操作的行数
用于执行ddl语句返回0
用于执行dml语句返回操作的行数
ResultSet executeQuery(); 用于执行查询语句 返回一个ResultSet 集合
public static void main(String[] args) {
JDBCDemo5 jd2 = new JDBCDemo5();
try {
jd2.saveStudent("tom","男","2000-1-1");
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("类找不到");
} catch (SQLException throwables) {
throwables.printStackTrace();
System.out.println("数据链接失败");
}
}
public void saveStudent(String name,String sex,String birthday) throws ClassNotFoundException, SQLException {
Connection connection = null;
PreparedStatement ps = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/school_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai";
connection = DriverManager.getConnection(url,"root","root");
// 预先将sql语句封装到PreparedStatement对象中 ?表示一个占位符,需要传入一个值
ps = connection.prepareStatement("insert into student(name,sex,birthday,reg_time)values(?,?,?,?)");
//向预编译好的sql中传入数据
ps.setString(1,name);
ps.setString(2,sex);
ps.setObject(3, birthday);
ps.setObject(4, new Date());
ps.executeUpdate();//执行sql
}finally {
if(ps!=null){
ps.close();
}
if(connection!=null){
connection.close();
}
}
}
PreparedStatement和Statement
1、虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无
论从可读性还是可维护性上来说。都比直接用Statement的代码高很多档次:
2、最重要的一点是极大地提高了安全性。
防止sql注入
如果出现这恶意攻击,在删除操作时就会全部被删除
public static void main(String[] args) {
JDBCDemo7 jd2 = new JDBCDemo7();
try {
//直接将值拼接到sql中,这时就可以恶意的向值中添加一些其他的语句,导致条件成立,造成对数据库的共计
jd2.deleteStudent("9 or 1=1");
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("类找不到");
} catch (SQLException throwables) {
throwables.printStackTrace();
System.out.println("数据链接失败");
}
}
private void deleteStudent(String num) throws ClassNotFoundException, SQLException {
Connection connection = null;
PreparedStatement ps = null;
try {
String url = "jdbc:mysql://127.0.0.1:3306/school_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai";
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection(url, "root", "root");
ps = connection.prepareStatement("delete from student_course where student_num = ?");
//通过set方法,在设置值的时候,会对进行检测,如果传入其他关键字,会报错
ps.setString(1,num);
ps.executeUpdate();
ps = connection.prepareStatement("delete from student where num = ?");
ps.setString(1, num);
ps.executeUpdate();
}finally {
if(ps!=null){
ps.close();
}
if(connection!=null){
connection.close();
}
}
}
而如果你使用预编译语句。你传入的任何内容就不会和原来的语句发生任何匹配的关系。
预编译模式中每个占位符处,只能插入一个值,而会过滤其他语句
查询
public static void main(String[] args) {
//查询学号为17学生
// 数据库持久化的存储数据, 当在程序中使用时,需要把数据查询出来,封装在对象中
JDBCDemo9 jdbcDemo9 = new JDBCDemo9();
try {
Student student = jdbcDemo9.findStdent(17);
System.out.println(student);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
private Student findStdent(int num) throws ClassNotFoundException, SQLException {
Connection connection = null;
PreparedStatement ps = null;
Student student = new Student();
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/school_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai";
connection = DriverManager.getConnection(url, "root", "root");
ps = connection.prepareStatement("SELECT\n" +
" num,\n" +
" name,\n" +
" sex,\n" +
" birthday,\n" +
" height,\n" +
" mobile,\n" +
" reg_time\n" +
"FROM\n" +
" student\n" +
"WHERE num = ?");
ps.setInt(1,num);
ResultSet res = ps.executeQuery();//执行查询操作
//从ResultSet中取出我们需要的数据 next()-有内容返回true,否则返回false
//获得下一行数据
while(res.next()){
//获得值给学生对象
student.setNum(res.getInt("num"));
student.setName(res.getString("name"));
student.setSex(res.getString("sex"));
student.setBirthday(res.getDate("birthday"));
student.setHeight(res.getFloat("height"));
student.setMobile(res.getString("mobile"));
student.setRegTime(res.getTimestamp("reg_time"));
}
}finally {
if(ps!=null){
ps.close();
}
if(connection!=null){
connection.close();
}
}
return student;
}