在简单的JDBC程序中使用ORM工具
本文来自【优锐课】——抽丝剥茧,细说架构那些事。
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工具的更多相关文章
- mybatis由浅入深day01_1课程安排_2对原生态jdbc程序中问题总结
mybatis 第一天 mybatis的基础知识 1 课程安排: mybatis和springmvc通过订单商品 案例驱动 第一天:基础知识(重点,内容量多) 对原生态jdbc程序(单独使用jdbc开 ...
- 编写一个简单的 JDBC 程序
连接数据库的步骤: 1.注册驱动(只做一次) 2.建立连接(Connection) 3.创建执行SQL的语句(Statement) 4.执行语句 5.处理执行结果(ResultSet) 6.释放资源 ...
- 01.原生态jdbc程序中问题总结
1.数据库启动包配置到工程目录中(mysql5.1) mysql-connector-java-5.1.7-bin.jar 2.jdbc原生态操作数据库(程序) 操作mysql数据库 1 packag ...
- 最简单的jdbc程序
package cn.ytu.mybatis.jdbc; import java.sql.Connection; import java.sql.DriverManager; import jav ...
- 对原生态jdbc程序中问题总结
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import ...
- 简单ORM工具的设计和编写,自己项目中曾经用过的
http://www.cnblogs.com/szp1118/archive/2011/03/30/ORM.html 在之前的一个项目中自己编写了一个简单的ORM小工具,这次重新整理和重构了一下代码, ...
- 在VS中手工创建一个最简单的WPF程序
如果不用VS的WPF项目模板,如何手工创建一个WPF程序呢?我们来模仿WPF模板,创建一个最简单的WPF程序. 第一步:文件——新建——项目——空项目,创建一个空项目. 第二步:添加引用,Presen ...
- win32程序中简单应用mfc
今日写程序在win32中用CRect发现报错,突然想起来.要引入mfc库.想重新建立一个工程添加对mfc的支持.发现选项不能选.查资料后发现. 在win32程序中简单应用mfc库,只需要简单的引入&l ...
- Windows程序设计笔记(二) 关于编写简单窗口程序中的几点疑惑
在编写窗口程序时主要是5个步骤,创建窗口类.注册窗口类.创建窗口.显示窗口.消息环的编写.对于这5个步骤为何要这样写,当初我不是太理解,学习到现在有些问题我基本上已经找到了答案,同时对于Windows ...
随机推荐
- 正则表达式在c++中的实现
这个是最基础的解释器,它实现了串联.并联.克林闭包,字符集为除了()|*的ASCII字符,而且不能判断表达式合法,效率还很低,内存利用率低. 它只能判读输入的字符串是否符合表达式. #include& ...
- Intellij IDEA使用(一)项目模板类型
概述 IDEA默认打开后,会出现欢迎页面,可以选择打开Project的方式. 对于新建的Project,一般会选择[Create New Project],对于界面中,众多的Project类型,有时候 ...
- Git详解之服务部署
前言 到目前为止,你应该已经学会了使用 Git 来完成日常工作.然而,如果想与他人合作,还需要一个远程的 Git 仓库.尽管技术上可以从个人的仓库里推送和拉取修改内容,但我们不鼓励这样做,因为一不留心 ...
- Docker基础内容之仓库
前言 Docker提供了开放的中央仓库dockerhub,同时也允许我们使用registry搭建本地私有仓库.搭建私有仓库有如下的优点: 节省网络带宽,提升Docker部署速度,不用每个镜像从Dock ...
- SpringBoot系列专栏
学会使用SpringBoot能够极大地提升Spring应用的开发效率,可以说是目前开发应用Java必需掌握的工具之一,而且SpringBoot也是微服务应用的基础,只有学会了SpringBoot,你才 ...
- linux实用指令 | 程序员线上排查必知必会linux指令(持续更新中)
Linux线上排查程序员实用指南 一.乱码问题 二.帮助指令 1. help命令 2. man命令 3. info命令 三.性能监测与优化 1. top命令 参考资源 Linux线上排查程序员实用指南 ...
- 四、Django学习之关系表介绍及使用
关系表介绍及使用 一对一关系 xx = models.OneToOneField(to='表名',to_field='字段名',on_delete=models.CASCADE) #on_delete ...
- 自学Java第四章——《数组》
4.1 数组的相关概念和名词(了解) 1.数组(array): 一组具有相同数据类型的数据的按照一定顺序排列的集合. 把有限的几个相同类型的变量使用一个名称来进行统一管理. 2.数组名: (1)这个数 ...
- what is muxing and demuxing
They're short for multiplexing and demultiplexing. Multiplexing means combining different types of d ...
- 基于 H5与webGL 的低碳工业园区监控系统
前言 低碳工业园区的建设与推广是我国推进工业低碳转型的重要举措,低碳工业园区能源与碳排放管控平台是低碳工业园区建设的关键环节.如何对园区内的企业的能源量进行采集.计量.碳排放核算,如何对能源消耗和碳排 ...