1、数据库
数据库,就是按照数据结构来组织、存储和管理数据的“仓库”。
数据库分为关系型数据库(sql数据库)与非关系型数据库(no-sql数据库),两者的区别在于是否使用SQL语句作为操作的方式和方法。我们常见的数据库多属于关系型数据库,比如MySql数据库、PostgreSql,oracle数据库。
2、数据库驱动
数据库驱动是不同数据库开发商(比如oracle mysql等)为了某一种开发语言环境(比如java)能够实现数据库调用而开发的一个程序,
数据库驱动的作用相当于一个翻译人员,将Java中对数据库的调用语言翻译成数据库自己的数据库语言,当然这个翻译(数据库驱动)是由各个开发商针对统一的接口自定义开发的。
常用的驱动:
1、MySQL
驱动类的名字:com.mysql.jdbc.Driver
JDBC URL(连接地址):jdbc:mysql://dbip:port/databasename
- dbip :为数据库服务器的IP地址,如果是本地可写:localhost或127.0.0.1。
- port :为数据库的监听端口,需要看安装时的配置,缺省为3306。
- databasename:数据库的名字。
2、SQL Server数据库
驱动类的名字:com.microsoft.jdbc.sqlserver.SQLServerDriver
JDBC URL:jdbc:microsoft:sqlserver://dbip:port;DatabaseName=databasename
- dbip :为数据库服务器的IP地址,如果是本地可写:localhost或127.0.0.1。
- port :为数据库的监听端口,需要看安装时的配置,缺省为1433。
- databasename:数据库的名字。
3、Oracle数据库
驱动类的名字:oracle.jdbc.driver.OracleDriver
JDBC URL:jdbc:oracle:thin:@dbip:port:databasename
- dbip :为数据库服务器的IP地址,如果是本地可写:localhost或127.0.0.1。
- port:为数据库的监听端口,需要看安装时的配置,缺省为1521。
- databasename:为数据库的SID,通常为全局数据库的名字。
如下图就是没有JDBC之前,java开发人员为了操作不同的数据库需要维护不同数据库的驱动程序
3、JDBC
JDBC的全称是Java数据库连接(Java Database connect),它是一套用于执行SQL语句的Java API。应用程序可通过这套API连接到关系数据库,并使用SQL语句来完成对数据库中数据的查询、更新和删除等操作。简单地说就是 连接 和 操作 数据库的组件。
public static void main(String[] args) throws Exception {
//1. 加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//2. 通过驱动管理类获取数据库连接
Connection conn = DriverManager.getConnection(url,username,password);
//3. 通过Connection对象创建Statement对象
Statement stmt = conn.createStatement();
//4. 执行sql语句
ResultSet rs = preparedStatement.executeQuery("SELECT * FROM ...") ;
//5. 遍历结果集
while(rs.next()){
String name = rs.getString("name") ;
}
//6. 关闭数据库连接,回收数据库资源
// 关闭顺序:依次关闭ResultSet、Statement、Connection等资源。
if(rs !=null){ // 关闭记录集
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt !=null){ // 关闭声明
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn !=null){ // 关闭连接对象
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
应用程序使用JDBC访问数据库的方式如下图所示:
从上图可以看出,应用程序使用JDBC访问特定的数据库时,需要与不同的数据库驱动进行连接。由于不同数据库厂商提供的数据库驱动不同,因此,为了使应用程序与数据库真正建立连接,JDBC需要提供访问数据库的API和封装与各种数据库服务器通信的细节。
4、datasource
数据源技术是Java操作数据库的一个很关键技术,流行的持久化框架都离不开数据源的应用。
数据源提供了一种 简单获取数据库连接的方式,并能在内部通过一个 池的机制来复用数据库连接,这样就大大减少创建数据库连接的次数,提高了系统性能。
需要数据源的原因:由于使用jdbc建立连接和销毁太过于浪费资源,因此需要一套高效的与数据库建立连接的组件,那就是数据源,数据源可以创建连接池。
常见的有DBCP、C3P0、druid、hikariCP等等
5、数据库连接池
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。连接池技术尽可能多地重用了内存的资源,大大节省了内存,提高了服务器的服务效率,能够支持更多的客户服务。通过使用连接池,将大大提高程序运行效率,同时,我们可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
以访问MySQL为例,执行一个SQL命令。
不使用连接池:
不使用数据库连接池的步骤:
TCP建立连接的三次握手
MySQL认证的三次握手
真正的SQL执行
MySQL的关闭
TCP的四次握手关闭
可以看到,为了执行一条SQL,却多了非常多我们不关心的网络交互。
优点 | 缺点 |
---|---|
实现简单 | 网络IO较多 数据库的负载较高 |
响应时间较长 | 响应时间较长 |
应用频繁的创建连接和关闭连接 | |
在关闭连接后,会出现大量TIME_WAIT 的TCP状态 |
使用连接池流程:
使用数据库连接池的步骤:
第一次访问的时候,需要建立连接。 但是之后的访问,均会复用之前创建的连接,直接执行SQL语句。
优点:
- 较少了网络开销
- 系统的性能会有一个实质的提升
- 没了麻烦的TIME_WAIT状态
6、持久层框架
6.1、ORM
对象-关系映射(Object-Relational Mapping,简称ORM),面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式, 业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。
对象-关系映射解释:
A . 简单:ORM以最基本的形式建模数据。比如ORM会将MySQL的一张表映射成一个Java类(模型),表的字段就是这个类的成员变量
B . 精确:ORM使所有的mysql数据表都按照统一的标准精确地映射成java类,使系统在代码层面保持准确统一
C . 易懂:ORM使数据库结构文档化。比如MySQL数据库就被ORM转换为了java程序员可以读懂的java类,java程序员可以只把注意力放在他擅长的java层面(当然能够熟练掌握MySQL更好)
D. 易用:ORM包含对持久类对象进行CRUD操作的API,例如create(), update(), save(), load(), find(), find_all(), where()等,也就是讲sql查询全部封装成了编程语言中的函数,通过函数的链式组合生成最终的SQL语句。通过这种封装避免了不规范、冗余、风格不统一的SQL语句,可以避免很多人为Bug,方便编码风格的统一和后期维护。
6.2、JdbcTemplate
JDBC也提供了一套操作数据库进行增删改查的接口,但是过于繁琐。
JdbcTemplate是spring提供访问jdbc的一个模板,是Spring对JDBC的封装,目的是使JDBC更加易于使用。
JdbcTemplate是Spring的一部分,它处理了资源的建立和释放,帮助我们避免一些常见的错误,比如忘了总要关闭连接。它运行核心的JDBC工作流,如Statement的建立和执行,而我们只需要提供SQL语句和提取结果,相比较于传统的JDBC的操作简单很多。
JdbcTemplate的用法:
JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
String sql = "INSERT INTO product VALUES (NULL, ?, ?);";
jdbcTemplate.update(sql, "iPhone3GS", 3333);
6.3、MyBatis
Mybatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层(半)ORM
框架
Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。
在SpringBoot中,MybatisAutoConfiguration类。可以看到数据源DataSource 注入到SqlSessionFactory 中,然后根据SqlSessionFactory 创建SqlSessionTemplate。这就完成了自动装配,我们就可以直接@Autowired直接使用
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
//...
}
@Bean
@ConditionalOnMissingBean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
ExecutorType executorType = this.properties.getExecutorType();
if (executorType != null) {
return new SqlSessionTemplate(sqlSessionFactory, executorType);
} else {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
Mybatis的组件:
各组件功能介绍:
- Mybatis的配置文件:SqlMapConfig.xml是Mybatis的全局配置文件,主要配置数据源、事务、加载映射文件等,它的名称可以是任意(最好见名知意)。Mapper.xml主要是配置Statement的相关信息,如SQL语句。
- SqlSessionFactoryBuilder:会根据XML配置或是Java配置来生成SqlSessionFactory对象.采用建造者模式(简单来说就是分步构建一个大的对象,例如建造一个大房子,采用购买砖头、砌砖、粉刷墙面的步骤建造,其中的大房子就是大对象,一系列的建造步骤就是分步构建)。
- SqlSessionFactory:用于生成SqlSession,可以通过 SqlSessionFactory.openSession() 方法创建 SqlSession 对象。使用工厂模式(简单来说就是我们获取对象是通过一个类,由这个类去创建我们所需的实例并返回,而不是我们自己通过new去创建)。
- SqlSession:相当于JDBC中的 Connection对象,可以用 SqlSession 实例来直接执行被映射的 SQL 语句,也可以获取对应的Mapper。
- Executor:MyBatis 中所有的 Mapper 语句的执行都是通过 Executor 执行的。(Mapper:由XML文件和Java接口组成,根据XML中配置的映射信息执行对应的SQL语句并返回执行结果。)
- Mapper接口:数据操作接口也就是通常说的 DAO 接口,要和 Mapper 配置文件中的方法一一对应,也就是必须和Mapper.xml中的增删改查标签Id一致。
- Mapper配置:用于组织具体的查询业务和映射数据库的字段关系,可以使用 XML 格式(Mapper.xml)或 Java 注解格式来实现。
- MappedStatement:作用是封装了Statement的相关信息,包括SQL语句、输入参数和输出结果等等。
Mybatis执行流程:
- 首先是加载Mybatis的全局配置文件,随后会加载SQL 映射文件或者是注解的相关 SQL 内容。
- 创建会话工厂,MyBatis 通过读取配置文件的信息来构造出会话工厂(SqlSessionFactory)。
- 创建会话,根据会话工厂,MyBatis 就可以通过它来创建会话对象(SqlSession),会话对象是一个接口,该接口中包含了对数据库操作的增、删、改、查方法。
- 创建执行器,因为会话对象本身不能直接操作数据库,所以它使用了一个叫做数据库执行器(Executor)的接口来帮它执行操作。
- 封装 SQL 对象,在这一步,执行器将待处理的 SQL 信息封装到一个对象中(MappedStatement),该对象包括 SQL 语句、输入参数映射信息(Java 简单类型、HashMap 或 POJO)和输出结果映射信息(Java 简单类型、HashMap 或 POJO)。
- 操作数据库,拥有了执行器和 SQL 信息封装对象就使用它们访问数据库了,最后再返回操作结果,结束流程。
6.4、JPA
JPA的全称是Java Persistence API, 即Java 持久化API,是SUN公司推出的一套基于ORM的规范
JPA规范本质上就是一种ORM规范,注意不是ORM框架——因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服务厂商来提供实现。JPA和Hibernate的关系就像JDBC和JDBC驱动的关系,JPA是规范,Hibernate除了作为ORM框架之外,它也是一种JPA实现。
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,底层还是用的实现jpa的hibernate技术,可使开发者用极简的代码即可实现对数据库的访问和操作
JPA框架的用法:
定义对象的操作的接口,继承JpaRepository核心接口。
import com.boot.jpa.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User,Integer> {
// 但条件查询
User findByAge(Integer age);
// 多条件查询
User findByNameAndAge(String name, Integer age);
// 自定义查询
@Query("from User u where u.name=:name")
User findSql(@Param("name") String name);
}
7、总结
JDBC: 连接和操作数据库的原生API,接近底层代码。
JDBC和数据源: 数据源是jdbc连接数据库的实现。
数据源和数据库驱动: 连接不同的数据库,就要使用不同的驱动。
数据源和连接池: 数据源会利用底层jdbc生成一些闲置的连接放入连接池,以供访问数据库时使用。
JdbcTemplate、MyBatis和数据源,操作数据库也是需要先连接到数据库的,所以要给jdbcTemplate、MyBatis设置数据源,以便jdbcTemplate、MyBatis能使用数据源的连接池。
jpa和Hibernate: Hibernate根据jpa规范实现的。底层也是利用数据源和JDBC,访问数据库。
JDBC和jpa:本质上,jdbc和jpa这两个东西不是一个层次的,
JDBC是数据库的统一接口标准。
jpa是ORM框架的统一接口标准。
用法有区别: jdbc更注重数据库,orm则更注重于java代码,
但是实际上jpa实现的框架底层还是用jdbc去和数据库打交道。
参考:
- https://www.cnblogs.com/yanze/p/9714703.html
- https://www.zhihu.com/question/45993333
- https://juejin.cn/post/6844903475239714823
- https://blog.csdn.net/An1090239782/article/details/107159335
- https://www.cnblogs.com/tanghaorong/p/13856465.html#:~:text=MyBatis%20%E6%98%AF%E6%94%AF%E6%8C%81%E5%AE%9A%E5%88%B6%E5%8C%96,%E5%8F%82%E6%95%B0%E4%BB%A5%E5%8F%8A%E8%8E%B7%E5%8F%96%E7%BB%93%E6%9E%9C%E9%9B%86%E3%80%82
- https://blog.csdn.net/u013541707/article/details/113182157
- https://blog.csdn.net/papima/article/details/78219000