本文来自【优锐课】——抽丝剥茧,细说架构那些事。

ORM(对象关系映射)是用于数据库编程的出色工具。只需一点经验和Java注释的强大功能,我们就可以相对轻松地构建复杂的数据库系统并利用生产力。关系数据库是大多数商业应用程序的主体。关系模型和面向对象的模型之间的不匹配总是很难映射。ORM工具以一种可以将对象映射到数据库中的方式为我们提供了帮助,就好像我们不再使用关系模型的记录而是使用面向对象模型中的对象一样。这改变了JDBC编程的整个范例。

它在哪里适合JDBC

在使用Java编写普通的JDBC代码时,你将同意它确实笨拙而费力,几乎每次我们向数据库发出CRUD请求时,一遍又一遍地编写相同的代码。现在,想象一下如果我们可以编写如下内容,世界将会如何:

 MyPojo hmm=new MyPojo();
MagicWand wave=MagicWand.getInstance();
wave.save(hmm);

并保留没有常规样板代码的POJO,而在我们与JDBC中的数据库交互时,我们不可避免地需要用某种方式来编写。你怎么看?可能?好吧,是的。魔术棒是Java中的ORM(对象关系映射)工具。市场上有很多可用的ORM工具。Hibernate是其中之一,并且非常有效且可靠。在本文中,我们将其作为实例引用示例代码。

JDBC方式

JDBC需要大量的代码来管理连接并维护各种规则,以确保我们的应用程序不会泄漏任何资源。 查看以下相对较大的JDBC代码,以获取员工记录的列表。

 public List<Employee> getEmployees() {
List<Employee> list = new ArrayList<>();
Connection con = null;
PreparedStatement pstmt = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost/minilibrary", "user1", "secret");
pstmt = con.prepareStatement("SELECT * FROM emp ORDER BY empId");
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
Employee emp = new Employee();
emp.setEmpId(rs.getInt(1));
emp.setName(rs.getString(2));
emp.setPhone(rs.getString(3));
emp.setEmail(rs.getString(4));
emp.setSalary(rs.getFloat(5));
emp.setDesignation(rs.getString(6));
list.add(emp);
}
} catch (SQLException | ClassNotFoundException ex) {
Logger.getLogger(EmployeeBean.class.getName()).log(Level.SEVERE, "Could not acquire record", ex);
throw new EmployeeException("Failed to retrieve employee from the database");
} finally {
try {
if (pstmt != null) {
pstmt.close();
}
if (con != null) {
con.close();
}
} catch (SQLException ex) {
Logger.getLogger(EmployeeBean.class.getName()).log(Level.SEVERE, null, ex);
}
}
return list;
}

尽管有各种各样的技术可以将其缩小到相当合适的大小,尤其是用于打开连接和记录问题的样板部分,但是从ResultSet中提取对象实例的主要逻辑仍然是相同的。当对象包含对其他对象或对象集合的引用时,情况就更糟了。

输入ORM

Hibernate减轻了JDBC编程的许多麻烦,并以更合理的方式解决了这个问题,或者我们应该说面向对象的方式。我们可以从选择的表列中创建一个POJO,并将其保存在数据库中。Hibernate直接支持类之间的继承和其他面向对象的关系。我们可以使用这些关系机制在关系数据库级别建立一对一,一对多,多对多映射。在Java注释@Entity的帮助下,创建实体很简单。@Id表示empId是数据库的主键。

 @Entity
public class Employee {
@Id
private int empId;
private String empName;
...
}

hibenate的关键在于配置设置,可以在通常称为hibernate.cfg.xml的XML文件中完成配置。也可以通过Java代码设置此配置设置,如下所示。

 public class HibernateUtil {

      private static final  SessionFactory sessionFactory;
private static final ServiceRegistry serviceRegistry;
static {
try {
Configuration config = getConfiguration();
serviceRegistry = new ServiceRegistryBuilder().applySettings(
config.getProperties()).buildServiceRegistry();
config.setSessionFactoryObserver(new SessionFactoryObserver() {
private static final long serialVersionUID = 1L; @Override
public void sessionFactoryCreated(SessionFactory factory) {
} @Override
public void sessionFactoryClosed(SessionFactory factory) {
ServiceRegistryBuilder.destroy(serviceRegistry);
}
});
sessionFactory = config.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static Session openSession() {
return sessionFactory.openSession();
} private static Configuration getConfiguration() {
Configuration cfg = new Configuration();
cfg.addAnnotatedClass(Employee.class );
cfg.setProperty("hibernate.connection.driver_class","com.mysql.jdbc.Driver");
cfg.setProperty("hibernate.connection.url","jdbc:mysql://localhost/hr");
cfg.setProperty("hibernate.connection.username", "user1");
cfg.setProperty("hibernate.connection.password", "secret");
cfg.setProperty("hibernate.show_sql", "true");
cfg.setProperty("hibernate.dialect","org.hibernate.dialect.MySQLSQLDialect");
cfg.setProperty("hibernate.hbm2ddl.auto", "update");
cfg.setProperty("hibernate.cache.provider_class","org.hibernate.cache.NoCacheProvider");
cfg.setProperty("hibernate.current_session_context_class", "thread");
return cfg;
}
}

设置好配置属性后,我们就可以开始了。现在让我们重写getEmployees函数的JDBC版本以获取雇员列表。

 public List<Employee> getEmployees(){
Session s=HibernateUtil.openSession();
s.beginTransaction();
List<Employee> list=s.createQuery("FROM Employee").list();
s.getTransaction().commit();
s.close();
return list;
}

并不是那么简单,清晰,并说明了为什么任何JDBC程序员都在数据库编程中使用Hibernate或任何其他ORM工具。

如果ORM是解决方案,那么JDBC是一个问题吗?

不,不,JDBC完全可以。实际上,在某些情况下(例如常见的CRUD操作),某种类型的对象关系映射是适当的,而通过JDBC连接API进行直接访问的传统方法占据了上风。ORM为程序员提供了一层便利。这种便利是否会带来性能代价。嗯,有很多传闻证明了这种缺点(尽管我尚未测试),但是我相信使用ORM工具的缺点远大于缺点。他们之间没有战争。一个可以弥补另一个缺点。从较高的角度来看,我们可以说– JDBC API在数据库编程中可以独立运行,而ORM工具则不能。即使我们在代码中显然不使用JDBC API,ORM也会始终使用下面的JDBC API。因此,以某种方式问我们应该选择哪个是一个荒谬的问题?ORM位于你的应用程序和JDBC之间,从而提供了编程的面向对象模型和关系数据库模型之间缺少的链接。实际上,这个所谓的ORM与JDBC交互以最终与数据库对话。下图可能会进一步阐明该概念。

图1:休眠在Java应用程序中的作用

结论

可以从Java应用程序直接调用Hibernate,也可以通过另一个框架访问它。无论是Swing应用程序,Servlet,JSP页面还是有权访问数据库的任何其他Java应用程序,我们通常都使用它来为应用程序创建数据访问层或替换现有的数据访问层。其他的ORM工具(例如MyBatis)通过不同的API和访问机制执行类似的功能。总体而言,ORM尤其是Hibernate比此高级概述更强大,更深入。也许本文提供了第一手的见解,并引起了你的兴趣,以探索兔子洞的深度。

感谢阅读!最后奉上近期整理出来的一套完整的java架构思维导图,分享给大家对照知识点参考学习。

在简单的JDBC程序中使用ORM工具的更多相关文章

  1. mybatis由浅入深day01_1课程安排_2对原生态jdbc程序中问题总结

    mybatis 第一天 mybatis的基础知识 1 课程安排: mybatis和springmvc通过订单商品 案例驱动 第一天:基础知识(重点,内容量多) 对原生态jdbc程序(单独使用jdbc开 ...

  2. 编写一个简单的 JDBC 程序

    连接数据库的步骤: 1.注册驱动(只做一次) 2.建立连接(Connection) 3.创建执行SQL的语句(Statement) 4.执行语句 5.处理执行结果(ResultSet) 6.释放资源 ...

  3. 01.原生态jdbc程序中问题总结

    1.数据库启动包配置到工程目录中(mysql5.1) mysql-connector-java-5.1.7-bin.jar 2.jdbc原生态操作数据库(程序) 操作mysql数据库 1 packag ...

  4. 最简单的jdbc程序

    package cn.ytu.mybatis.jdbc;   import java.sql.Connection; import java.sql.DriverManager; import jav ...

  5. 对原生态jdbc程序中问题总结

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import ...

  6. 简单ORM工具的设计和编写,自己项目中曾经用过的

    http://www.cnblogs.com/szp1118/archive/2011/03/30/ORM.html 在之前的一个项目中自己编写了一个简单的ORM小工具,这次重新整理和重构了一下代码, ...

  7. 在VS中手工创建一个最简单的WPF程序

    如果不用VS的WPF项目模板,如何手工创建一个WPF程序呢?我们来模仿WPF模板,创建一个最简单的WPF程序. 第一步:文件——新建——项目——空项目,创建一个空项目. 第二步:添加引用,Presen ...

  8. win32程序中简单应用mfc

    今日写程序在win32中用CRect发现报错,突然想起来.要引入mfc库.想重新建立一个工程添加对mfc的支持.发现选项不能选.查资料后发现. 在win32程序中简单应用mfc库,只需要简单的引入&l ...

  9. Windows程序设计笔记(二) 关于编写简单窗口程序中的几点疑惑

    在编写窗口程序时主要是5个步骤,创建窗口类.注册窗口类.创建窗口.显示窗口.消息环的编写.对于这5个步骤为何要这样写,当初我不是太理解,学习到现在有些问题我基本上已经找到了答案,同时对于Windows ...

随机推荐

  1. 【WPF学习】第二十三章 列表控件

    WPF提供了许多封装项的集合的控件,本章介绍简单的ListBox和ComboBox控件,后续哈会介绍更特殊的控件,如ListView.TreeView和ToolBar控件.所有这些控件都继承自Item ...

  2. Python3实现发送邮件和发送短信验证码

    Python3实现发送邮件和发送短信验证码 Python3实现发送邮件: import smtplib from email.mime.text import MIMEText from email. ...

  3. springboot集成quartz实现任务调度

    quartz 概述 特点 强大的调度功能 灵活的应用方式 分布式和集群能力 用到的设计模式 Builder 模式 factory模式 组件模式 链式写法 体系结构 调度器 任务 触发器 架构图 spr ...

  4. STM32 调试 24L01 心得

    大部分使用STM32开发nrf24L01的用户基本都是照搬常见的几个开发板的源代码,在这里我做一些总结: 1.源代码中在while(1)的循环中有 NRF24L01_TX_Mode();或NRF24L ...

  5. Git详解之分支使用

    前言 几乎每一种版本控制系统都以某种形式支持分支.使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作.在很多版本控制系统中,这是个昂贵的过程,常常需要创建一个源代码目录的完整副本 ...

  6. Git详解之初次运行

    配置文件 一般在新的系统上,我们都需要先配置下自己的 Git 工作环境.配置工作只需一次,以后升级时还会沿用现在的配置.当然,如果需要,你随时可以用相同的命令修改已有的配置. Git 提供了一个叫做 ...

  7. 透彻分析和解决一切javaWeb项目乱码问题

    前言 乱码是我们在程序开发中经常碰到且让人头疼的一件事,尤其是我们在做javaweb开发,如果我们没有清楚乱码产生的原理,碰到乱码问题了就容易摸不着头脑,无从下手. 乱码主要出现在两部分,如下: 第一 ...

  8. Altium Designer 14安装破解

    Altium Designer 14简称AD14,是一款专业的PCB设计软件,利用他可以计出专业的PCB元件.Altium Designer 14.3.10是目前的最新版本. Altium Desig ...

  9. num12---组合模式

    案例描述: 学校下有多个学院,每个学院下有多个专业系. 把学校.院系.专业  全都看成某个组织类型,含有添加add方法,删除remove方法,显示print方法. 如果有新增的院系.专业,新增加对应的 ...

  10. Python原来这么好学-1.2节: 在Linux中安装python

    这是一本教同学们彻底学通Python的高质量学习教程,认真地学习每一章节的内容,每天只需学好一节,帮助你成为一名卓越的Python程序员: 本教程面向的是零编程基础的同学,非科班人士,以及有一定编程水 ...