1.JDBC 和数据库连接池
java设计者设计接口规范 这些接口规范实现的细节由不同的厂商实现这些类 这些类来实际操作数据库 就是实现接口类蓝色圆角矩形的地方
如果这样访问数据库 可以说简直狗屎
2.JDBC模拟
java设计者提供
public interface JdbcInterface {
//连接
public Object getConnection();
//crud
public void crud();
//关闭连接
public void close();
}
数据库厂商实现
package com.hspedu.jdbc.myJDBC;
/**
* mysql 数据库实现了JDBC接口[模拟] 【mysql厂家开发】
*/
public class MysqlJdbcImpl implements JdbcInterface{
@Override
public Object getConnection() {
System.out.println("得到mysql的连接");
return null;
}
@Override
public void crud() {
System.out.println("完成mysql 增删改查");
}
@Override
public void close() {
System.out.println("关闭mysql连接");
}
}
package com.hspedu.jdbc.myJDBC;
public class OracleJdbcImpl implements JdbcInterface{
@Override
public Object getConnection() {
System.out.println("得到oracle的连接");
return null;
}
@Override
public void crud() {
System.out.println("完成oracle 增删改查");
}
@Override
public void close() {
System.out.println("关闭oracle连接");
}
}
用户使用testJDBC
package com.hspedu.jdbc.myJDBC;
public class TestJDBC {
public static void main(String[] args) {
//完成对mysql的操作
JdbcInterface jdbcInterface = new MysqlJdbcImpl();
jdbcInterface.getConnection();//通过接口调用实现类[动态绑定机制]
jdbcInterface.crud();
jdbcInterface.close();
//完成对oraclsql的操作
jdbcInterface = new OracleJdbcImpl();
jdbcInterface.getConnection();//通过接口调用实现类[动态绑定机制]
jdbcInterface.crud();
jdbcInterface.close();
}
}
得到mysql的连接
完成mysql 增删改查
关闭mysql连接
得到oracle的连接
完成oracle 增删改查
关闭oracle连接
3.JDBC API
4.JDBC快速入门
一.JDBC 程序编写步骤
2.获取连接 表示客户端(java程序)到数据库的连接
二.JDBC 第一个程序
获取数据库连接 5 种方式
1 方式 1
package com.hspedu.jdbc;
import com.mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class jdbc01 {
public static void main(String[] args) throws SQLException {
//前置工作:在项目下创建一个文件夹比如1ibs
//将mysql.jar拷贝到该目录下,点击add to project·,加入到项目
//1.注册驱动
Driver driver = new Driver(); //创建Driver对象
//2.得到连接
//(1)jdbc:mysql://规定好协议 ,通过jdbc方式连接mysql
//(2)localhost 主机,也可以是ip地址
//比如说mysql是远程的 而不是本地的 这里是因为Java程序和mysql在同一台机器
//(3)3306表示mysql监听的端口
//(4)mydb2 连接mysql dbms的哪个数据库
//(5)mysql的连接本质是前面学过的socke连接
String url="jdbc:mysql://localhost:3306/mydb2";
//将用户名和密码放入到Properties 对象
Properties properties = new Properties();
//说明user和password是规定好的,后面的值根据实际情况写
properties.setProperty("user", "root"); //用户
properties.setProperty("password", "123456"); //密码
//现在才正式开始获取连接
/* Connection connect(String url, Properties info)
尝试使数据库连接到给定的URL。
Connection类的API
*/
Connection connect = driver.connect(url, properties);
//3.执行sql
//自增长的我们可以用null id是自增长的
/* String sql="insert into actor values(null,'刘德华','男','1970-11-11','110')";*/
String sql="delete from actor where id=1";
//我们真正去通过一个对象执行sql语句是创建一个statement或
/* public interface Statement
extends Wrapper, AutoCloseable
用于执行静态SQL语句并返回其生成的结果的对象。*/
Statement statement = connect.createStatement();
//如果是dml语句 返回值代表受影响的函数
int rows = statement.executeUpdate(sql);
System.out.println( rows>0?"成功":"失败");
//4.关闭连接资源 先关闭statement 再关闭connect
statement.close();
connect.close();
}
}
成功
2 方式 2
package com.hspedu.jdbc;
import com.mysql.jdbc.Driver;
import org.junit.Test;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class JdbcConn {
//方式1
@Test
public void connect01() throws SQLException {
Driver driver = new Driver();
String url="jdbc:mysql://localhost:3306/mydb2";
//将用户名和密码放入到Properties 对象
Properties properties = new Properties();
//说明user和password是规定好的,后面的值根据实际情况写
properties.setProperty("user", "root"); //用户
properties.setProperty("password", "123456"); //密码
Connection connect = driver.connect(url, properties);
System.out.println("方式一"+connect);
}
//方式2
@Test
public void connect02() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
//使用反射加载Driver类 动态加载 更加灵活 减少了依赖性
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
Driver driver =(Driver) aClass.newInstance();
//将用户名和密码放入到Properties 对象
Properties properties = new Properties();
//说明user和password是规定好的,后面的值根据实际情况写
properties.setProperty("user", "root"); //用户
properties.setProperty("password", "123456"); //密码
String url="jdbc:mysql://localhost:3306/mydb2";
Connection connect = driver.connect(url, properties);
System.out.println("方式二"+connect);
}
//方式3 使用DriverManager 替代 Driver进行统一管理
//第三种方式用DriverManager进行统一管理有更好的扩展性
@Test
public void connect03() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
//使用反射加载Driver
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
Driver driver =(Driver) aClass.newInstance();
//创建url和user和password
String url="jdbc:mysql://localhost:3306/mydb2";
String user="root";
String password="123456";
/* static void registerDriver(Driver driver)
注册与给定的驱动程序 DriverManager 。*/
DriverManager.registerDriver(driver); //注册Driver驱动
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println("第三种方式"+connection);
}
//方式4:使用Class.forName 自动完成注册驱动 ,简化代码
//这种方式获取连接是使用的最多的
//Class.java这个文件就已经有静态代码块帮我们做这步操作了
@Test
public void connect04() throws ClassNotFoundException, SQLException {
//使用反射加载Driver
//加载Driver类时,完成注册
/**
* 源码:1.静态代码块 在类加载时 会执行一次
* 2. DriverManager.registerDriver(new Driver());
* 3.因此注册driver的工作已经完成
*static {
* try {
* DriverManager.registerDriver(new Driver());
* } catch (SQLException var1) {
* throw new RuntimeException("Can't register driver!");
* }
* }
*/
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");//这句话也可以省略不过不建议 因为mysql-connector包下文本中的类名称去注册
//创建url和user和password
String url="jdbc:mysql://localhost:3306/mydb2";
String user="root";
String password="123456";
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println("第4中方式 "+connection);
}
//方式5,在方式4的基础上改进,增加配置文件,让连接mysql更加灵活
@Test
public void connect05() throws IOException, ClassNotFoundException, SQLException {
//通过Properties对象获取配置文件的信息
Properties properties=new Properties();
properties.load(new FileInputStream("src/main/java/com/hspedu/mysql.properties"));
//获取相关的值
String user=properties.getProperty("user");
String password=properties.getProperty("password");
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println("方式5"+connection);
}
}
方式一com.mysql.jdbc.JDBC4Connection@12bc6874
方式二com.mysql.jdbc.JDBC4Connection@12bc6874
3 方式 3
4 方式 4
5 方式 5
5.ResultSet底层
package com.hspedu.jdbc.resultset_;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.Properties;
/**
* 演示select 返回ResultSet,并取出结果
*/
@SuppressWarnings({"all"})
public class ResultSet {
public static void main(String[] args) throws Exception{
//通过Properties对象获取配置文件的信息
Properties properties=new Properties();
properties.load(new FileInputStream("src/main/java/com/hspedu/mysql.properties"));
//获取相关的值
String user=properties.getProperty("user");
String password=properties.getProperty("password");
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
//1.注册驱动
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
//2.得到连接
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println("方式5"+connection);
//3.得到Statament
Statement statement = connection.createStatement();
//4.组织sql
String sql="select id,name,sex,borndate from actor";
/* ResultSet executeQuery(String sql)
执行给定的SQL语句 ,该语句返回单个 ResultSet对象。*/
/* mysql> SELECT * FROM actor;
+----+--------+-----+---------------------+-------+
| id | NAME | sex | borndate | phone |
+----+--------+-----+---------------------+-------+
| 2 | 刘德华 | 男 | 1970-12-12 00:00:00 | 110 |
| 3 | jack | 男 | 1990-11-11 00:00:00 | 112 |
+----+--------+-----+---------------------+-------+
2 rows in set (0.01 sec)
这里是没有phone这一栏的 因为select里面没写
*/
java.sql.ResultSet resultSet = statement.executeQuery(sql);
//5.使用while取出数据
/* boolean next()
将光标从当前位置向前移动一行。
让光标向后移动.如果没有更多行,则返回false
*/
/* int getInt(int columnIndex)
这个检索的当前行中指定列的值 ResultSet作为对象 int在Java编程语言。
ResultSet对象结构
*/
while (resultSet.next()){
int id=resultSet.getInt(1);
String name= resultSet.getString(2);
String sex = resultSet.getString(3);
Date date = resultSet.getDate(4);
System.out.println(id+"\t"+name+"\t"+sex+"\t"+date);
}
//6.关闭连接
resultSet.close();
statement.close();
connection.close();
}
}
2 刘德华 男 1970-12-12
3 jack 男 1990-11-11
rowData代表所有行 elemData黄色0表示其中一行 蓝色0代表其中第一列 且所有行是Arraylist来存储的
6.SQL注入
一.Statement方式
package com.hspedu.jdbc.statement;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
import java.util.Scanner;
@SuppressWarnings({"all"})
public class Statement_ {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
//让用户输入管理员名和密码
System.out.print("请输入管理员名字:"); //next():当接收到空格或者'就是表示结束
String admin_name=scanner.nextLine(); //老师说明 如果希望看到SQL注入 这里需要nextLine 回车才会结束
System.out.print("请输入管理员密码");
String admin_pwd=scanner.nextLine();
//通过Properties对象获取配置文件的信息
Properties properties=new Properties();
properties.load(new FileInputStream("src/main/java/com/hspedu/mysql.properties"));
//获取相关的值
String user=properties.getProperty("user");
String password=properties.getProperty("password");
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
//1.注册驱动
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
//2.得到连接
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println("方式5"+connection);
//3.得到Statament
Statement statement = connection.createStatement();
//4.组织sql
String sql="select name,pwd from admin where name='"+admin_name+"' and pwd='"+admin_pwd+"'";
ResultSet resultSet = statement.executeQuery(sql);
if (resultSet.next()){//如果查询一条记录,则说明该管理存在
System.out.println("恭喜,登陆成功");
}else{
System.out.println("对不起,登陆失败");
}
//关闭
}
}
请输入管理员名字:1’ or
请输入管理员密码or ‘1’='1
方式5com.mysql.jdbc.JDBC4Connection@41906a77
恭喜,登陆成功
二.PreparedStatement方式(预处理方式)
(1) 对于DML select语句 用executeQuery()方法
package com.hspedu.jdbc.preparestatement;
import java.io.FileInputStream;
import java.sql.*;
import java.util.Properties;
import java.util.Scanner;
/**
* 演示preparedStatement
*
*/
@SuppressWarnings({"all"})
public class PreparedStatement_ {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
//让用户输入管理员名和密码
System.out.print("请输入管理员名字:"); //next():当接收到空格或者'就是表示结束
String admin_name=scanner.nextLine(); //老师说明 如果希望看到SQL注入 这里需要nextLine 回车才会结束
System.out.print("请输入管理员密码");
String admin_pwd=scanner.nextLine();
//通过Properties对象获取配置文件的信息
Properties properties=new Properties();
properties.load(new FileInputStream("src/main/java/com/hspedu/mysql.properties"));
//获取相关的值
String user=properties.getProperty("user");
String password=properties.getProperty("password");
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
//1.注册驱动
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
//2.得到连接
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println("方式5"+connection);
//3.得到PreparedStatament
//3.1组织sqL,sql语句的?相当于占位符
String sql="select name,pwd from admin where name=? and pwd=?";
//3.2preparedStatement 对象实现了PreparedStatement接口的实现类的对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//3.3 给?赋值
preparedStatement.setString(1,admin_name);
preparedStatement.setString(2, admin_pwd);
//4.执行select语句使用 executeQuery
//如果执行的是dml(update,insert,delete) executeUpdate()
//这里执行 executeQuery,不啊哟再写sql了
/* ResultSet resultSet = preparedStatement.executeQuery(sql); 这样写有sql参数是错误的,因为已经被处理过了*/
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()){//如果查询一条记录,则说明该管理存在
System.out.println("恭喜,登陆成功");
}else{
System.out.println("对不起,登陆失败");
}
//关闭
resultSet.close();
preparedStatement.close();
connection.close();
}
}
请输入管理员名字:1’ or
请输入管理员密码or ‘1’='1
方式5com.mysql.jdbc.JDBC4Connection@41906a77
对不起,登陆失败
(2)DML语句 dml(update,insert,delete) 用 executeUpdate() 方法
package com.hspedu.jdbc.preparestatement;
import java.io.FileInputStream;
import java.sql.*;
import java.util.Properties;
import java.util.Scanner;
/**
* 演示preparedStatement
*
*/
@SuppressWarnings({"all"})
public class PreparedStatement_ {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
//让用户输入管理员名和密码
System.out.print("请输入管理员名字:"); //next():当接收到空格或者'就是表示结束
String admin_name=scanner.nextLine(); //老师说明 如果希望看到SQL注入 这里需要nextLine 回车才会结束
System.out.print("请输入管理员密码");
String admin_pwd=scanner.nextLine();
//通过Properties对象获取配置文件的信息
Properties properties=new Properties();
properties.load(new FileInputStream("src/main/java/com/hspedu/mysql.properties"));
//获取相关的值
String user=properties.getProperty("user");
String password=properties.getProperty("password");
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
//1.注册驱动
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
//2.得到连接
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println("方式5"+connection);
//3.得到PreparedStatament
//3.1组织sqL,sql语句的?相当于占位符
String sql="select name,pwd from admin where name=? and pwd=?";
//3.2preparedStatement 对象实现了PreparedStatement接口的实现类的对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//3.3 给?赋值
preparedStatement.setString(1,admin_name);
preparedStatement.setString(2, admin_pwd);
//4.执行select语句使用 executeQuery
//如果执行的是dml(update,insert,delete) executeUpdate()
//这里执行 executeQuery,不啊哟再写sql了
/* ResultSet resultSet = preparedStatement.executeQuery(sql); 这样写有sql参数是错误的,因为已经被处理过了*/
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()){//如果查询一条记录,则说明该管理存在
System.out.println("恭喜,登陆成功");
}else{
System.out.println("对不起,登陆失败");
}
//关闭
resultSet.close();
preparedStatement.close();
connection.close();
}
}
请输入管理员名字:hsp
请输入管理员密码123456
方式5com.mysql.jdbc.JDBC4Connection@41906a77
执行成功
7.JDBC_API
有时候我们可能仅需要创建表 删除表 不需要返回结果或增删改
用execute这个方法就可以了