前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JDBC详解

JDBC详解

作者头像
CODER-V
发布2023-03-04 13:05:35
8310
发布2023-03-04 13:05:35
举报
文章被收录于专栏:藏经阁

文章目录

1、概述

JDBC概念:

  • JDBC就是使用Java语言操作关系型数据库的API
  • 全称:Java DataBase ConectivityJava数据库连接
  • 正常情况下,一套Java代码不能操作不同的关系型数据库,因为每种数据库底层都不同。JDBC就是为了解决这一问题而出现,一套JDBC代码可以操作MySQL、Oracle、IBM等不同的数据库。
  • JDBC只是定义了一套接口(也就是规则),具体的实现类由不同的数据库厂商自己定义,厂商们将实现类称为驱动

JDBC本质:

  • 官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口
  • 各个数据库厂商去实现这套接口,提供数据库驱动jar包,我们需要使用哪个数据库就要再项目导入对应的jar包。
  • 我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。

JDBC好处:

  • 我们通过一套Java代码可以操作不同的数据库。
  • 可以随时替换底层数据库,访问数据库的Java代码基本不变。

2、JDBC使用步骤

代码语言:javascript
复制
public class JDBC {
    public static void main(String[] args) throws Exception {
        // 1. 注册驱动,此步骤在MySQL5.0版本后可省,因为在lib/META-INF/services/java.sql.Driver文件里记录了驱动的名称,会自动加载。
        Class.forName("com.mysql.Driver");

        // 2.获取连接
        String url = "jdbc:mysql://ip地址(域名)/端口号/数据库名称[?参数键值对1&参数键值对2]";
        // String url = "jdbc:mysql://ip地址(域名)/端口号/数据库名称?useSSl=false"解决控制栏警告提示
        String username = "数据库账户名";
        String password = "数据库密码";
        Connection connection = DriverManager.getConnection(url,username,password);

		// 此处可开启事务

        // 3.定义sql
        String sql = "update account set money = 20000 where id = 1";

        // 4.获取执行sql的对象 statement
        Statement statement = connection.createStatement();

        // 5.执行sql
        int count = statement.executeUpdate(sql);

        // 6.处理结果
        System.out.println(count);

		// 此处可提交事务

        // 7.释放资源
        statement.close();
        connection.close();


    }
}

3、DriverManager

DriverManager(驱动管理类)作用:

  • 注册驱动: Class.forName("com.mysql.Driver") 此步骤在MySQL5.0版本后可省略,因为在lib/META-INF/services/java.sql.Driver文件里记录了驱动的名称,会自动加载。
  • 获取数据库连接: Connection connection = DriverManager.getConnection(url,username,password);
    • 其中url="jdbc:mysql://ip地址(域名)/端口号/数据库名称?参数键值对1&参数键值对2"
    • 若连接的是本机MySQL服务器,并且MySQL默认端口是3306,则俩可以简写为:jdba:mysql:///数据库名称[?参数键值对1,参数键值对2]
    • 在域名后面添加useSSl=false参数,禁用安全连接方式,解决控制栏警告提示。 jdbc:mysql://ip地址(域名)/端口号/数据库名称?useSSl=false

4、Connection

Connection(数据库连接对象)作用:

获取执行sql的对象

  • 普通执行sql对象:Statement createStatement()
  • 预编译sql的执行失去了对象:防止sql注入:PreparedStatement prepareStatement(sql)
  • 执行存储过程的对象:CallableStatement prepareCall(sql)

管理事务

  • MySQL事务管理
代码语言:javascript
复制
开启事务:BEGIN或START TRANSACTION;
提交事务:COMMIT
回滚事务:ROLLBACK
  • JDBC事务管理:Connection接口中定义了3个对应的方法,默认自动提交事务。
代码语言:javascript
复制
开启事务:setAutoCommit(true/false),true为自动提交,false为手动提交,即开启事务
提交事务:commit
回滚事务:rollback

开启事务在定义sql之提交事务在处理完数据库返回的结果回滚事务catch中进行,用try-catch处理sql语句,若出现异常则进行相应的回滚操作。 示例:

代码语言:javascript
复制
	try{
		// 开启事务
		connection.setAutoCommit(fale);
		
		// 定义sql
    	String sql = "update account set money = 20000 where id = 1";

    	// 获取执行sql的对象 statement
   		Statement statement = connection.createStatement();

    	// 执行sql
    	int count = statement.executeUpdate(sql);

    	// 处理结果
    	System.out.println(count);

		// 提交事务
		connection.commit();
		} catch(Exception throwables){
			// 回滚事务
			connection.rollback();
		}

5、Statement

Statement作用:执行sql语句

  • int executeUpdate(sql):执行DML(对表的操作)、DDL(对数据的增删改)。 返回值:
    • DML语句影响的行数
    • DDL语句执行后,执行成功也可能返回0
  • ResultSet executeQuery(sql):执行DQL(select查询语句)。 返回值:ResultSet结果集对象

6、ResultSet

ResultSet(结果集对象)作用:

  • 封装了DQL查询语句的结果:ResultSet statement.executeQuery(sql);执行select语句,返回ResultSet对象

获取查询结果:

  • boolean next()
    • 将光标从当前位置向前移动一行。默认指向的表头行,非数据行;因而要获取数据需要将游标往下移动一行
    • 判断当前行是否为有效行
    • 返回值:
      • 有效行,当前行由数据
      • 无效行,当前行无数据
  • xxx getXxx(参数):获取数据,参数可以是具体的值,也可以是对应的字段。
    • xxx:数据类型。如:int getInt(参数);String getString(参数)
    • int:列的编号(主键),从1开始。
    • String:列的名称

我们查询出来的数据需要封装到ArrayList集合中,返回给前端,见以下案例:

需求:查询Account账户表数据,并将数据封装Account对象中,再将Account对象存入ArrayList集合。

创建Account实体类:

代码语言:javascript
复制
public class Account {
	private in id;
	private String name;
	private double money;

	public in getId(){
		return id;
	}

	public void setId(int id){
		this.id=id;
	}

	public String getName(){
		return name;
	}

	public void setName(){
		this.name=name;
	}
	
	public double getMoney(){
		return name;
	}

	public void setMoney(){
		this.money=money;
	}

	//这里只是为了查看效果
	@Override
	public String toString(){
		return "Account{"+"id="id+",name='"+name+'\''+",money="money+'}';
	}
}

JDBC,查询Account账户表数据,并将数据封装Account对象中,再将Account对象存入ArrayList集合

代码语言:javascript
复制
// 1.定义实体类Account
// 2.查询数据,封装到Account对象中
// 3.将Account对象存入ArrayList集合中

public class resultSet() {
    public static void main(String[] args) throws Exception {
        // 1. 注册驱动,此步骤在MySQL5.0版本后可省,因为在lib/META-INF/services/java.sql.Driver文件里记录了驱动的名称,会自动加载。
        Class.forName("com.mysql.Driver");

        // 2.获取连接
        String url = "jdbc:mysql://ip地址(域名)/端口号/数据库名称[?参数键值对1&参数键值对2]";
        // String url = "jdbc:mysql://ip地址(域名)/端口号/数据库名称?useSSl=false"解决控制栏警告提示
        String username = "数据库账户名";
        String password = "数据库密码";
        Connection connection = DriverManager.getConnection(url,username,password);

        // 3.定义sql
        String sql = "select * from account";

        // 4.获取执行sql的对象 statement
        Statement statement = connection.createStatement();

        // 5.执行sql
        ResultSet res = statement.executeQuery(sql);

		// 6.创建集合
		List<Account> list = new ArrayList<>();

        // 7.处理结果
        // 光标向下移动一行,并判断当前行是否有数据
        while(res.next()){
			// 给每行记录创建一个Account对象
			Account account = new Account();

			// 获取数据
			in id = res.getInt("id");
			String name = res.getString("name");
			double money = res.getDouble("money");

			// 赋值
			account.setId(id);
			account.setName(name);
			account.setMoney(money);

			// 存入集合
			list.add(account);
		}

        // 8.释放资源
        res.close();
        statement.close();
        connection.close();
    }
}

7、PreparedStatement

PreparedStatement作用:

  • 预编译SQl语句并执行
  • 防止SQL注入问题。

PreparedStatement优点:

  • 预编译sql,性能更高
    • 我们通过?来代替直接传入具体值,这一sql只需要编译一次sql语句。
    • 若每次都直接传入具体值,sql就每次都要编译一次,而编译sql相对执行sql是比较耗时的。
  • 防止sql注入
    • 将敏感字符进行转义

开启PreparedStatement预编译功能:在url后面加上useServerPrepStmts=true

要查看日志,需要在MySQL配置文件中配置,然后重启服务器

代码语言:javascript
复制
log-output=FILE
general-log=1
gereral_log_file="D:\mysql.log" #输出目录
slow-query-log=1
slow_query_log_file="D:\mysql_slow.log"# 慢查询日志输出目录
long_query_time=2

PreparedStatement使用:

代码语言:javascript
复制
1.获取PrepareStatement对象
// SQL语句的参数设置为?,防止SQL注入
String sql="select * from user where username=? and password=?";
// 通过Connection对象获取,并传入对应的sql语句
PrepareStatement pstmt=connection.prepareStatement(sql);

2.设置?的值
//因为姓名和密码都是String类型,所以都是getString,根据值的数据类型来选择setXxx(parameterIndex,值),parameterIndex表示给第几个值设置值。
pstmt.setString(parameterIndex,name)
pstmt.setString(parameterIndex,pwd)

3.执行SQL
// 不需要将sql作为参数传入执行
executeQuery();//查询语句时使用
executeUpdate();//更新语句时使用

PreparedStatement原理:

  1. 在获取PreparedStatement对象时,将sql语句发送给MySQL服务器进行检查,编译。
  2. 执行时就不用再进行检查,编译。
  3. 如果sql模板一样,则只需要进行一次检查、编译。

SQL注入

  • SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。

  • 简单的SQL注入代码,比如在登陆时密码框输入:'' or '1'='1'
    • 第一对’',表示截断sql查询的值,查询1=1也就是查询全表。
    • 因为我们在查询账户密码的时候通过:select * from user where username='"+name+"' and password='"+pwd+"'这样的语句来拼接字符串,导致任何类型的值都可以被拼接成功。
  • PreparedStatement解决sql注入原理:
    • 通过"select * from user where username=? and password=?"用?代替值,在设置?的值的时候会对值进行转义。
    • 比如:'\' or \'1\' = \'1',把用户非法输入的单引号进行转义,最终传入参数作为一个整体执行,从而防止 SQL 注入,而 Statement 对象不会进行此操作。

8、数据库连接池

8.1、概述

  • 数据库连接池时一个容器,赋值分配、管理数据库连接(Connection)
  • 即 将连接放入一个数据库连接池,当连接使用完后,不会立刻结束连接,而是将其放回连接池,供他人使用。
  • 如果一个连接被占用的时间超过了规定时间,则会被释放,避免程序过多时引起数据库连接遗漏。就是连接池中的连接被全部占用,后来的程序找不到连接。

好处:

  • 资源复用
  • 提升系统响应速度,因为不用重复建立连接,建立网络连接是比较耗时的
  • 避免数据库连接遗漏

8.2、数据库连接池的实现

  • 标准接口:DataSource
    • 官方(SUN)提供的数据库连接池标准接口,由第三方组织实现此接口
    • 功能:获取连接Connection getConnection()
  • 常见的数据库连接池:
    • DBCP
    • C3P0
    • Druid
  • Druid(德鲁伊)
    • Druid连接池是阿里巴巴开源的数据库连接池i项目
    • 功能强大,性能优秀,是Java最好的数据库连接池之一

8.3、Druid的使用

  1. 导入jar包到lib目录
  2. 在src下定义配置文件druid.properties
代码语言:javascript
复制
driverClassName=com.mysql.jdbc.Driver
# 这里的url和JDBC连接数据库的url格式一样
url=jdbc:mysql://数据库ip
username=数据库账户
password=数据库密码
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000
  1. 加载配置文件
  2. 获取数据库连接池对象
  3. 获取连接
代码语言:javascript
复制
// 加载配置文件
Properties prop = new Properties();
	// 路径不确定可以通过打印System.getProperty("user.dir")查看
prop.load(new FileInputStream("druid.properties配置文件路径"));
// 获取数据库连接池对象
	// 这里可以传入不同参数创建连接池对象,使用的时候具体查看。可以先写该步骤再new相应的对象,也就是加载配置文件的步骤
DataSource dataSource = DruidDataSourceFactor.createDataSource(prop);
// 获取数据库连接connection
Connection connection = dataSource.getConnection();
System.out.println(connection);
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 1、概述
  • 2、JDBC使用步骤
  • 3、DriverManager
  • 4、Connection
  • 5、Statement
  • 6、ResultSet
  • 7、PreparedStatement
  • 8、数据库连接池
    • 8.1、概述
      • 8.2、数据库连接池的实现
        • 8.3、Druid的使用
        相关产品与服务
        数据库
        云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档