JDBC数据库编程

JDBC API是一个Java API可以访问任何类型的数据库的数据,尤其是存储在关系数据库中的数据。通过JDBC API可以方便地实现对各种主流数据库的操作。本篇将以MySQL为例,介绍一下如何使用JDBC操作数据库。

JDBC

  1. 客户端操作MySQL数据库的方式:

    1. 使用第三方客户端来访问 MySQL:Navicat、SQLWave、MyDB Studio、EMS SQL Manager for MySQL
    2. 使用 MySQL 自带的命令行方式
    3. 通过 Java 来访问 MySQL 数据库,本文要介绍的内容。
  2. 概念:Java DataBase Connectivity Java 数据库连接, Java语言操作数据库。
    JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。在这里插入图片描述

  3. 使用JDBC的好处:

    1. 如果要开发访问数据库的程序,只需要会调用 JDBC 接口中的方法即可,不用关注类是如何实现的。
    2. 使用同一套 Java 代码,进行少量的修改就可以访问其他 JDBC 支持的数据库。
  4. 使用步骤:
    使用JDBC主要有八个步骤,分别是:

    • 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
    • 注册驱动
    • 获取数据库连接对象 Connection
    • 定义sql
    • 获取执行sql语句的对象 Statement
    • 执行sql,接受返回结果
    • 处理结果
    • 释放资源

下面举个例子来说明下这八个步骤。


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class Demo1 {

	public static void main(String[] args) throws Exception {
		//0.首先导入jar包
		//1.注册驱动
		Class.forName("com.mysql.jdbc.Driver");
		//3.获取数据库连接对象
		Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/wbg_logistics","root","root");
		//4.sql语句
		String sql="update depart set dedpart_no=3 where dedpart_no=1";
		//5.获取执行sql的对象 Statement
		Statement stmt=conn.createStatement();
		//6.执行sql
		int count=stmt.executeUpdate(sql);
		//7.打印结果
		System.out.println("影响的行数:"+count);
		//8.释放资源
		stmt.close();
		conn.close();
	}
}

**注意:**报错Exception in thread “main” java.lang.ClassNotFoundException: com.mysql.jdbc.Driver:加载类的时候找不到该类,缺少对应的mysql-connector-java的jar包。

3.JDBC的核心API介绍:

  1. DriverManager:管理和注册驱动,得到数据库连接对象。为什么Class.forName(数据库驱动实现类)可以注册驱动?因为Driver 接口是所有数据库厂商必须实现的接口,表示这是一个驱动类。com.mysql.jdbc.Driver 源代码如下:

    public class Driver implements java.sql.Driver {     
    	public Driver() throws SQLException {     } 
    	
         static {        
         	try {             
        	 DriverManager.registerDriver(new Driver());  //注册数据库驱动         
         	} catch (SQLException var1) {             
         		throw new RuntimeException("Can't register driver!");         
         	}     
         } 
     } 
    

  2. Connection:数据库连接对象,可用于创建 Statement 和 PreparedStatement 对象。

    • 主要方法:

      Connection 接口中的方法描述
      Statement createStatement()创建一条 SQL 语句对象
  3. Statement:执行sql的对象

    • 主要方法

      Statement 接口中的方法描述
      int executeUpdate(String sql)用于发送 DML 语句,增删改的操作,insert、update、delete 参数:SQL 语句 返回值:返回对数据库影响的行数
      ResultSet executeQuery(String sql)用于发送 DQL 语句,执行查询的操作。select 参数:SQL 语句 返回值:查询的结果集
  4. ResultSet:结果集对象,封装查询结果

    ResultSet 接口中的方法描述
    boolean next()1) 游标向下移动 1 行 2) 返回 boolean 类型,如果还有下一条记录,返回 true,否则返回 false
    数据类型 getXxx()【比如boolean getBoolean】1) 通过字段名,参数是 String 类型。返回不同的类型 2) 通过列号,参数是整数,从 1 开始。返回不同的类型

  5. PreparedStatement:执行sql的对象,是 Statement 的子接口

    • SQL注入问题:在拼接sql的时候,有一些sql的特殊关键字参与字符串的拼接,可能会造成安全问题。为了解决这个问题,使用PreparedStatement对象来解决。
    • 预编译的SQL:参数使用?作为占位符

抽取JDBC工具类:JDBUtils

​ 其实不难发现,当增删查改的时候按照这样的方法需要写很多遍连接数据库、加载驱动还有关闭资源等代码,因为这些功能经常用到,所以建议把它做成一个工具类,抽取出来,方便可以在不同的地方重用。
目录结构:
在这里插入图片描述
1.在src目录下新建一个文件mysql.properties,,user和password分别写用户和密码。localhost可以写ip地址(本机的和远程的都可以),3306是端口号。

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/修改为自己索要连接的数据库名称
user=root
password=root

2.在src目录下新建dbConfig.java,主要是加载配置文件用的。

import java.io.FileInputStream;
import java.util.Properties;

public class dbConfig {

	private static Properties p = null;
	static {
		try {
			p = new Properties();
			// 加载配置文件
			p.load(new FileInputStream("src/mysql.properties"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	// 获取键对应的值ֵ
	public static String getValue(String key) {
		return p.get(key).toString();
	}
}

3.在src下新建utils包,utils包中新建JDBCUtils.java,用来写连接数据库和释放资源等操作,后续也可以将CRUD的操作写在该文件中,简化操作。



import java.sql.*;

public class JDBUtils {

	private static Connection conn = null;
	private static ResultSet rs=null;
	private static PreparedStatement pstmt=null;
	/**
	 * 得到数据库连接
	 */
	public static Connection getConnection() throws ClassNotFoundException,
			SQLException, InstantiationException, IllegalAccessException {
		// 通过dbConfig获取数据库配置信息
		String driver = dbConfig.getValue("driver");
		String url = dbConfig.getValue("url");
		String user = dbConfig.getValue("user");
		String pwd = dbConfig.getValue("password");
		try {
			// 指定驱动程序
			Class.forName(driver);
			// 建立数据库连结
			conn = DriverManager.getConnection(url, user, pwd);
			return conn;
		} catch (Exception e) {
			// 如果连接过程出现异常,抛出异常信息
			throw new SQLException("驱动错误或连接失败!");
		}
	}

	/**
	 * 释放资源
	 */
	public static void closeAll() {
		// 如果rs不空,关闭rs
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		// 如果pstmt不空,关闭pstmt
		if (pstmt != null) {
			try {
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		// 如果conn不空,关闭conn
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

JDBC控制事务

1.事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。

2.相关操作:

  1. 开启事务
  2. 提交事务
  3. 回滚事务

3.使用Connection对象来管理事务

  1. 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务。在执行sql之前开启事务
  2. 提交事务:commit()。当所有sql都执行完提交事务
  3. 回滚事务:rollback() 。在catch中回滚事务

4.例子

​ 假设某银行中有这样两个用户A和B,A和B的账户余额均为3000元,因为某种不可抗拒的因素,账户A要给账户B转账500元,那么转账成功后A账户的余额应为2500元,B账户的余额应为3500.假设如果银行在A账户中划走了500元,此时银行划走的500元尚未转账给B账户就恰好出现了故障,程序抛出异常无法完成给B转账的工作,这样的情况不能称之为交易成功。那么基于这样的情况就需要回滚事务,把从A账户中划走的500元还给A。

import com.nayelya.utils.JDBUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Demo {

	public static void main(String[] args) {
		Connection conn=null;
		PreparedStatement pst1=null;
		PreparedStatement pst2=null;

		String sql1="update my_account set balance=balance - ? where name=? ";
		String sql2="update my_account set balance=balance + ? where name=? ";

		try {
			conn = JDBUtils.getConnection();
			pst1=conn.prepareStatement(sql1);
			pst2=conn.prepareStatement(sql2);
			pst1.setDouble(1,500);
			pst1.setString(2,"A");
			/*假设此处出现异常*/
			int res=6/0;
			pst2.setDouble(1,500);
			pst2.setString(2,"B");

			pst1.executeUpdate();
			pst2.executeUpdate();
		} catch (SQLException e) {
			try {
				if(conn != null) {
					conn.rollback();
				}
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBUtils.closeAll();
		}
	}
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值