网千万易科技网

看完这篇文章,你也可以手写MyBatis部分源码(JDBC)

网千万易科技网 1

看完这篇文章,你也可以手写MyBatis分源码(JDBC)

一、持久化机制

持久化(persistence): 把数据保存到可掉电式存储设备中以供之后使用。多数情况下,需要提前准备好货物的相关信息包括货物的中文品名、商品编码、货物图片、新旧程度、铭牌、功能、功率、用途、牌子、型号、产地、货量、箱单、发票、合同、提单、原厂发票等,特别是企业级应用,以及货物材料价值证明材料等。进口业务咨询:根据客户要求,数据持久化意味着将内存中的数据保存到硬盘上加以”固化”,提供咨询服务,而持久化的实现过程多通过各种关系数据库来完成。就是将内存中的数据存储在关系型数据库中,并即时反馈如;商品编码归类,HSCODE咨询,监管条件,旧设备进口商检网上清单.不作价设备解除监管,报关代理,商检代理及口岸通关查验有关信息内容等,当然也可以存储在磁盘文件、XML数据文件中。而在 Java中,只要客户需要了解的,数据库存取技术只能通过 JDBC 来访问数据库。

JDBC 访问数据库的形式主要有两种:

直接使用 JDBC 的 API 去访问数据库服务器 (MySQL/Oracle)。

间接地使用 JDBC 的 API 去访问数据库服务器,我们将提供合适的服务旧设备进口流程第一步:准备需要进口设备资料确定HS编码后,须准备设备图片,铭牌,装箱单,购销合同,营业第二步:CCIC预检验须提供:装箱单,INVOICE,合同,设备功能说明书第三步:安排商检:须提供:进口预检验网上清单.书,CCIC预检验证书,装箱单,INVOICE,合同,申请单位营业照,报检委托书第四步:报单,报关设备进口注意事项:1.注意装货的包装安全、木包装的消毒2.注意码头的合理性。首先是安排中检的问题,使用第三方O/R Mapping工具,如果是安排国外中检,如 Hibernate, MyBatis 等。(底层依然是 JDBC ,那肯定要先到国外码头。如果是在荷兰、日本、美国已经完成了中检,JDBC 是 Java 访问数据库的基石,其他技术都是对 JDBC 的封装)

二、JDBC概述

JDBC (Java DataBase Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),那么要根据客观的国内物流路线,定义了用来访问数据库的标准Java类库,来确定进口码头3.特种柜,(java.sql,javax.sql)使用这些类库可以以一种标准的方法、方便地访问数据库资源。 JDBC为访问不同的数据库提供了一种统一的途径,为者屏蔽了一些细节问题。 JDBC 的目标是使 Java 程序员使用 JDBC 可以连接任何提供了 JDBC 实现 (驱动程序)的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而简化和加快了过程。

简单来说,JDBC 本身是 Java 连接数据库的一个标准,是进行数据库连接的抽象层,由 Java编写的一组类和接口组成,接口的实现由各个数据库厂商来完成。

JDBC编写的步骤如下:

ODBC(Open Database Connectivity,式数据库连接),是微软在Windows平台下推出的。使用者在程序中只需要调用ODBC API,由 ODBC 驱动程序将调用转换成为对特定的数据库的调用请求。

三、获取数据库连接

3.1、加载注册驱动

java.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现。在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类(java.sql.DriverManager)去调用这些Driver实现。

加载驱动:加载 JDBC 驱动需调用 Class 类的静态方法 forName(),向其传递要加载的 JDBC 驱动的类名

3.2、注册驱动的原理

注册驱动:DriverManager 类是驱动程序管理器类,负责管理驱动程序

他通常有以下两个步骤:

3.3、获取连接对象

我们一般使用 DriverManager 的 getConnection 方法创建 Connection 对象

3.3.1、URL详解

JDBC URL 用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到数据库的连接。

JDBC URL的标准由三分组成(协议:子协议:子名称),各分间用冒号分隔。

协议:JDBC URL中的协议总是jdbc(固定写法)。

子协议:子协议用于标识一个数据库驱动程序。

子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库提供足够的信息。包含主机名(对应服务端的ip地址),端口号,数据库名。

url的常见写法:

jdbc:mysql://主机名称:mysql服务端口号/数据库名称?参数=值&参数=值

jdbc:mysql://localhost:3306/atguigu

jdbc:mysql://localhost:3306/atguigu**?useUnicode=true&characterEncoding=utf8**(如果JDBC程序与服务器端的字符集不一致,会导致乱码,那么可以通过参数指定服务器端的字符集)

jdbc:mysql://localhost:3306/atguigu?user=root&password=123456

3.4、数据库连接方法

3.4.1、方式一

我们可以通过直接获取注册驱动,将数据库信息写在代码中,这个的问题也是很明显的,那就是一个硬编码问题,当我们需要修改数据库的时候,需要直接修改Java源代码。

3.4.2、方式二

我们为了解决方式一硬编码的问题,需要将驱动信息放入配置文件,然后通过读取的方式来进行赋值。

使用配置文件的好处:

实现了代码和数据的分离,如果需要修改配置信息,直接在配置文件中修改,不需要深入代码。

如果修改了配置信息,去重新编译的过程。

四、DAO思想

4.1、没有DAO

在没有 DAO 的时候,我们的代码存在量的重复。

4.2、DAO介绍

DAO(Data Access Object) 数据访问对象是一个面向对象的数据库接口. 顾名思义就是与数据库打交道,夹在业务逻辑与数据库资源中间,将所有对数据源的访问操作抽象封装在一个公共 API 中。程序书写就是建立一个接口,接口中定义了此应用程序中将会用到的所有事务方法。DAO 中的主要操作: 增删改查(CRUD)。

通过以上图,DAO 作为组件,那其主要的是方法的设计,方法设计需要注意什么呢?

在保存功能中,调用者需要传递多个参数进来,然后把这些数据保存到数据库中。

在查询功能中,结果集的每行数据有多个列的值,然后把这些数据返回给调用者。

在过程中,如果遇到需要传递的数据有多个的时候,通常需要使用 JavaBean 对其进行封装

4.3、DAO规范

DAO本质就是一个可以重复使用的组件。他包括了两个规范:

分包规范(域名倒写.项目模块名.组件)

命名规范

DAO 接口 : 表示对某个模型的 CRUD 操作做规范,以 I 开头,interface。例如:IStudentDAO

DAO 实现类: 表示对某个 DAO 接口的实现,例如:EmployeeDAOImpl

DAO 测试类: 测试 DAO 组件中的所有方法,例如:EmployeeDAOTest

调用建议:面向接口编程

传统的做法 : EmployeeDAOImpl dao = new EmployeeDAOImpl();

面向接口编程 : IEmployeeDAO dao = new EmployeeDAOImpl();

五、JDBC之CRUD操作

5.1、Statement对象及其弊端

5.1.1、Statement对象

对象时用于执行静态 SQL 语句并返回它所生成结果的对象。

通过调用 Connection 对象的 createStatement() 方法创建该对象。该对象用于执行静态的 SQL 语句,并且返回执行结果。

Statement 接口中定义了下列方法用于执行 SQL 语句:

5.1.2、使用Statement对象的弊端

用Statement操作数据表存在弊端:

存在拼串操作,繁琐

存在SQL注入问题

SQL 注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令(如:SELECT user, password FROM user_table WHERE user='a' OR 1 = ' AND password = ' OR '1' = '1') ,从而利用系统的 SQL 引擎完成恶意行为的做法。

5.2、PreparedStatement

我们可以通过调用 Connection 对象的 方法获取对象,PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句。

对象所代表的 SQL 语句中的参数用问号(?)来表示,调用对象的 setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值。

5.3、PreparedStatement vs Statement

对象比对象的代码的可读性和可维护性。

能最可能提高性能。

DBServer会对预编译语句提供性能优化。因为预编译语句有可能被重复调用,所以语句在被DBServer的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中就会得到执行。

在statement语句中,即使是相同操作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存。这样每执行一次都要对传入的语句编译一次。

PreparedStatement 可以防止 SQL 注入 。

5.4、 ResultSet

查询需要调用 的 方法,查询结果是一个ResultSet 对象,ResultSet 对象以逻辑表格的形式封装了执行数据库操作的结果集,ResultSet 接口由数据库厂商提供实现。

ResultSet 返回的实际上就是一张数据表。有一个指针指向数据表的第一条记录的前面。

ResultSet 对象维护了一个指向当前数据行的游标,初始的时候,游标在第一行之前,可以通过 ResultSet 对象的 方法移动到下一行。调用 方法检测下一行是否有效。若有效,该方法返回 true,且指针下移。相当于Iterator对象的和方法的结合体。

当指针指向一行时, 可以通过调用 或 获取每一列的值。*Java与数据库交互涉及到的相关Java API中的索引都从1开始。*例如:

5.5、CRUD操作

5.5.1、User类

5.5.2、IUserDAO

5.5.3、UserDAOImpl

5.5.4、DaoUtils

5.5.5、测试类

六、操作BLOB类型字段

6.1、BLOB类型简介

MySQL中,BLOB是一个二进制型对象,是一个可以存储量数据的容器,它能容纳不同小的数据。**插入BLOB类型的数据必须使用PreparedStatement,因为BLOB类型的数据无法使用字符串拼接写的。**MySQL有四种BLOB类型,他们除了在存储的最信息量上不同外,除此之外他们是等同的。

如果在指定了相关的Blob类型以后,还报错:xxx too large,那么在mysql的安装目录下,找my.ini文件加上如下的配置参数:max_allowed_packet=16M。同时注意:修改了my.ini文件之后,需要重新启动mysql服务。

6.2、插入BLOB类型

6.3、修改BLOB类型

6.4、从数据库表中读取BLOG类型

七、批量处理

八、数据库事务

8.1、问题引出

案例: 银行转账, 从张无忌账户上给赵敏转 1000 块钱。

我们有一张account(账户表)。然后我们开始转账。

转账的步骤概细分为以下几个步骤:

查询张无忌的账户余额是否于等于1000。余额小于1000就提示温馨提示:亲,你的余额不足。如果余额于等于1000转账。

从张无忌的账户余额中减少1000。

在赵敏的账户余额中增加1000。

这个时候问题来了,当程序执行到第步和第步之间,突然出现一个异常,此时会造成转账前后数据不一致的问题,会造成转账了,但是对方的账户上没有多钱。 造成这个问题的根本原因是因为转入转出是两个单独的操作,其中一个失败后,不会影响到另一个的执行。但是在转账这个业务中,我们需要保证进出两个操作要么都成功,要么都失败。

这个时候就需要引出事务的概念。

8.2、事务

事务(Transaction,简写为tx):一组逻辑操作单元,使数据从一种状态变换到另一种状态。

事务处理(事务操作):保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务**回滚(rollback)**到最初状态。回滚可以看成是撤销操作。

为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全完成时,数据的一致性可以保持,而当这个单元中的一分操作失败,整个事务应全视为错误,所有从起始点以后的操作应全回退到开始状态。

8.3、事务的ACID属性

原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

一致性(Consistency)事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

隔离性(Isolation)事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。

8.4、数据库的并发问题

对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题:

脏读: 对于两个事务 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段。之后, 若 T2 回滚, T1读取的内容就是临时且无效的。

不可重复读: 对于两个事务T1, T2, T1 读取了一个字段, 然后 T2更新了该字段。之后, T1再次读取同一个字段, 值就不同了。

幻读: 对于两个事务T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插入了一些新的行。之后, 如果 T1 再次读取同一个表, 就会多出几行。

8.4.1、事务的隔离性

数据库事务的隔离性: 数据库系统必须具有隔离并发运行各个事务的能力, 使它们不会相互影响, 避免各种并发问题。

一个事务与其他事务隔离的程度称为隔离级别。数据库规定了多种事务隔离级别, 不同隔离级别对应不同的干扰程度,隔离级别越高, 数据一致性就越好, 但并发性越弱。

8.4.2、数据库的隔离级别

MySQL数据库支持4种事务隔离级别。Mysql 默认的事务隔离级别为:REPEATABLE READ。

8.4.3、设置隔离级别

每启动一个 mysql 程序, 就会获得一个单独的数据库连接. 每个数据库连接都有一个全变量 , 表示当前的事务隔离级别。

8.4.3.1、查看当前的隔离级别

8.4.3.2、设置当前mysql隔离级别

8.4.3.3、设置mysql的全隔离级别

8.5、事务的操作步骤

先定义开始一个事务,然后对数据作修改操作。

执行过程中,如果没有问题就事务,此时的修改将永久地保存下来。

如果执行过程中有问题(异常),回滚事务(rollback),数据库管理系统将放弃所作的所有修改而回到开始事务时的状态。

8.6、事务的注意事项

在默认情况下,事务会在执行完DML操作后会自动提交。

在进行查询操作的时候一般是不需要事务的,但是我们一般也会在查询中写事务

在写代码的时候,如果代码完全正常没有异常,但是数据库中的数据没有任何改变的话,说明是没有提交事务。

在MySQL中,只有InnoDB存储引擎支持事务,支持外键,MyISAM是不支持事务的。

以后处理事务的时候,必须在service层中进行控制。

九、连接池

9.1、JDBC数据库连接池的必要性

在使用基于数据库的web程序时,传统的模式基本是按以下步骤:

在主程序中建立数据库连接。

进行sql操作。

断开数据库连接。

这种模式会存在几个很显著的问题:

普通的JDBC数据库连接使用 DriverManager 来获取,每次向数据库建立连接的时候都要将 Connection 加载到内存中,再验证用户名和密码(得花费0.05s~1s的时间)。需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接。这样的方式将会消耗量的资源和时间。**数据库的连接资源并没有得到很好的重复利用。**若同时有几百人甚至几千人在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃。

**对于每一次数据库连接,使用完后都得断开,**否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将导致重启数据库。

这种不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。

9.2、数据库连接池

为解决传统中的数据库连接问题,我们可以采用数据库连接池技术。

数据库连接池的基本思想:就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个

数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最数据库连接数量限定了这个连接池能占有的最连接数,当应用程序向连接池请求的连接数超过最连接数量时,这些请求将被加入到等待队列中。

9.2.1、数据库连接池的原理以及优势

使用数据库连接池的优点也是很明显的:

资源重复使用

由于数据库连接得以重用,避免了频繁创建,释放连接引起的量性能开销。在减少系统消耗的基础上,另一方面也增加了系统运行环境的平稳性。

更快的系统反应速度

数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于连接池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而减少了系统的响应时间。

新的资源分配手段

对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置,实现某一应用最可用数据库连接数的限制,避免某一应用独占所有的数据库资源。

统一的连接管理,避免数据库连接泄漏

在较为完善的数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄露。

9.2.2、数据库连接池的属性

基本属性:连接池存了连接对象,而连接对象依赖四要素,所以四要素(driverClassName,url,username,password)是基本要求。

其他属性:对连接对象做限制的配置

1. 初始化连接数:在连接池中事先准备好初始化Connection对象。

2. 最多连接数:在连接池中最多有一定数量的Connection对象,其他客户端进入等待状态。

3. 最少连接数:在连接池中最少一定数量的Connection对象。

4. 最长等待时间:使用一定时间来申请获取Connection对象,如果时间到还没有申请到,则提示,自

动放弃。

5. 最长超时时间:如果你在一定时间之内没有任何动作,则认为是自动放弃Connection对象。

9.3、数据库连接池的分类

JDBC 的数据库连接池使用来表示,DataSource 只是一个接口,该接口通常由服务器(Weblogic, WebSphere, Tomcat)提供实现,也有一些开源组织提供实现:

DBCP是Apache提供的数据库连接池。tomcat 服务器自带dbcp数据库连接池。速度相对c3p0较快,但因自身存在BUG,Hibernate3已不再提供支持。

C3P0是一个开源组织提供的一个数据库连接池,**速度相对较慢,稳定性还可以。**hibernate官方推荐使用。

Proxool是sourceforge下的一个开源项目数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点

BoneCP是一个开源组织提供的数据库连接池,速度快。

Druid是阿里提供的数据库连接池,据说是集DBCP 、C3P0 、Proxool 优点于一身的数据库连接池,但是速度不确定是否有BoneCP快。

DataSource 通常被称为数据源,它包含连接池和连接池管理两个分,惯上也经常把 DataSource 称为连接池,DataSource用来取代DriverManager来获取Connection,获取速度快,同时可以幅度提高数据库访问速度。

注意:

数据源和数据库连接不同,数据源无需创建多个,它是产生数据库连接的工厂,因此整个应用只需要一个数据源即可。

当数据库访问结束后,程序还是像以前一样关闭数据库连接:conn.close(); 但conn.close()并没有关闭数据库的物理连接,它仅仅把数据库连接释放,归还给了数据库连接池。

9.4、DBCP连接池

DBCP 是 Apache 软件基金组织下的开源连接池实现,该连接池依赖该组织下的另一个开源系统:Common-pool。如需使用该连接池实现,应在系统中增加如下两个 jar 文件:

Commons-dbcp.jar:连接池的实现

Commons-pool.jar:连接池实现的依赖库

**Tomcat 的连接池正是采用该连接池来实现的。**该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。

数据源和数据库连接不同,数据源无需创建多个,它是产生数据库连接的工厂,因此整个应用只需要一个数据源即可。

当数据库访问结束后,程序还是像以前一样关闭数据库连接:; 但上面的代码并没有关闭数据库的物理连接,它仅仅把数据库连接释放,归还给了数据库连接池。

9.4.1、DBCP属性说明

9.4.2、获取连接的方式

9.4.3、注意事项

由于使用了DBCP,所以配置文件的key我们必须按照他官方给定的要求来书写。

9.5、Druid(德鲁伊)连接池

Druid是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、Proxool等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池,可以说是目前最好的连接池之一。

9.5.1、Druid参数详解

9.5.2、获取连接方式

9.5.3、注意事项

properties配置文件中的 key 一定要和 DruidDataSource 中对应的属性名一致。

port java.io.IOException;import java.io.InputStream;import java.net.URL;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;import javax.sql.DataSource;

/**

@author Xiao_Lin

@date 2021/1/3 19:47

*/public class DruidUtils

static catch (Exception e) }

public static Connection getConnection() catch (SQLException e) return null;}}

windows10怎么兼容性站点

android 文件加密隐藏文件夹吗

苹果macos系统怎么装

中通快递为什么一直招人

申通快递物流什么样啊

韵达快递发货的步骤是什么

饥荒钓鱼种地有什么用途

网页上传服务器后台不显示

优化seo绩效考核方法

免责声明:文中图片均来源于网络,如有版权问题请联系我们进行删除!

标签:jdbc mybatis 数据库 java 调用 驱动程序