【Spring】著作阅读笔记——ORM的诞生及Spring的集成

23 篇文章 2 订阅
16 篇文章 0 订阅

前言

  1. 回顾曾经约定俗成的开发规则,DAO模式 —— Oracle 官网介绍的开发标准(浏览即可)
  2. 什么是JDBC
  3. JDBC的缺陷
  4. ORM的诞生
  5. Spring集成ORM做的努力

1. JDBC

1.1 什么是JDBC

以下内容整理至百度

JDBC (Java Database Connectivity)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口。
JDBC API主要位于JDK中的java.sql包中(之后扩展的内容位于javax.sql包中)

具体的规范有:

  • Driver 会将自身加载到DriverManager中去。
  • DriverManager 负责加载各种不同驱动程序(Driver)并根据不同的请求,向调用者返回相应的数据库连接(Connection)
  • Connection 数据库的一个连接环境,在这个环境下可以实现数据库的交互
  • Statement 用以执行SQL查询和更新(针对静态SQL语句和单次执行)
  • PreparedStatement 用以执行包含动态参数的SQL查询和更新(在服务器端编译,允许重复执行以提高效率)
  • SQLException 代表在数据库连接的建立和关闭和SQL语句的执行过程中发生了例外情况(即错误)
    注意,现在主流使用的是JDBC2.0标准,也就是javax.sql.DataSource取代了用 DriverManager获取数据库连接

1.2 数据库驱动

  • Maven管理的MySQL驱动
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.25</version>
</dependency> 
  • 区分硬件的驱动
    独立显卡为什么要装驱动? 因为显卡厂商要告诉操作系统:“我很强,请识别出我的优势,CPU可以把渲染的工作交给我,需要我的时候请使用这些API”。操作系统就能很好得识别并控制独立显卡这个大家伙。硬件的驱动是比操作系统再高一层的软件,夹在应用程序和操作系统之间。
  • 数据库驱动是什么
    在Java的生态里,习惯把mysql-connector-java 称为驱动,或是因为它的核心类符合JDBCDriver规范,Driver翻译过来就是驱动。但是区别于硬件的驱动,这里的数据库驱动实质上就是应用软件。使用navicat 或者其他工具操作MySQL,重要的是什么?—— 连接。输入了用户名密码后,navicat 帮你连接了数据库。如果是在Java程序中,properties或者yml文件提供了url 密码等信息, mysql-connector-java 做了什么?—— 连接。所以,可以认为数据库驱动是数据库的连接管理器。
  • mysql-connector-java 和 JDBC 的关系
    mysql-connector-java 是MySQL厂商遵循JDBC 标准的数据库连接管理器,供程序员在程序中使用
    所以,当驱动注册好了后,程序员只用面向JDBC 的接口编程即可。

1.3 Spring 集成数据库连接池

Spring 的数据访问框架在数据库资源的管理上全部采用JDBC2.0标准的javax.sql.DataSource 用于数据库连接。由于数据库连接的新增和销毁是很占用资源且耗时的,所以把连接进行池化是很必要,具体思路如下:

  • 遵循JDBC的DataSource接口创建实现类A,用该实现类获取connection
  • connection.close()后,数据库连接不是释放而是返回到连接池中
  • 以后都使用A获取数据库连接
    以上思路的第三点,交给Spring IOC 容器提供该服务是最好不过了,所以让应用集成连接池,最简单的是可以用Spring 配置一个bean,在使用的时候注入即可。(这个bean的id = ‘dataSource’ 用于覆盖Spring的默认实现)
    <!-- 1.加载jdbc.properties文件的位置 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    
    <!-- 2.配置druid连接池 ,id是固定值,class是druid连接池类的全路径 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <!-- 配置连接数据库的基本信息 -->
        <property name="driverClassName" value="${db.driverClassName}"></property>
        <property name="url" value="${db.url}"></property>
        <property name="username" value="${db.username}"></property>
        <property name="password" value="${db.password}"></property>
    </bean>

Spring Boot 默认配置的是 HikariCP 连接池

1.4 使用JDBC与数据库交互

有了JDBC和数据库驱动,就能用java程序实现和数据库交互了。网上摘了一段代码下来:插入数据

private void insert(Person p) {
		Connection conn = null;
		Statement stmt = null;
		// 连接数据库url
		String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8";
		// 数据库用户名
		String user = "root";
		// 数据库密码
		String password = "root";
		try {
			// 1.加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			// 2.创建数据连接对象
			conn = DriverManager.getConnection(url, user, password);
			// 3.创建Statement对象
			stmt = conn.createStatement();
			// 对sql拼接
			String sql = "insert into t_person(name,age)values('" + p.getName()
					+ "','" + p.getAge() + "')";
			// 执行增加操作
			stmt.executeUpdate(sql);	
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {// 关闭数据库
				if (stmt != null)
					stmt.close();
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

2. ORM的诞生

JDBC的出现提供了访问数据库的便利,但是在面向对象的编程习惯里面,还是跟面向对象的表达存在着隔阂。ORM的出现就是尽可能的消除这些隔阂,值得一提的是,ORM是一个思想,并不是Java 所特有的。看以下代码体会以下ORM 怎么把sql语句封装成对象的操作。

public Double calcAmount(String customerid, double amount) 
{
    Customer customer = CustomerManager.getCustomer(custmerid); 
    // 根据客户等级获得打折规则
    Promotion promotion = PromotionManager.getPromotion(customer.getLevel()); 
    // 累积客户总消费额,并保存累计结果
    customer.setSumAmount(customer.getSumAmount().add(amount); 
    CustomerManager.save(customer); 
    return amount.multiply(protomtion.getRatio()); 
}

3. Spring集成ORM框架

3.1 JdbcTemplate

要说Spring 集成ORM框架,首先得提到Spring封装jdbc形成的JdbcTemplate (记住这种命名方式,Spring在后期提供的RabbitMqTemplateRedisTemplateRestTemplate 也有这个意味)。

  • Spring 封装模板代码
    注意到原生的JDBC实现:
 		catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {// 关闭数据库
				if (stmt != null)
					stmt.close();
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

既然每次写访问数据库的代码都要带上这大段,那么何不使用模板方法设计模式进行封装。

  • Spring 细化 SQLException 的语义
    JDBC 标准中 SQLException 存在比较宽泛的语义,不同数据库厂商会在方法中抛出的SQLException或是代表不同的意思,程序排错的时候看得就一脸懵逼,什么错都是SQLException。并且SQLException是一个 checked Exception,Java对checked Exception的约束是:当前抛出异常,上层选择要捕获或者继续抛出。Spring 作为一个劳模,看源码,把模糊的SQLException 转化成各种见名知意unchecked Exception 也就是所谓的RuntimeException 的子类,抛出后上层可以不捕获。Eg:
  1. InvalidDataAccessApiUsageException 无效数据访问API使用异常
  2. DataRetrievalFailureException 数据获取异常
  3. DeadlockLoserDataAccessException 死锁
  4. DataIntegrityViolationException 一致性检验异常
  • 综合上诉两个特点,JdbcTemplate 支持以下写法(忽略依赖注入的代码)
String sql="insert into user (name,deptid) values (?,?)";
List<Object[]> batchArgs=new ArrayList<Object[]>();
batchArgs.add(new Object[]{"caoyc",6});
batchArgs.add(new Object[]{"zhh",8});
batchArgs.add(new Object[]{"cjx",8});
jdbcTemplate.batchUpdate(sql, batchArgs);

3.2 Hibernate 和 MyBatis

Spring 集成HibernateMyBatis都同JdbcTemplate的思想大同小异

  1. 统一资源的管理方式
  2. Spring 异常管理的转译
  3. 事务管理及控制(这块内容比较大,后期还会更新)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值