JDBC->SpringJDBC->Mybatis封装JDBC

news2024/11/24 19:36:56

一、JDBC介绍


Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。

二、主要用途


1.与数据库建立连接

2.发送 SQL 语句

3.处理结果

三、JDBC概述


1、什么是JDBC 

JDBC(Java Data Base Connectivity,  Java数据库连接) 是一种用于执行SQL语句的Java API,为多种关系数据库提供统一访问 ,它由一组用Java语言编写的类和接口组成。


2、有了JDBC,程序员只需用JDBC API写一个程序,就可访问所有数据库。(常用的框架Hibernate、MyBatis底层都是JDBC,都是对JDBC的封装) 


 3、 Sun公司、数据库厂商、程序员三方关系:SUN公司是规范制定者,制定了规范JDBC(连接数据库规范)

(1)DriverManager类   作用:管理各种不同的JDBC驱动

(2)Connection接口  

(3)Statement接口和PreparedStatement接口    

(4)ResultSet接口

数据库厂商微软、甲骨文等分别提供实现JDBC接口的驱动jar包,程序员学习JDBC规范来应用这些jar包里的类。


4、JDBC访问数据库步骤

  • :加载一个Driver驱动
  • :创建数据库连接(Connection)
  •  :创建SQL命令发送器Statement
  • :通过Statement发送SQL命令并得到结果
  • :处理结果(select语句)
  • :关闭数据库资源

四、实例:用JDBC完成查询操作

 

 

1、ResultSet里的数据一行一行排列,每行有多个字段,且有一个记录指针,指针所指的数据行叫做当前数据行,我们只能来操作当前的数据行。我们如果想要取得某一条记录,就要使用ResultSet的next()方法 ,如果我们想要得到ResultSet里的所有记录,就应该使用while循环。

2、ResultSet对象自动维护指向当前数据行的游标。每调用一次next()方法,游标向下移动一行。

3、初始状态下记录指针指向第一条记录的前面,通过next()方法指向第一条记录。循环完毕后指向最后一条记录的后面。

 ResultSet类的方法


4、作为一种好的编程风格,应在不需要Statement对象和Connection对象时显式地关闭它们。关闭Statement对象和Connection对象的语法形式为:

5、用户不必关闭ResultSet。当它的 Statement 关闭、重新执行或用于从多结果序列中获取下一个结果时,该ResultSet将被自动关闭

示例:是将后台查询到的数据在后台输出。实际开发中应该是客户端向服务器发起请求,服务器端访问数据库得到数据并封装到List中,作为整体传输到前台,并在前台输出。另外可以使用try-with-resources方式来处理异常而省略finally语句中对资源的手动关闭。 

五、JDBC高级操作


1、JDBC中使用事务

(1)在JDBC中,事务操作缺省是自动提交。一条对数据库的DML(insert、update、delete)代表一项事务操作,操作成功后,系统将自动调用commit()提交,否则自动调用rollback()回滚

(2)在JDBC中,事务操作方法都位于接口java.sql.Connection中,可以通过调用setAutoCommit(false)来禁止自动提交。之后就可以把多个数据库操作的表达式作为一个事务,在操作完成后调用commit()来进行整体提交,倘若其中一个表达式操作失败,都不会执行到commit(),并且将产生响应的异常;此时就可以在异常捕获时调用rollback()进行回滚,回复至数据初始状态

(3)事务开始的边界则不是那么明显了,它会开始于组成当前事务的所有statement中的第一个被执行的时候。

(4)事务结束的边界是commit或者rollback方法的调用

2、连接池

建立数据库连接的两种方式:

(1)传统连接方式:

首先调用Class.forName()方法加载数据库驱动,

然后调用DriverManager.getConnection()方法建立连接.

(2)连接池技术:

连接池解决方案是在应用程序启动时就预先建立多个数据库连接对象,然后将连接对象保存到连接池中。

当客户请求到来时,从池中取出一个连接对象为客户服务。

当请求完成时,客户程序调用close()方法,将连接对象放回池中.

对于多于连接池中连接数的请求,排队等待。

应用程序还可根据连接池中连接的使用率,动态增加或减少池中的连接数。 

 

3、传统的数据库连接方式的缺点

一个连接对象对应一个物理连接

每次操作都打开一个物理连接,

使用完都关闭连接,造成系统性能低下。

4、连接池技术的优点

客户程序得到的连接对象是连接池中物理连接的一个句柄

调用连接对象的close()方法,物理连接并没有关闭,数据源的实现只是删除了客户程序中的连接对象和池中的连接对象之间的联系.

5、数据库连接的建立及关闭是耗费系统资源的操作,在大型应用中对系统的性能影响尤为明显。为了能重复利用数据库连接对象,缩短请求的响应时间和提高服务器的性能,支持更多的客户,应采用连接池技术。

六、JDBC API总结


1、Connection接口

2、DriverManager类

作用:管理一组 JDBC 驱动程序的基本服务

应用程序不再需要使用 Class.forName() 显式地加载 JDBC 驱动程序。在调用 getConnection 方法时,DriverManager 会试着从初始化时加载的那些驱动程序以及使用与当前 applet 或应用程序相同的类加载器显式加载的那些驱动程序中查找合适的驱动程序。 

3、Statement接口

作用:用于将 SQL 语句发送到数据库中,或理解为执行sql语句

有三种 Statement对象:

Statement:用于执行不带参数的简单SQL语句;

PreparedStatement(从 Statement 继承):用于执行带或不带参数的预编译SQL语句;

CallableStatement(从PreparedStatement 继承):用于执行数据库存储过程的调用。

 

4、PreparedStatement接口

关系:public interface PreparedStatement extends Statement

区别

(1)PreparedStatment安全性高,可以避免SQL注入

(2)PreparedStatment简单不繁琐,不用进行字符串拼接

(3)PreparedStatment性能高,用在执行多个相同数据库DML操作时

5、ResultSet接口

ResultSet对象是executeQuery()方法的返回值,它被称为结果集,它代表符合SQL语句条件的所有行,并且它通过一套getXXX方法(这些get方法可以访问当前行中的不同列)提供了对这些行中数据的访问。

ResultSet里的数据一行一行排列,每行有多个字段,且有一个记录指针,指针所指的数据行叫做当前数据行,我们只能来操作当前的数据行。我们如果想要取得某一条记录,就要使用ResultSet的next()方法 ,如果我们想要得到ResultSet里的所有记录,就应该使用while循环。

ResultSet对象自动维护指向当前数据行的游标。每调用一次next()方法,游标向下移动一行。

初始状态下记录指针指向第一条记录的前面,通过next()方法指向第一条记录。循环完毕后指向最后一条记录的后面。

七、连接池体系

①传统连接方式的弊端分析

 1.局限性 : 

我们知道,JDBC连接MySQL本质上还是走了Socket连接,即网络通讯;当Java程序在同一时间间隔内要与数据库建立较多连接时,会消耗较长的时间,网络开销大。而且,Java程序通过JDBC连接数据库的最大连接数是有限制的,如果同一时间间隔内Java程序要建立很多与数据库的连接,甚至有多个Java程序都要与数据库建立连接,很可能会把数据库给干爆,导致数据库瘫痪,跑不起来;此时Java程序会抛出"Too many connections"异常。

2.几个弊端 :

  •  传统的JDBC连接方式是通过DriverManager类的getConnection方法来获取连接的;每次与数据库建立连接,都需要将获取到的Connection对象加载到内存中,再验证IP地址,用户名和密码等信息(通常消耗0.05~1s 时间,取决于此时计算机的网络卡顿情况和此时的并发线程数)。因此,频繁的建立与数据库的连接会占用很多的系统资源,容易造成服务器崩溃。
  • 每一次建立与数据库的连接后,使用完毕都必须断开连接;否则,如果程序出现异常而未能正常关闭,将导致数据库内存泄漏,最终将导致重启数据库。
  • 传统获取连接的方式,无法控制实际建立连接的数量,若连接过多,也可能导致内存泄漏,MySQL崩溃。

 

②数据库连接池

1.基本介绍 : 


数据库连接池是指,在Java程序未和数据库建立连接时,就提前创建好一定数量的连接并放入缓冲池中;当Java程序请求建立数据库连接时,就可以直接从缓冲池中“拿出”建立好的连接来用,用完后取消Java程序对该连接的引用即可,连接本身不会中断,只是“放回”了连接池(动态绑定机制)。数据库连接池负责分配,管理和释放数据库连接,它允许用户程序重复使用一个现有的数据库连接,而不是重新建立一个。(即连接池中的连接是公共的,谁都能用,你用完我可以接着用)当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。

2.示意图如下 : 

3.连接池种类 : 

  • JDBC的数据库连接池使用javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由第三方来实现。
  • C3P0数据库连接池,速度相对较慢(只是慢一丢丢),但是稳定性很好,Hibernate,Spring底层用的就是C3P0。
  • DBCP数据库连接池,速度比C3P0快,但是稳定性差。
  • Proxool数据库连接池,有监控连接池状态的功能,但稳定性仍然比C3P0差一些。
  • BoneCP数据库连接池,速度较快。
  • Druid数据库连接池(德鲁伊连接池),由阿里提供,集DBCP,Proxool,C3P0连接池的优点于一身,是日常项目开发中使用频率最高的数据库连接池。

 八、SpringJDBC

1.Spring的JDBC模块有四个包组成:

  • core:核心包,JDBC核心功能,JdbcTemplate就在此包内
  • DataSource:数据源包,访问数据源的工具类,SimpleDriverDataSource 在此包
  • Object:对象包,以面向对象的方式访问数据库,它允许执行查询,并将结果作为业务对象,处理数据表和业务对象之间的映射
  • support:支持包,含有core和object包的支持类
     

2.配置数据库资源


在Spring中,通过JDBC驱动定义数据源是最简单的配置方式。Spring提供了三个这样的数据源类(均位于org.springframework.jdbc.datasource包中)供选择:

  • org.springframework.jdbc.datasource.DriverManagerDataSource:在每个连接请求时都会返回一个新建的连接,旧的JDBC,无池化管理。基本上已被SimpleDriverDataSource取代。
  • org.springframework.jdbc.datasource.SimpleDriverDataSource:与DriverManagerDataSource的工作方式类似,但是它直接使用JDBC驱动。
  • org.springframework.jdbc.datasource.SingleConnectionDataSource:它的连接不会关闭,在每个连接请求时都会返回同一个的连接。(它不是严格意义上的连接池数据源,但是可以将其视为只有一个连接的连接池)

除了这些简单的数据原外,所以我们也可以选择其他的第三方连接池使用,第三方的数据库连接池其实有很多,不过大多使用:Druid(阿里的)、HikariCP(springboot目前默认的)。
 

3. JdbcTemplate

在web编程中,传统JDBC每次执行SQL时每次都需要获取:Connection、PreparedStatement、ResultSet 这些数据库资源,然后就需要大量的try、catch、finally语句捕捉异常、关闭数据库资源。既便是专门使用一个类设置成单例进行封装,它依然是很繁琐的。在spring 中提供了JdbcTemplate模板来解决这个问题,它是比较经典的jdbc实现方式之一,同时也是Spring 在jdbc方便最底层的方法,SimpleJdbcInsert,SimpleJdbcCall 等底层都是用了JdbcTemplate。JdbcTemplate是 org.springframework.jdbc.core 中的类,用来处理数据库资源的创建和释放, JdbcTemplate类主要包含下面这些功能:

  • 执行SQL查询语句
  • 执行更新语句和存储过程调用
  • 对 ResultSet 执行迭代并提取返回的参数值。
  • 捕获JDBC异常并进行处理

我们发现这些功能都是我们在写 JCBC时每条sql语句都会涉及到的内容,而JdbcTemplate把这些提取出来进行封装,我们只需要在XML中配置好,就可直接提供sql语句执行了。

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <!--将之前配置好的连接池加载进来 -->
    <property name="dataSource" ref="druidDataSource"/>
</bean>

获取JdbcTemplate对象就可以直接使用,它内部的常用的方法

  • query():重载了大量 query方法来进行数据的查询操作,返回的是List,内部是自定义的Bean

List query(String sql, PreparedStatementSetter pss, RowMapper rowMapper):根据sql语句创建PreparedStatementSetter 对象。通过RowMapper 将结果返回到list中

List query(String sql, Object[] args, RowMapper rowMapper):使用Object[] 的值注入sql语句,利用RowMapper 返回数据

List query(String sql, RowMapper rowMapper, Object… args)

jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(数据表对应的类.class),参数....);
  • queryForObject(String sql, RowMapper rowMapper, Object… args)():只能查询一行数据库记录,RowMapper自动封装,返回任意对象
jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(数据表对应的类.class),参数....);
  • queryForList():可以返回多行数据的结果,返回的是List数据
  • update():此方法用来进行修改、新增、删除操作
int update(String sql)
int update(String sql,Object… args)
int[] batchUpdate(String sql, List<Object[]> batchArgs, final int[] argTypes) :批量执行新增、更新、删除等语句

sql:需要执行的 SQL 语句;argTypes:需要注入的 SQL 参数的 JDBC 类型;

batchArgs:表示需要传入到 SQL 语句的参数。

execute():可以执行任意 SQL,一般用于执行 DDL 语句;
@SpringJUnitConfig(locations = {"classpath:application.xml"})
public class JDBCTest {
   	@Resource
    private JdbcTemplate jdbcTemplate;
    
    @Test
    public void select(){
        Integer[] id = {1};
        String sql = "select * from classes where c_id =?";
        //Classes classes =jdbcTemplate1.query(sql, new BeanPropertyRowMapper<>(Classes.class),id); 
        Classes classes = jdbcTemplate.queryForObject(sql,id,(ResultSet rs,int rowNum)->{
            Classes classes1 = new Classes();
            classes1.setcId(rs.getInt("c_id"));
            classes1.setClassesName(rs.getString("classes_name"));
            classes1.setDeleted(rs.getBoolean("is_deleted"));
            return classes1;
        });
        if(classes!=null){
            System.out.println(classes.getClassesName());
        }
    }
     @Test
    public void selectAll(){
        String sql = "select * from classes";
        List<Classes> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Classes.class));
        list.forEach(c -> System.out.println(c.getClassesName()));
    }

    @Test
    public void insert(){
        String classesName = "新增班级";
        String sql = "insert into classes(classes_name) values(?)";
        jdbcTemplate.update(sql, classesName);
        
    }
    @Test
    public void delete(){
        int id = 1;
        String sql = "delete from classes where c_id=?";
        jdbcTemplate.update(sql,id);
    }

    @Test
    public void update(){
        String newName = "修改班级";
        int id = 1;
        String sql = "UPDATE classes SET classes_name='?' WHERE classes.c_id = ?";
        jdbcTemplate.update(sql,newName,id);
    }
}

 九、spring整合mybatis

 

1.传统的dao方式操作数据库

即获取sqlSession,然后调用sqlSession.selectOne 等等的方式来进行数据库操作。

2.mapper方式

使用mapper方式,只需要一个接口类,不需要实现类,但有几点要求:

(1)映射文件保持命名空间与接口类名称一致,注意这个命名空间,如果没有在sqlMapConfig里配置好typeAliases,则必须是全路径命称,即此处命名空间名称必须为mapper接口路径加名称

(2)映射文件的SQLID名,与mapper接品方法名一致

(3)映射文件的输入参数与mapper接口的形参一致

(4)映射文件的返回结果类型与mapper接口的返回类型一致

另注意如果,在sqlMapConfig里采用的是包方式的映射(即mappers标签下,使用的是package标签),则需保证映射文件与mapper接口在同一目录下,并且必须名称相称,如果不是以包方式,则不需要如此,只需要保证以上4点即可。另第二种方式一般以sqlSession.getMapper 方式调用。

 

十、SpringBoot持久化

1.使用SpringBoot的过程中,常用的持久化解决方案主要有两种,一种是Mybatis框架,另一个就是SpringData JPA。

2. SpringData JPA和MyBatis最大的区别就是SpringData JPA是Spring亲生的,这个从名字的命名方式上也能看出来,当然是因为它们是一家人了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1350319.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WPF+Halcon 培训项目实战(8-9):WPF+Halcon初次开发

文章目录 前言相关链接项目专栏运行环境匹配图片WPF Halcon组件HSmartWindowControlWPF绑定读取图片运行代码运行结果 抖动问题解决运行结果 绘制矩形绘制图像会消失 绘制对象绑定事件拖动事件 前言 为了更好地去学习WPFHalcon&#xff0c;我决定去报个班学一下。原因无非是想…

数据结构——顺序栈与链式栈的实现

目录 一、概念 1、栈的定义 2、栈顶 3、栈底 二、接口 1、可写接口 1&#xff09;数据入栈 2&#xff09;数据出栈 3&#xff09;清空栈 2、只读接口 1&#xff09;获取栈顶数据 2&#xff09;获取栈元素个数 3&#xff09;栈的判空 三、栈的基本运算 四、顺序栈&…

【CISSP学习笔记】5. 安全架构和工程

该知识领域涉及如下考点&#xff0c;具体内容分布于如下各个子章节&#xff1a; 使用安全设计原理来研究、实施与管理工程过程理解安全模型的基本概念&#xff08;例如 Biba、Star Model、Bell-LaPadula 等模型&#xff09;基于系统安全要求选择控制措施理解信息系统 (IS) 的安…

智能对话意图分析服务接口

机器人聊天&#xff0c;智能助手&#xff0c;内容生成&#xff0c;智能办公&#xff0c;智能辅助&#xff0c;智能搜索 一、接口介绍 通过接收用户提出的问题、输入的图片和文档等需求&#xff0c;准确识别其对话意图&#xff0c;并触发相应的回复。同时&#xff0c;整合了AP…

ansible管理windows测试

一、环境介绍 Ansible管理主机&#xff1a; 系统: redhat7.6 Linux管理服务器需安装pywinrm插件 Windows客户端主机&#xff1a; 系统: Server2012R2 Windows机器需要安装或升级powershell4.0以上版本&#xff0c;Server2008R2默认的版本是2.0&#xff0c;因此必须升…

m1芯片电脑上的paragon15如何安装激活 m1芯片电脑上ntfs for mac如何安装

Paragon NTFS软件在M1芯片电脑上安装之后&#xff0c;最后一步会让我们“允许加载第三方内核扩展”&#xff0c;具体如下图所示。 图1&#xff1a;允许加载第三方内核扩展 按照图中提示“单击此处“&#xff0c;然后打开安全与隐私。接下来依次点击小锁标志进行解锁&#xff0c…

【零基础入门TypeScript】TypeScript - 概述

目录 什么是 TypeScript&#xff1f; TypeScript 的特点 TypeScript 和 ECMAScript 为什么使用 TypeScript&#xff1f; TypeScript 的组件 声明文件 JavaScript 是作为客户端语言引入的。Node.js 的发展也标志着 JavaScript 成为一种新兴的服务器端技术。然而&#xff0…

云原生十二问

一、什么是云原生&#xff1f; 云原生是在云计算环境中构建、部署和管理现代应用程序的软件方法。现代企业希望构建高度可扩展、灵活且具有弹性的应用程序&#xff0c;可以快速更新以满足客户需求。为此&#xff0c;他们使用现代工具和技术&#xff0c;这些工具和技术本质上支…

python 深度学习 记录遇到的报错问题11

本篇继python 深度学习 记录遇到的报错问题10-CSDN博客 六、ValueError: cannot convert float NaN to integer 报错&#xff1a; 原因&#xff1a;这个错误通常是因为在尝试将NaN值转换为整数时发生的。NaN表示“非数字”&#xff0c;它无法转换为整数。在 Python 中&#xf…

2023年度回顾:怿星科技的转型与创新

岁月不居&#xff0c;时节如流。随着2023年的落幕&#xff0c;怿星科技在这一年中不仅实现了自身的转型&#xff0c;还在技术创新、产品研发、行业合作和人才培养等方面取得了显著的成就。这一年&#xff0c;怿星科技正式完成了从服务型公司向产品型公司的战略转变&#xff0c;…

媒体捕捉-拍照

引言 在项目开发中&#xff0c;从媒体库中选择图片或使用相机拍摄图片是一个极为普遍的需求。通常&#xff0c;我们使用UIImagePickerController来实现单张图片选择或启动相机拍照。整个拍照过程由UIImagePickerController内部实现&#xff0c;无需我们关心细节&#xff0c;只…

让你的隧道代理HTTP使用更加顺畅高效

在数字世界的探险中&#xff0c;隧道代理HTTP是我们穿越网络限制的重要工具。但有时候&#xff0c;我们可能会遇到连接不稳定、速度慢等问题。如何让隧道代理HTTP使用更加顺畅高效&#xff1f;下面是一些建议和技巧。 一、选择合适的代理服务器 代理服务器的地理位置、性能和…

C#/.NET/.NET Core推荐学习书籍(23年12月更新)

前言 古人云&#xff1a;“书中自有黄金屋&#xff0c;书中自有颜如玉”&#xff0c;说明了书籍的重要性。作为程序员&#xff0c;我们需要不断学习以提升自己的核心竞争力。以下是一些优秀的C#/.NET/.NET Core相关学习书籍&#xff0c;值得.NET开发者们学习和专研。书籍已分类…

查看证书有效期的命令

后面的证书是我们当时创建证书的路径 cfssl-certinfo -cert /opt/etcd/certs/etcd.pem

服务雪崩简单的介绍

定义 服务雪崩效应是一种因“服务提供者的不可用”&#xff08;原因&#xff09;导致“服务调用者不可用”&#xff08;结果&#xff09;&#xff0c;并将不可用逐渐放大的现象。如下图所示&#xff1a; 上图中, A为服务提供者, B为A的服务调用者, C和D是B的服务调用者. 当A的…

精确率(Precision,P),召回率(Recall,R)以及F1值(F1-score,F1)

狗狗识别系统的例子&#xff1a; 假设我们有两个集合&#xff1a; 实际狗狗的集合&#xff08;实际真正是狗狗的图片&#xff09;&#xff1a;A我们识别为狗狗的集合&#xff08;我们认为是狗狗的图片&#xff09;&#xff1a;B 精确率&#xff08;Precision&#xff0c;P&am…

LeetCode刷题--- 第 N 个泰波那契数

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 ​​​​​​http://t.csdnimg.cn/6AbpV 数据结构与算法 ​​​http://t.csdnimg.cn/hKh2l 前言&#xff1a;这个专栏主要讲述动…

【十三】【动态规划】1745. 分割回文串 IV、132. 分割回文串 II、516. 最长回文子序列,三道题目深度解析

动态规划 动态规划就像是解决问题的一种策略&#xff0c;它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题&#xff0c;并将每个小问题的解保存起来。这样&#xff0c;当我们需要解决原始问题的时候&#xff0c;我们就可以直接利…

半年没发过文章,这个博主竟然...

目 录 前言这半年去干了什么&#xff1f;考研求职山东电建移动 论文大创课余 未来公务员继续考研就业 结语 前言 第一次写这样的记录性的文章&#xff0c;这篇文章可能不会有太过于华丽的辞藻&#xff0c;但是它将展现我个人的真实经历和内心感受。在过去的时间里&#xff0c;我…

WEB 3D技术 three.js通过光线投射 完成几何体与外界的事件交互

本文 我们来说 光线投射 光线投射技术是用于3维空间场景中的交互事件 我们先编写代码如下 import ./style.css import * as THREE from "three"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";const scene new THRE…