JDBC
JDBC简介
JDBC概念
-
定义:JDBC就是使用java语言操作关系型数据库的一套API
-
全称:(Java DataBase Connectivity) Java数据库连接
JDBC本质
- 官方(sun公司)定义的一套操作所有关系型数据库的规则。即接口
- 各个数据库厂商去实现这套接口,提供数据库驱动jar包
- 我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类
JDBC好处
- 各数据库厂商使用相同的接口。Java代码不需要针对不同数据库分别开发
- 可随时替换底层数据库,访问数据库点的Java代码基本不变。
JDBC快速入门
步骤
-
1.创建工程,导入驱动jar包
-
2.注册驱动
Class.forName("com.mysql.jdbc.Driver");
- 2.获取连接
Connection conn=DriverManager.getConnection(url,usename,password);
- 3.定义SQL语句
String sql="update......";
- 4.获取执行SQL对象
Statement stm=conn.createStatement();
- 5.执行SQL
stm.executeUpdate(sql);
-
6.处理返回结果
-
7.释放资源
完整实例
public static void jdbcTest() throws Exception {
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
String username="root"; //数据库用户名称
String password="123456"; //数据库用户密码
String url="jdbc:mysql://localhost:3306/bd"; //格式统一————————jdbc:mysql://IP:端口//数据库的名称
Connection conn= DriverManager.getConnection(url,username,password);
//定义sql语句
String sql="update xiao set tel='88888' where id=2";
//获取执行sql对象satement对象
Statement statement = conn.createStatement();
//执行sql
int i = statement.executeUpdate(sql); //返回值为影响的行数
System.out.println(i);
//释放资源
statement.close();
conn.close();
}
JDBC API详解
-
DriverManager(驱动管理类)作用:
-
1.注册驱动
Class.forName(com.mysql.jdbc.Driver);
查看Driver源码
static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); } }
提示:
- MySQL 5之后的驱动包,可以省略注册驱动的步骤
- 自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类
-
2.获取数据库连接
获取的方法:
static Connection getConnection(String url,String username,String password);
参数:
1.url:连接路径
语法:jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2…
示例:jdbc:mysql://127.0.0.1:3306/db1
细节:
-
如果连接的是本机mysql服务器,并且mysql服务器默认端口是3306,则url可以简写为:jdbc:mysql://数据库名称?参数键值对1&参数键值对2…
-
配置useSSL=false参数,禁用安全连接方式,解决警告提示
例如:
String url="jdbc:mysql://localhost:3306/bd?useSSL=false";
2.username:用户名
3.password:密码
-
-
-
Connection(数据库连接对象)作用:
1.获取执行SQL的对象
-
普通执行SQL对象
Statement createStatement();
-
预编译SQL的执行SQL对象:防止SQL注入
PreparedStatement prepareStatement(sql);
-
执行存储过程的对象
CallableStatement prepareCall(sql);
2.管理事务
-
MySQL事务管理
开启事务:BEGIN;START TRANSACTION;
提交事务:COMMIT;
回滚事务:ROLLBACK;
MySQL默认自动提交事务
-
JDBC事务管理:Connection接口中定义了3个对应得方法
开启事务:setAutoCommit(boolean autoCommit):true为自动提交事务,即为开启事务
提交事务:commit()
回滚事务:rollback()
-
实例
public static void jdbcTest() throws Exception { //注册驱动 Class.forName("com.mysql.jdbc.Driver"); //获取连接 String username="root"; //数据库用户名称 String password="123456"; //数据库用户密码 String url="jdbc:mysql://localhost:3306/bd?useSSL=false"; //格式统一————————jdbc:mysql://IP:端口//数据库的名称 Connection conn= DriverManager.getConnection(url,username,password); //获取执行sql对象satement对象 Statement statement = conn.createStatement(); try { //开启事务 conn.setAutoCommit(false); //true为自动提交 //定义sql语句 String sql1="update xiao set tel='88888' where id=2"; String sql2="update xiao set tel='22222565' where id=2"; //执行sql int i = statement.executeUpdate(sql1); //返回值为影响的行数 System.out.println(i); int i1 = statement.executeUpdate(sql2); System.out.println(i1); //事务提交 conn.commit(); } catch (Exception e) { //回滚事务 conn.rollback(); e.printStackTrace(); } //释放资源 statement.close(); conn.close(); }
-
-
Statement
1.Statement作用:
- 执行SQL语句
2.执行SQL语句
int executeUpdate(sql); //执行DML,DDL语句 //返回值:(1)DML语句影响的行数。(2)DDL语句执行后,执行成功也可以1返回0
ResultSet executeQuery(sql); //执行DQL语句 //返回值:ResultSet结果集对象
3.实例
public static void DDL_JDBC_Test() throws ClassNotFoundException, SQLException { //注册驱动 Class.forName("com.mysql.jdbc.Driver"); //创建连接 String username="root"; //数据库用户名称 String password="123456"; //数据库用户密码 String url="jdbc:mysql://localhost:3306/?useSSL=false"; Connection connection = DriverManager.getConnection(url, username, password); //创建执行SQL对象 Statement statement = connection.createStatement(); //sql语句 String sql="create database tt"; //执行sql语句 int i = statement.executeUpdate(sql); if (i>0){ System.out.println("创建成功"); }else { System.out.println("创建失败"); } //关闭 statement.close(); connection.close(); }
-
ResultSet
-
ResultSet(结果集对象)作用:
1.封装了DQL查询语句的结果
ResultSet executeQuery(sql); //执行DQL语句,返回ResultSet对象
-
获取查询结果
boolean next(); //(1)将光标从当前位置向前移动一行 (2)判断当前行是否为有效行 //返回值:true:有效行,当前行有数据。 false:无效行,当前行没有数据。
xxx getXxx(参数); //获取数据 //xxx:数据类型:如 int getInt(参数) String getString(参数) //参数: //int :列的编号,从1开始 //String :列的名称
使用步骤
1.游标向下移动一行,并判断该行是否有数据:next()
2.获取数据:getXxx(参数)
//循环判断游标是否是最后一行末尾 while(rs.next()){ //获取数据 rs.getXxx(参数); }
-
实例
public static void DQL_JDBC_Test() throws ClassNotFoundException, SQLException { //注册驱动 Class.forName("com.mysql.jdbc.Driver"); //创建连接 String username="root"; //数据库用户名称 String password="123456"; //数据库用户密码 String url="jdbc:mysql://localhost:3306/bd?useSSL=false"; Connection connection = DriverManager.getConnection(url, username, password); //创建执行SQL对象 Statement statement = connection.createStatement(); //sql语句 String sql="select * from xiao"; //执行sql语句 ResultSet resultSet = statement.executeQuery(sql); while (resultSet.next()){ int id = resultSet.getInt(1); String name = resultSet.getString(2); System.out.print(id+" "); System.out.println(name); } //关闭 statement.close(); connection.close(); }
-
-
PreparedStatement
1.PreparedStatement作用:
-
预编译SQL语句并执行:预防SQL注入问题
a.获取PreparedStatement对象
//SQL语句中的参数值,使用?占位符替代 String sql="select * from user where usename=? and password=?"; //通过Connection对象获取,并传入对应的sql语句 PreparedStatement pstmt=conn.prepareStatement(sql);
b.设置参数值
PreparedStatement对象:setXxx(参数1,参数2):给?赋值
1.Xxx:数据类型:如setInt(参数1,参数2)
2.参数:- 参数1:?的位置编号,从1开始
- 参数2:?的值
c.执行SQL
executeUpdate(); /executeQuery(); :不需要再转递sql
2.SQL注入
- SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法
3.PreparedStatement原理
-
PreparedStatement好处:
a.预编译SQL,性能更高
b.防止SQL注入,将敏感字符转义
1.PreparedStatement :预编译功能开启:useServerPrepStmts=true
2.配置MySQL执行日志(重启mysql服务后生效)
log-ouyput=FLFE general-log=1 general_log_file="mysql.log的路径" slow-query-log=1 slow_query_log_file="mysql_slow.log的路径" long_query_time=2
-
PreparedStatement原理:
1.在获取Preparedment对象时,将sql语句发送给mysql服务器,进行检查,编译(这些步骤很耗时)
2.执行时就不用进行这些步骤,速度更快
3.如果sql模板一样,则只需要进行一次检查,编译
-
-
实例
public void PreparedStatement() throws Exception { //注册驱动 Class.forName("com.mysql.jdbc.Driver"); //获取连接 String url="jdbc:mysql:///bd?useSSL=false"; String user="root"; String password="123456"; Connection conn=DriverManager.getConnection(url,user,password); //sql语句 String sql="update xiao set tel=? where id=?"; //获取执行sql对象 PreparedStatement p = conn.prepareStatement(sql); //给?赋值 String tel="4545454554"; String id="1"; p.setString(1,tel); p.setString(2,id); //执行sql语句 int i = p.executeUpdate(); if (i>0){ System.out.println("修改成功!"); }else{ System.out.println("修改失败!"); } //释放资源 p.close(); conn.close(); }
数据库连接池
-
数据库连接池简介
- 数据库连接池是个容器,负责分配,管理数据库连接(Connection)
- 它允许应用程序重复使用一个现有的数据库连接,而不是再重复建立一个
- 释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
- 好处:
- 资源重用
- 提升系统响应速度
- 避免数据库连接遗漏
-
数据库连接池实现
-
标准接口 DataSource
-
官方(SUN)提供的数据库连接池标准接口,由第三方组织实现此接口
-
功能:获取连接
Connection getConnection()
-
-
常见的数据库连接池:
- DBCP
- C3P0
- Druid
-
Druid(德鲁伊)
- Druid连接池是阿里巴巴开源的数据库连接池项目
- 功能强大,性能优秀,是java语言最好的数据库连接池之一
-
-
Druid数据库连接池
-
使用步骤
1.导入jar包druid.jar(可以选择版本)
2.定义配置文件
3.加载配置文件
4.获取数据库连接池对象
5.获取连接
-
-
实例
public static void main(String[] args) throws Exception { //定义配置文件 //加载配置文件 Properties properties = new Properties(); properties.load(new FileInputStream(new File("src/JDBC/druid.properties.properties"))); //获取连接池 DataSource ds= DruidDataSourceFactory.createDataSource(properties); //获取连接 Connection connection = ds.getConnection(); //sql语句 String sql="select * from dog"; //获取执行ProparedStatement对象 PreparedStatement preparedStatement = connection.prepareStatement(sql); //获取所有对象集合 ResultSet resultSet = preparedStatement.executeQuery(); //存放dog的集合 List<dog> dogs=new ArrayList<>(); //定义dog对象 dog d=null; while(resultSet.next()){ d=new dog(); //狗的id int id = resultSet.getInt("id"); //狗的名字 String name = resultSet.getString("name"); //狗的年龄 int age = resultSet.getInt("age"); //狗的生日 String brithday = resultSet.getString("brithday"); //给dog对象赋值 d.setId(id); d.setName(name); d.setAge(age); d.setBrithday(brithday); //将dog添加到集合中 dogs.add(d); } System.out.println("添加成功"); for (dog a:dogs) { System.out.println(a); } //释放资源 preparedStatement.close(); connection.close(); }
-
dog类
package JDBC; public class dog { private int id; private String name; private int age; private String brithday; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getBrithday() { return brithday; } public void setBrithday(String brithday) { this.brithday = brithday; } @Override public String toString() { return "dog{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", brithday='" + brithday + '\'' + '}'; } }
-
配置文件
url=jdbc:mysql://localhost:3306/bd?useSSL=false username=root password=123456 #?????? initialSize=5 #????? maxActive=10 #?????? maxWait=3000