jdbc Java操作数据库的语言,在Java编写的项目中连接数据库
jdbc就是一套接口,实现与数据库的连接,但是接口我们是不能直接用的,因此需要JDBC 的实现类--------驱动。
**
**
1.导入包:需要包含包含数据库编程所需的JDBC类的包。使用Java语言的import语句在Java代码开头位置导入所需的类。 大多数情况下,使用import java.sql.*就足够了。
2.注册JDBC驱动程序:需要初始化驱动程序,以便可以打开与数据库的通信通道。使JVM将所需的驱动程序实现加载到内存中,从而可以满足JDBC请求
3.数据库URL配置:
创建一个正确格式化的地址,指向要连接到的数据库(如:MySQL,Oracle和MSSQL等等)。
3.打开一个连接:(创建连接对象)
需要使用DriverManager.getConnection()方法创建一个Connection对象,建立实际的数据库连接,它表示与数据库的物理连接。
4.执行查询:需要使用类型为Statement的对象来构建和提交SQL语句到数据库。
5.从结果集中提取数据:需要使用相应的ResultSet.getXXX()方法从结果集中检索数据。
6.清理环境:需要明确地关闭所有数据库资源,而不依赖于JVM的垃圾收集。
驱动:
jdbc 的实现类,有类才可以使用相关的接口实现对数据库的连接和操作。这是由数据库厂商提供。有了操作规范,就可以实现对不同的数据库的操作,只要更改底层的实现类就可以了
JDBC 的驱动程序:
JDBC驱动程序在JDBC API中实现定义的接口。用于与数据库服务器进行交互。例如,使用JDBC驱动程序,可以通过发送SQL或数据库命令,然后使用Java接收结果来打开数据库连接并与数据库进行交互。JDK附带的Java.sql包包含各种类,其类的行为被定义,实现在第三方驱动程序中完成。 第三方供应商在其数据库驱动程序中实现java.sql.Driver接口。
1.在代码中不写main() 函数入口,使用junit 单元测试
要求:
方法是公共的(public void xxx(){//没有参数
})
在方法上添加@test
import org.junit.Test;//使用 @Test 要导入包
public class Demo1 {
@Test
public void f1(){
System.out.println("我又回来写Java了!!");
}
}
运行junit 测试单元:函数名上右击,选择run (运行)
虽然没有写main() 方法,但是这个测试单元的底层用的还是main方法
需要导入的jar包,不是在代码中导入,而是直接在web 项目中导入
@Test
public void fi() throws Exception {
注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");//加上cj 是更加符合现在的版本,不加也可以但是会有警告
获取连接!!!!
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1?serverTimezone=GMT%2B8","root","123");
编写sql//sql 语句是一个字符串
String sql = "select * from emp;";
创建语句执行者
PreparedStatement st = conn.prepareStatement(sql); //通过连接,创建执行者
设置参数
要往数据库中添加的数据
执行sql
ResultSet rs = st.executeQuery(); //执行者进行执行操作
处理结果
while(rs.next()){
System.out.println(rs.getString("ename")+"::"+rs.getString("sal"));
}
释放资源 先打开后关闭
rs.close();
st.close();
conn.close();
}
示例代码:向数据库中插入数据(存储数据)
1.将注册驱动,获取连接,资源释放,封装在一个类中(工具类)
2.插入数据
public class jdbc_until {
public static Connection getConn() throws ClassNotFoundException, SQLException {//将异常抛出
Class.forName("com.mysql.cj.jdbc.Driver");
获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1?serverTimezone=GMT%2B8","root","123");
return conn;
}
public static void closeResource(Connection conn, Statement st, ResultSet rs){
先创建的后释放
closeResult(rs);
closeStatement(st);
closeConn(conn);
}
/**
* 释放连接资源
* @param conn
*/
public static void closeConn(Connection conn){
if(conn!=null){ 在释放资源的时候都要考虑到资源对象为空的情况
try { 关闭会出现异常
conn.close();
}catch(Exception e){
}
conn=null; 无论是否关闭成功都将conn 设置为null 空对象会被Java的垃圾回收机制,快速的回收处理
}
}
public static void closeStatement(Statement st){
if(st!=null){ 关闭会出现异常
try {
st.close();
}catch(Exception e){
}
st=null; 无论是否关闭成功都将conn 设置为null 空对象会被Java的垃圾回收机制,快速的回收处理
}
}
public static void closeResult(ResultSet rs){
if(rs!=null){ 关闭会出现异常
try {
rs.close();
}catch(Exception e){
}
rs=null; 无论是否关闭成功都将conn 设置为null 空对象会被Java的垃圾回收机制,快速的回收处理
}
}
}
在代码中我们每一次都要注册驱动,获取连接,当我们换数据库的时候,我们为您就要更改工具类中的数据,但是在之后我们是看不见Java文件的只能得到.class 文件,所以如果要修改源代码中的字符串,就要将.class 文件转为.java 文件,修改后再转为.class 文件,这样就十分麻烦,所以解决办法是:
将字符串抽取出来,保存到配置文件中
常见的配置文件:
1.properties:
集合Properties 是map 的一个接口。里面的值 key=value
将注册驱动,获取连接的字符串存储在这个文件中。需要去读文件时,非常麻烦。所以使用工具类 ResourceBundle ,前提是:配置文件在src 文件夹下。这样我们就可以使用工具类快速的获取配置文件的信息
使用步骤:
a. 获取ResourceBundle 对象:static ResourceBundle getBundle(“文件名不带后缀名”)
b. 通过ResourceBundle 对象的方法获取配置信息
String getString(String key) : 通过键获取值(value)
对于代码的优化(优化封装了注册驱动,获取连接,释放资源的工具类)
问题:每次使用工具类的时候都要执行一段重复的代码(读取配置文件的配置信息),所以用静态代码块封装,第一次加载到内存中后就不再加载
代码:
public class jdbc_until {
//将加载的配置文件信息共享
static final String driverClass;
static final String url;
static final String user;
static final String password;
static {
//要从配置文件中读取信息
//获取对象
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
//通过键获取对应的值
driverClass = bundle.getString("driverClass");
url = bundle.getString("url");
//System.out.println(url);
user = bundle.getString("user");
password = bundle.getString("password");
try {
Class.forName(driverClass);//无法抛出,所以就处理了
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConn() throws ClassNotFoundException, SQLException {//将异常抛出
// Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
// Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1?serverTimezone=GMT%2B8","root","123");
return DriverManager.getConnection(url,user,password);
}
public static void closeResource(Connection conn, Statement st, ResultSet rs){
//先创建的后释放
closeResult(rs);
closeStatement(st);
closeConn(conn);
}
public static void closeConn(Connection conn){
if(conn!=null){//在释放资源的时候都要考虑到资源对象为空的情况
try {//关闭会出现异常
conn.close();
}catch(Exception e){
}
conn=null;//无论是否关闭成功都将conn 设置为null 空对象会被Java的垃圾回收机制,快速的回收处理
}
}
public static void closeStatement(Statement st){
if(st!=null){//关闭会出现异常
try {
st.close();
}catch(Exception e){
}
st=null;//无论是否关闭成功都将conn 设置为null 空对象会被Java的垃圾回收机制,快速的回收处理
}
}
public static void closeResult(ResultSet rs){
if(rs!=null){//关闭会出现异常
try {
rs.close();
}catch(Exception e){
}
rs=null;//无论是否关闭成功都将conn 设置为null 空对象会被Java的垃圾回收机制,快速的回收处理
}
}
}
2.xml
在之前使用jdbc 操作数据库时,每操作一次都需要获取连接(创建一个连接),用完之后就将连接释放掉(函数/程序结束)销毁。现在通过连接池来优化代码和执行
连接池的作用:提高项目的性能,在连接初始化的时候存入一定量的连接,用的时候通过方法获取,不用的时候归还连接
所有的连接必须要实现一个接口:javax.sql.DataSource 接口(定义了一个规范)
定义一个连接池
获取连接的方法: Connection getConnection()
通过连接池获取连接,会在将连接池返回之前将连接传入装饰类,修改方法close()
再将连接返回。
归还连接池 : connection.close()
常用连接池:
1.DBCP : (了解)apache
使用步骤:
1.导入jar 包(conmmons_dbcp_ .jar 和 commons_pool_ .jar
2.使用api
a.硬编码:将配置信息写在代码里
b.使用配置文件
2.C3P0:(掌握)
hibernate 和 spring 使用 。而且有自动回收不用连接的功能。
使用步骤:
1.导入jar 包
2.使用api
a.硬编码(十分不想用)
new combopooledDataSource();
b.配置文件
配置文件的名称:c3p0.properties 或者是 c3p0-config.xml
文件放置的位置:src 目录下
编码只需要写: new combopooledDataSource(); 就完全可以了。就可以直接获取连接了
properties 文件的格式:
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///mydb1?serverTimezone=GMT%2B8
c3p0.user=root
c3p0.password=123
代码:
public class Demo_prop {
/**使用配置文件 c3p0.properties c3p0-config.xml
* @param
*/
@Test
public void function() throws SQLException {
//ComboPooledDataSource ds = new ComboPooledDataSource();//使用默认配置
ComboPooledDataSource ds = new ComboPooledDataSource("hdiwhd");
//使用指定配置,如果指定配置无法完成,那么将自动回到默认配置
//警告: named-config with name 'hdiwhd' does not exist. Using default-config extensions.
Connection conn = ds.getConnection();
//编写sql 语句
String sql ="insert into st(id,ename) values(?,?)";
//执行者
PreparedStatement pr = conn.prepareStatement(sql);
//设置参数
pr.setString(1,"S_1005");
pr.setString(2,"面包");
//执行
int i= pr.executeUpdate();
System.out.println(i);
conn.close();
}
}