JDBC
概念
概念:Java DataBase Connectivity Java 数据库连接, Java语言操作数据库
本质:官方定义了操作所有关系型数据库的规则(接口)
各个数据库厂商实现接口,提供数据库驱动jar包,我们可以使用这套接口编程,真正执行的代码是驱动jar包中的实现类
入门使用
步骤:
1.导入驱动jar包
2.注册驱动
3.获取数据库连接对象 Connection
4.定义sql
5.获取执行sql语句的对象Statement
6.执行sql,接收返回结果
7.处理结果
8.释放资源
实现:
1.导入驱动jar包(复制到目录下)
右击选择添加到项目空间
public class jdbc {
public static void main(String[] args) throws Exception {
//1.导入jar包
//2.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//3.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root");
//4.定义sql语句
String sql = "update user_t set age = 10 where id = 1";
//5.获取执行sql对象,Statement
Statement stmt = conn.createStatement();
//6.执行sql
int count = stmt.executeUpdate(sql);
//处理结果
System.out.println(count);
//8.释放资源
stmt.close();
conn.close();
}
}
1
详解各个对象:
1.DriverManager:驱动管理对象
功能:
1).注册驱动:告诉程序该使用哪一个数据库驱动jar
static void registerDrive(Drive drive):注册与给定的驱动程序
写代码使用:Class.forName(“com.mysql.cj.jdbc.Driver”);
注意:myaql5之后驱动ja包可以省略注册驱动的步骤
2).获取数据库连接:
方法 static Connection getConnection(String urlm , String user ,String password )
参数:
url:指定连接路径
语法:jdbc:mysql://IP地址(域名): 端口号/数据库名称
例子:
onnection conn =DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root");*
注意:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql://l/db3
user:用户名
password 密码**
2.Connection:数据库连接对象
1.功能:
1)执行sql的对象
Statement createStatement()
PreparedStatement prepareStatement(String sql)
2)管理事务
-
开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务
-
提交事务:commit()
回滚事务:rollback()
3.Statement:执行sql对象
1)执行sql:
-
boolean execute(String sql):true如果第一个结果是一个ResultSet对象; false如果第一个结果是更新计数或没有结果
-
int executeUpdate(String sql):执行在该SQL语句PreparedStatement对象,它必须是一个SQL数据操纵语言(DML)语句,如INSERT , UPDATE或DELETE ; 或不返回任何内容的SQL语句,例如DDL语句。返回值为影响的行数
-
ResultSet executeQuery(String sql):执行此 PreparedStatement对象中的SQL查询,并返回查询 PreparedStatement的 ResultSet对象。返回一个结果集对象
4.ResultSet:结果集对象
1)next():游标向下移动
2)getXxx(参数):获取数据
- Xxx代表数据类型
- 参数:
int代表编号
String 代表列名称
3)使用步骤
- 游标向下移动一行
- 判断是否有数据
- 获取数据
4)
5.PreparedStatement:执行sql对象
1)sql注入问题,在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全性问题
- 用户输入的内容形成了新的sql语句
- 导致sql语言错误
2)解决sql注入问题:使用PreparedStatement解决
- 参数使用?作为占位符
3)步骤
-
1.导入驱动jar包
-
2.注册驱动
-
3.获取数据库连接对象 Connection
-
4.定义sql
使用?作为占位符。例如:select * form user where id= ?and name = ?; -
5.获取执行sql语句的对象PreparedStatement Connection.prepareStatement(String sql)
-
6.给?赋值:
setXxx(参数1:,参数2):参数1:?的位置,参数2:?的值 -
7.执行sql,接收返回结果
-
8.处理结果
-
9.释放资源
增删改例子
package JDBC;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBC02 {
public static void main(String[] args) {
//1.注册驱动
Statement stmt = null;
Connection conn = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
//添加一条记录
//String sql = "insert into user_t values(null,'刘德华','1855',30)";
//修改一条记录
// String sql = "update user_t set address ='风娃娃' where id = 1 ";
//修改一条记录
String sql = "delete from user_t where id = 2";
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root");
stmt = conn.createStatement();
int count = stmt.executeUpdate(sql);
System.out.println(count);
if(count>0){
System.out.println("添加成功");
}
else{
System.out.println("添加失败");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
1
添加成功
遍历
package JDBC;
import java.sql.*;
public class JDBC02 {
public static void main(String[] args) {
//1.注册驱动
Statement stmt = null;
Connection conn = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
//添加一条记录
//String sql = "insert into user_t values(null,'刘德华','1855',30)";
//修改一条记录
// String sql = "update user_t set address ='风娃娃' where id = 1 ";
//修改一条记录
//String sql = "delete from user_t where id = 2";
//查询
String sql = "select * from user_t ";
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root");
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
//循环判断游标是否为末尾
while(rs.next()){
System.out.print(rs.getInt(1));
System.out.print(rs.getString(2));
System.out.print(rs.getString(3));
System.out.println(rs.getInt(4));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
正规遍历例子
学生类:
package JDBC;
public class Stu {
int id;
String address;
String name;
int age;
public Stu(String address, String name, int age) {
this.address = address;
this.name = name;
this.age = age;
}
public Stu() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
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;
}
@Override
public String toString() {
return "Stu{" +
"id=" + id +
", address='" + address + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
查询方法
package JDBC;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class jdbc03 {
public List<Stu> findall(){
Statement stmt = null;
Connection conn = null;
ResultSet rs = null;
Stu stu = null;
List<Stu> list = new ArrayList<Stu>();
try {
Class.forName("com.mysql.cj.jdbc.Driver");
//添加一条记录
//String sql = "insert into user_t values(null,'刘德华','1855',30)";
//修改一条记录
// String sql = "update user_t set address ='风娃娃' where id = 1 ";
//修改一条记录
//String sql = "delete from user_t where id = 2";
//查询
String sql = "select * from user_t ";
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root");
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
//循环判断游标是否为末尾
while(rs.next()){
int id = rs.getInt("id");
String address = rs.getString("address");
String name = rs.getString("name");
int age = rs.getInt("age");
stu = new Stu();
stu.setId(id);
stu.setAddress(address);
stu.setName(name);
stu.setAge(age);
list.add(stu);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
return list;
}
}
测试类:
public class deom {
public static void main(String[] args) {
jdbc03 n = new jdbc03();
List<Stu> m = n.findall();
System.out.println(m.toString());
}
}
[Stu{id=1, address='风娃娃', name='张泽培', age=10}, Stu{id=6, address='内蒙古', name='付鹤', age=20}, Stu{id=7, address='内蒙古', name='牛魔', age=20}]
抽取工具类
1.抽取工具类
package JDBC;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class gongjvl {
//只有静态变量才能被静态方法访问
private static String url;
private static String user;
private static String password;
private static String driver;
//文件的读取,只需要读去一次,使用静态代码块
static {
//通过Properties集合类读取文件
try {
// 创建Properties
Properties pro = new Properties();
//获取src路径下的文件方式--》ClassLoader 类加载器
ClassLoader classLoader = gongjvl.class.getClassLoader();
URL res = classLoader.getResource("jdbc02.properties");
//获得字符串路径
String path = res.getPath();
// System.out.println(path);
//加载文件
pro.load(new FileReader(path));
//获取属性
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//注册驱动
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
public static void closs(Statement stmt,Connection conn){
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
2.使用
package JDBC;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class jdbc03 {
public List<Stu> findall(){
Statement stmt = null;
Connection conn = null;
ResultSet rs = null;
Stu stu = null;
List<Stu> list = new ArrayList<Stu>();
//添加一条记录
//String sql = "insert into user_t values(null,'刘德华','1855',30)";
//修改一条记录
// String sql = "update user_t set address ='风娃娃' where id = 1 ";
//修改一条记录
//String sql = "delete from user_t where id = 2";
//查询
try {
String sql = "select * from user_t ";
//使用工具类
conn = gongjvl.getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
//循环判断游标是否为末尾
while(rs.next()){
int id = rs.getInt("id");
String address = rs.getString("address");
String name = rs.getString("name");
int age = rs.getInt("age");
stu = new Stu();
stu.setId(id);
stu.setAddress(address);
stu.setName(name);
stu.setAge(age);
list.add(stu);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
//使用工具类
gongjvl.closs(stmt,conn);
}
return list;
}
}
sql注入问题
1.输入的语句和原有的sql语句组成了新的sql命令,造成安全问题
2.解决sql注入问题:使用PreparedStatement
3.预编译的sql:参数使用?作为占位符
public class jdbc03 {
public List<Stu> findall(){
int i = 1;
int n = 10;
PreparedStatement pstmt = null;
Connection conn = null;
ResultSet rs = null;
Stu stu = null;
List<Stu> list = new ArrayList<Stu>();
//添加一条记录
//String sql = "insert into user_t values(null,'刘德华','1855',30)";
//修改一条记录
// String sql = "update user_t set address ='风娃娃' where id = 1 ";
//修改一条记录
//String sql = "delete from user_t where id = 2";
//查询
try {
String sql = "select * from user_t where id= ? and age = ?";
conn = gongjvl.getConnection();
pstmt = conn.prepareStatement(sql);
//给?赋值
pstmt.setInt(1,i);
pstmt.setInt(2,n);
//执行查询
rs = pstmt.executeQuery();
//循环判断游标是否为末尾
while(rs.next()){
int id = rs.getInt("id");
String address = rs.getString("address");
String name = rs.getString("name");
int age = rs.getInt("age");
stu = new Stu();
stu.setId(id);
stu.setAddress(address);
stu.setName(name);
stu.setAge(age);
list.add(stu);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
gongjvl.closs(pstmt,conn);
}
return list;
}
}
JDBC控制事务
1事务:一个事务包括多个步骤的业务操作。如果这个业务操作被事务管理,则多个步骤要么同步成功,要么同步失败
2.操作:
-
开启事务 :conn.setAutoCommit(false);
在执行sql前开启事务 -
提交事务 :conn.commit();、
当所有事务执行完毕提交事务 -
回滚事务:conn.rollback();}
在catch中回滚事务
3.使用Connction对象来管理事务
代码不规范,只作为案例
public class JDBC10 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
PreparedStatement pstmt2 = null;
try {
//获取连接
conn = gongjvl.getConnection();
//开启事务
conn.setAutoCommit(false);
//定义接口
String sql = "update user_t set age = age -? where id=?";
String sql2 = "update user_t set age = age +? where id=?";
pstmt = conn.prepareStatement(sql);
pstmt2 = conn.prepareStatement(sql2);
//设置参数
pstmt.setInt(1,10);
pstmt.setInt(2,1);
pstmt2.setInt(1,20);
pstmt2.setInt(2,6);
//执行sql
int i = pstmt.executeUpdate();
int n =3/0;
int i1 = pstmt2.executeUpdate();
//提交事务
conn.commit();
} catch (Exception throwables) {
//事务回滚
try {
if(conn!=null){
conn.rollback();}
} catch (SQLException e) {
e.printStackTrace();
}
throwables.printStackTrace();
}finally {
gongjvl.closs(pstmt,conn);
gongjvl.closs(pstmt2,null);
}
}
数据库连接池
1.概念: 就是一个容器(集合),存放数据库连接的容器。当系统初始化好后,容器被创建,容器会申请一些连接对象,当用户来访问数据时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器
2.好处:
- 节约资源
- 访问高效
3.实现:
3.1标准接口:DataSource java。sql包下的
方法:
- 获取连接:getConnetion()
- 归还连接:如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接
3.2. - 般我们不去实现它,有数据库厂商来实现,
- C3P0 :数据库连接池技术
- Druid:数据库连接池实现技术,由阿里巴巴提供的
4.c3po:数据库连接技、
4.1 步骤
- 导入jar包(两个)c3p0-0.9.5.5和mysql-connector-java-8.0.23
- 定义配置文件c3p0.properties 或者 c3p0-config.xml
注意:文件名不能改变
路径:直接将文件放在src目录下即可 - 创建核心对象 数据库连接池对象 ComboPooledDataSource
- 获取连接:getConnection
c3p0-config.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<!-- 连接参数 -->
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db3</property>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">root</property>
<!-- 连接池参数 -->
<!-- 超时时间 -->
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<!-- 初始化申请的数量 -->
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<!-- 最大的连接数量 -->
<property name="maxPoolSize">100</property>
<!-- 最小连接的数量 -->
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</default-config>
</c3p0-config>
getConnection():获得连接
close():归还连接
public class c3p0demo01 {
public static void main(String[] args) throws SQLException {
// 1.创建数据库连接池对象,不传参数就使用默认,添加参数(连接池名称,选择对应的连接池)
DataSource ds = new ComboPooledDataSource();
//2.获取连接对象
Connection conn = ds.getConnection();
System.out.println(conn);
}
}
4.Druid:数据库连接技、
数据库连接池实现技术,由阿里巴巴提供
4.1 步骤
- 1.导入jar包druid-1.0.9.jar
- 2.定义配文件:
*是properties形式的
*可以叫任意名称,可以放在任意目录下 - 3.加载配ri文件。Properties方法
- 4.获取数据库连接池对象:通过工厂来来获取DruidDataSourceFactory
- 5.获取连接: getConnection
druid.properties文件
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/db3
username=root
password = root
#初始胡连接数量
initialSize=5
#最大连接数
maxActive=10
#最大等待时间
maxWait=3000
maxIdle=8
minIdle=3
package Druid;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;
public class Druiddome {
public static void main(String[] args) throws Exception {
//加载配置文件
Properties pro = new Properties();
InputStream is = Druiddome.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//获取连接池对象
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
//获取连接
Connection conn = ds.getConnection();
System.out.println(conn);
}
}
5.连接池定义工具类
5.1。定义一个JDBCUtils
5.2.提供方法
- 1.获取连接方法:通过数据库连接池获取连接
- 2.释放资源
- 3.获取连接池的方法
package utils;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class gongjvl {
//只有静态变量才能被静态方法访问
private static String url;
private static String user;
private static String password;
private static String driver;
//文件的读取,只需要读去一次,使用静态代码块
static {
//通过Properties集合类读取文件
try {
// 创建Properties
Properties pro = new Properties();
//获取src路径下的文件方式--》ClassLoader 类加载器
ClassLoader classLoader = gongjvl.class.getClassLoader();
URL res = classLoader.getResource("jdbc02.properties");
//获得字符串路径
String path = res.getPath();
System.out.println(path);
//加载文件
pro.load(new FileReader("D:\\私人文件\\大三下\\woek\\out\\production\\day05\\jdbc02.properties"));
//获取属性
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//注册驱动
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
public static void closs(Statement stmt,Connection conn){
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
Druid工具类的使用
package Druid;
import com.alibaba.druid.util.JdbcUtils;
import utils.utilJDBC;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
//使用新的工具类
//完成添加操作,添加一条记录
public class Druiddome02 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstm = null;
try {
//1.获取连接
conn = utilJDBC.getConnection();
//2.定义sql
String sql = "insert into user_t values(null,?,?,?)";
//3.获取pstm对象
pstm = conn.prepareStatement(sql);
//4.给?赋值
pstm.setString(1,"王五");
pstm.setString(2,"中国");
pstm.setInt(3,20);
//执行sql
int i = pstm.executeUpdate();
System.out.println(i);
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
//释放资源、
utilJDBC.dclose(pstm,conn);
}
}
}
JDBCTemplate
spring JDBC
- Spring 框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
步骤
1.导入jar包
2.创建JdbcTemplate对象。 依赖于数据源DataSource
- JdbcTemplate template = new Jdbc Template(ds);
3.调用JdbcTemplate的方法来完成CRUD的操作
- update():执行DML语句。增、劃、改语句
- queryForMap():查询结果将结果集封装为map集合
- queryForlist():查询结果将结果集封装为list集合
- query():查询结果,将结果封装为JavaBean对象
- queryForobject :查询结果,将结果封装为对象