数据访问中间件


数据访问中间件介绍 科学数据中心 沈志宏 2008.5 提纲 „ 中间件、数据访问中间件 „ ODBC、JDBC „ 连接、数据源与DBCP „ DAO与Spring „ ORM框架 中间件、数据访问中间件 中间件 „ 问题 1. 在设计阶段就开始关心数据库连接? 2. 更换数据库产品,更改代码? 3. 数据访问层的代码编写总是相近的重复 的,如何降低代码冗余? 4. 面向对象的编程和关系数据的不统一; 中间件 „ 中间件:可以为其它程序员复用、实现特定功 能接口的程序包或服务; „ 为其它开发人员提供统一的系统接口,屏蔽系 统的复杂性; „ 大大缩短软件开发周期; 中间件 „ 数据访问中间件,就是指一切连接应用程序和 数据库的软件。 „ 与一般的中间件一样,面向数据库的中间件允 许开发人员通过单一的、定义良好的API访问 另一台计算机上的资源,中间件的使用是解决 异质平台、异质环境、异质数据库的统一访问、 统一存取的最佳方案。 中间件 „ 中间件的作用是保证网络中各部件(软件和硬件)之 间透明地连接,即隐藏网络部件的异构性,尤其保证 不同网络、不同DBMS和某些访问语言的透明性,即下 面三个透明性。 • 网络透明性:能支持所有类型的网络 。 • 服务器透明性:不管服务器上的DBMS是何种型号 (ORACLE、SYBASE、DB2等),一个好的中间件都 能通过标准的SQL语言与不同DBMS上的SQL语言连接 起来。 • 语言透明性:客户机可用任何开发语言进行发送请 求和接受回答,被调用的功能应该像语言那样也是 独立的。 中间件 用户程序 MySQL Oracle SQLServer 用户程序 MySQL Oracle SQLServer 中间件 ODBC、JDBC ODBC简介 „ ODBC(Open Database Connectivity,开放数据库 互连)是微软公司确立和定义的,已被数据库界 广泛接受和采用,成为一种访问数据库的统一。 „ 通过ODBC,数据库应用程序不需要考虑不同数 据库的格式,而采用统一的方法去使用数据库。 „ 上是一组访问数据库的API函数库,应用程序可 以通过ODBC API函数操作数据库中的数据。 ODBC简介 ODBC简介 ODBC数 据源设置 ODBC简介 „ 环境(Environment) „ 使用一个全局文本用来存取数据,它包含应用于所 有ODBC session的信息,例如一个session的 connections句柄。在用ODBC之前你必须从环境中获 得这个句柄。 „ 连接(Connection) „ 指定ODBC驱动程序和数据源(数据库)。你可以在同 一环境中同时连接不同的数据库 ; „ 语句(Statement) „ ODBC使用SQL作为自己的语言。 因而只要简单的 认为语句就是你希望ODBC执行的SQL命令就行了; ODBC应用程序的基础流程 分配环境句柄 分配连接句柄 与服务器连接 分配语句句柄 初始化 释放环境句柄 SQL处理 释放语句句柄 语句处理和检索部分 与服务器断开 释放连接句柄 终止 相应的函数名 SQLAllocEnv SQLAllocConnect SQLConnect SQLAllocStmt SQLExecDirect (直接执行函数) SQLPrepare (语句预备函数 ) SQLExecute (语句执行函数 ) SQLDisconnect SQLFreeEnv SQLFreeConnect SQLFreeStmt ODBC示例 main() { HENV henv; /*说明henv是一个环境型变量*/ HDBC hdbc; /*说明hdbc是一个连接型变量*/ HSTMT hstmt; /*说明hstmt是一个语句句柄变量*/ RETCODE retcode; /*说明retcode是一个返回变量*/ SQLAllocEnv(&henv); /*分配一个环境句柄*/ SQLAllocConnect(henv,&hdbc); /*分配一个连接句柄*/ SQLConnect(hdbc,"学生",SQL_NTS,NULL,0,NULL,0);/*连接数据源*/ SQLAllocStmt(hdbc,&hstmt); /*分配一个语句句柄*/ retcode=SQLExecDirect(hstmt,"SELECT * FROM S",SQL_NTS);/*执行语句*/ .../*结果集处理*/ SQLDisconnect(hdbc); /*断开数据源*/ SQLFreeStmt(hstmt,SQL_DROP)/*释放一个语句句柄*/ SQLFreeConnect(hdbc); /*释放一个连接句柄*/ SQLFreeEnv(henv); /*当应用完成后,释放环境句柄*/ } 环境 连接 JDBC介绍 „ JDBC(Java DataBase Connectivity,数据库连接 )是 执行SQL语句的Java API。 „ JDBC原来是Java Soft公司设计的Java语言的数据库访问 API。最初的Java语言本身并没有访问DB的能力, JDBC是第一个支持Java语言的标准的数据库API。1996 年夏天,Sun公司推出了JDBC。现在JDBC驱动程序已 经被大多数主流数据库所用。 „ JDBC由一组用Java语言编写的类与接口组成。 „ JDBC扩充了Java的应用范围,用Java与JDBC API可以 发布一种包含远程数据库信息的Applet(小应用程序) 的WWW页面。 JDBC介绍 „ JDBC API通过驱动不同版本的Driver操作 各种数据库 JDBC介绍 JDBC介绍 JDBC介绍 //注册JDBC驱动 DriverManager .registerDriver(new net.sourceforge.jtds.jdbc.Driver()); String url = "jdbc:jtds:sqlserver://localhost:1433/test"; String user = "sa"; String password = ""; //根据url获取连接 Connection connection = DriverManager.getConnection(url, user, password); //创建SQL语句 Statement statement = connection.createStatement(); String sql = "SELECT 1"; //执行SQL语句 statement.execute(sql); statement.close(); 获取连接 创建语句 连接、数据源与DBCP 连接 „ 通过DriverManager连接数据库方式 Class.forName("org.gjt.mm.mysql.Driver").newInstance(); String url= “jdbc:mysql://localhost/myDB?user=soft&password=soft123” //myDB为数据库名 Connection conn= DriverManager.getConnection(url); 连接 „ 上述代码的问题 „ 硬编码数据库用户名密码 „ 安全性问题,通过反编译获取用户名密码 „ 可移植性问题,数据库参数有所修改时必须修改 源文件 „ 软件无法脱离数据库独立地存在 „ 解决办法 „ 使用配置文件存储数据库参数; „ 使用数据源DataSource; 数据源 „ 数据源是在JDBC 2.0中引入的一个概念,通过 javax.sql.DataSource这个接口来描述; „ 可以使用逻辑名称(Logic Name)从JNDI服 务中查询数据源,并通过数据源获得数据库连 接; DataSource的标准属性 用户登录名Stringuser 数据库服务器名称StringserverName 数据库服务器使用的端口IntportNumber 用户登录密码StringPassword 和服务器通讯使用的网络协议名StringnetworkProtocol 对数据源的描述Stringdescription 数据源接口实现类的名称StringdataSourceName 数据库名称,即SIDStringdatabaseName DataSource使用例子 Context ctx = new InitialContext(); // 从JNDI中查询OracleDataSource实例 DataSource ods = (DataSource) ctx.lookup (“datasourcename”); // 从查询到的OracleDataSource实例中获取数据库连接 Connection conn = ods.getConnection(); // 生成一个Statement实例 Statement stmt = conn.createStatement (); … … // 关闭Statement实例 stmt.close(); // 关闭连接 conn.close(); conn = null; 数据源 „ 与DriverManager相比两大主要优势 „ 通过逻辑名称获取连接,不需要硬编码数据 库连接参数,安全性和可移植性更高; „ DataSource接口允许实现者提供如连接 池,分布式事务处理等特性。 使用数据源实现解耦 DataSource提供方DataSource客户程序 DBCP:数据库连接池 „ 传统工作方式下,频繁的数据库连接 „ 每次连接都要占用一部分时间,数据库连接 的时间开销很大 „ 占用系统资源,数据库服务器负担重 使用数据库连接池 „ 对象池Pool,解决资源频繁分配释放的问题 „ 需要时从连接池中取出连接,使用后放回池内 „ 同时还有监视连接情况,优化系统性能的能力 DBCP „ 通过DriverManager接口只能获得物理连 接 „ 通过JDBC2.0扩展的连接池管理接口,可 以获得缓存的逻辑连接。 „ javax.sql.ConnectionPoolDataSource 接口 „ 资源管理器,管理被缓存的连接。数据库服务商 提供实现 „ javax.sql.PooledConnection 接口 „ 对物理连接的封装,同样由数据库服务商提供 Tomcat中配置DBCP factoryorg.apache.commons.dbcp.Basi cDataSourceFactory usernamesa password driverClassNameorg.hsqldb.jdbcDrive r urljdbc:hsqldb:database maxActive10 数据库连接池使用 // initialize JNDI lookup parameters Context ctx = new InitialContext(parms); ... DataSource cpds = (DataSource)ctx.lookup(“abandoned”); ... ... Connection pc = cpds.getConnection(); ... // do business logic conn.close(); apache-dbcp „ http://jakarta.apache.org/commons/dbcp/ „ 依赖commons-pool: http://jakarta.apache.org/commons/pool/ „ commons-pool实际是一个对象池,而连接池是对象池 的一种 „ 主要的两个对象 „ ObjectPool管理对象池中的对象,借出,回收 方法 „ PoolabeObjectFactory,负责生命周期管理 DAO与Spring DAO DAO DAO模式建议将对象和对象的CRUD操作分离; Create(创建)Read(读取)Update(更新) Delete(删除) PersonDao pd = new DaoFactory().getDao("person"); Person someone = pd.getPerson(1); String name = someone.getName(); ... someone.setName(“bluejoe”); pd.updatePerson(someone); Spring „ Spring是一个解决了许多在J2EE开发中常见的问题的强大框架; „ Spring的架构基础是基于使用JavaBean属性的Inversion of Control容 器; „ Spring提供了唯一的数据访问抽象,包括简单和有效率的JDBC框架,极 大的改进了效率并且减少了可能的错误。Spring的数据访问架构还集成 了Hibernate和其他O/R mapping解决方案。 „ Spring提供了一个用标准Java语言编写的AOP框架,它给POJOs提供了 声明式的事务管理和其他企业事务,应用程序能够抛开EJB的复杂性, 同时享受着和传统EJB相关的关键服务。 „ Spring还提供了可以和IoC容器集成的强大而灵活的MVC Web框架。 Spring http://www.springframework.org/ Spring Spring对JDBC的DAO的支持 „ Spring提供JdbcDaoSupport简化Jdbc Dao的开发, JdbcDaoSupport类有如下两个方法: „ void setDataSource(DataSource dataSource): 依赖注入所需的setter方法; „ getJdbcTemplate():获得JdbcTemplate对象通过 这种JdbcDaoSupport的支持,DAO对象无须手动 注册驱动,获取连接; Spring对JDBC的DAO的支持 „ JdbcTemplate提供的主要的CRUD方法: „ void execute(String sql):主要用于执行DDL语句 „ List query(String sql,Object[]args,RowMapper rowMapper):执 行SQL查询,并将每条记录映射成bean实例,返回bean实例集合 „ List queryForList(String sql,Object[] args):执行SQL查询,将 ResultSet的每条记录包装成List对象,返回这些List组成的集合, 结果为List的元素仍是List „ Object queryForObject(String sql,RowMapper rowMapper):执 行SQL查询,将查询的ResultSet包装成对象后返回 „ int update(String sql):执行SQL更新 „ int update(String sql,Object[] args):执行带参数的SQL更新 Spring对JDBC的DAO的支持 JdbcTemplate jt = new JdbcTemplate(dataSource); objects.addAll((List) (jt.query(sql, os, new RowMapper() { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new MyObject(rs.getString("A"), rs.getString("B"), rs.getString("C"), rs.getDate("D").getTime()); } }))); DAO的问题 „ DAO夹杂着过多的数据库操作和对象操作,如 果数据库表结构发生了变化,或者bean类发生 了变化,就必须来修改这个DAO; „ 程序员不得不为每一个bean都准备一个 DAO,而其共同的逻辑应该抽象出来,以提高 代码的复用性; „ 这个共同的逻辑实际上已经被抽象出来了,而 且相当流行,那就是O/R Mapping(对象关系 映射,ORM:Object Relational Mapping)。 ORM ORM „ 对象关系映射(Object Relational Mapping,简称 ORM)是一种为了解决面向对象与关系数据库存在的互 不匹配的现象的技术。 ORM „ 一般的ORM包括以下四部分: „ 一个对持久类对象进行CRUD操作的API; „ 一个语言或API用来规定与类和类属性相关的查 询; „ 一个规定mapping metadata的工具; „ 一种技术可以让ORM的实现同事务对象一起进行 dirty checking, lazy association fetching以及其 他的优化操作。 ORM „ 目前众多厂商和开源社区都提供了持久层框架的实 现,常见的有: „ Apache OJB (http://db.apache.org/ojb/) „ Cayenne (http://objectstyle.org/cayenne/) „ Jaxor (http://jaxor.sourceforge.net) „ Hibernate (http://www.hibernate.org) „ iBatis (http://www.ibatis.com) „ jRelationalFramework (http://ijf.sourceforge.net) „ mirage (http://itor.cq2.org/en/oss/mirage/toon) „ SMYLE (http://www.drjava.de/smyle) „ TopLink (http://otn.oracle.com/products/ias/toplink/index.html) Hibernate简介 „ Hibernate寓意:Let Java objects hibernate in the relational database. „ Hibernate 是Java应用和关系数据 库之间的桥梁,负责Java对象和关 系数据库之间的映射的ORM中间件。 Hibernate是一个开放源代码的对 象关系映射框架,它对JDBC进行了 非常轻量级的对象封装,使得Java 开发人员可以随心所欲的使用对象 编程思维来操纵数据库。 数据库 Hibernate框架 对象 应用程序 Hibernate http://www.hibernate.org Hibernate实例 简单步骤: 1. 配置数据库连接 2. 编写实体域对象 3. 创建O/R对象-关系映射文件 4. 通过Hibernate API 访问数据库 配置数据库链接 hibernate.cfg.xml true false net.sf.hibernate.dialect.MySQLDialect org.gjt.mm.mysql.Driver jdbc:mysql://localhost:3306/netstore root 123456 true gb2312 Hibernate 2.编写实体域对象 public class Customer { private Integer id; private String name; private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } ……setXxx,getXxx方法符合javaBean规范 利用hibernate API Configuration config = new Configuration().configure(); // 创建一个SessionFactory 实例 sessionFactory = config.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx = null; try { /* 开始一个事务 */ tx = session.beginTransaction(); session.save(customer); /* 提交事务 */ tx.commit(); } catch (Exception e) { if (tx != null) tx.rollback(); throw e; } finally { session.close(); } ibatis „ ibatis是一种“半自动化”的ORM实现。 „ 所谓“半自动”,是相对于目前主流的ORM的“全自动”,无论 Hibernate 还是Apache OJB,都对数据库结构提供了较为完整 的封装,提供了从POJO 到数据库表的全套映射机制。程序员往 往只需定义好了POJO 到数据库表的映射关系,即可通过 Hibernate或者OJB 提供的方法完成持久层操作。程序员甚至不 需要对SQL 的熟练掌握,Hibernate/OJB 会根据制定的存储逻 辑,自动生成对应的SQL 并调用JDBC 接口加以执行。 „ 而ibatis并不会为程序员在运行期自动生成SQL 执行。具体的 SQL 需要程序员编写,然后通过映射配置文件,将SQL所需的 参数,以及返回的结果字段映射到指定POJO; ibatis http://www.ibatis.com SQL map映射文件 Person.xml Ibatis编程框架 „ 首先要设置SQL Map,读入刚创建好的SQL Map XML配置文件 String resource = “com/ibatis/example/sql-map-config.xml”; Reader reader = Resources.getResourceAsReader (resource); sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader); „ 从数据库读取对象 SqlMapClient sqlMap = MyAppSqlMapConfig.getSqlMapInstance(); // as coded above … Integer personPk = new Integer(5); Person person = (Person) sqlMap.queryForObject (“getPerson”, personPk); Ibatis编程框架 „ 写对象进数据库 person.setHeightInMeters(1.83); // person as read from the database above person.setWeightInKilograms(86.36); … sqlMap.update(“updatePerson”, person); „ 从数据库中删除对象 sqlMap.delete(“deletePerson”, person); Hibernate与ibatis比较 „ hibernate 与 ibatis 都是目前最流行的 O/R mapping 框架 „ hibernate 它出身于 sf.net 现在已经是 JBoss 的一部分了 „ ibatis 它属于 apache 下的一个子项目 Hibernate与ibatis比较 „ hibernate 它是全封闭式的,对数据库的操作提供了完整封装, 所有的SQL都是自动生成和执行,开发人员不需要再关注底层的 建设,甚至不需要开发人员对SQL的熟练掌握,所有操作都是 java对象,而更注重业务逻辑,开发人员只需定义好POJO与数 据库的映射(*.hbm.xml),在对数据操作时只需调用hibernate 提 供的方法完成数据层的操作,hibernate/OJB 会根据制定的存储 逻辑,自动生成相应的SQL并调用JDBC接口完成执行; „ ibatis 它是半封闭式的,何为半封闭式,这相对hibernate 对 比,ibatis的着力点则在于POJO与SQL之间的映射关系,所有的 SQL都需要开发人员在映射文件编写,通过这个映射文件的配 置,将SQL所需要的参数传入进去和返回的结果字段映射到指定 的POJO,而且ibatis最好的一个亮点在于可以操作存储过程。 Hibernate与ibatis比较 „ iBATIS非常简单易学,Hibernate相对较复 杂,门槛较高。 „ 当系统属于二次开发,无法对数据库结构做到 控制和修改,那iBATIS的灵活性将比 Hibernate更适合; „ 系统数据处理量巨大,性能要求极为苛刻,这 往往意味着我们必须通过经过高度优化的SQL 语句(或存储过程)才能达到系统性能设计指 标。在这种情况下iBATIS会有更好的可控性 和表现; Hibernate与ibatis比较 „ iBATIS需要手写sql语句,也可以生成一部分, Hibernate则基本上可以自动生成,偶尔会写一些 Hql。同样的需求,iBATIS的工作量比Hibernate要 大很多。类似的,如果涉及到数据库字段的修改, Hibernate修改的地方很少,而iBATIS要把那些sql mapping的地方一一修改。 „ 以数据库字段一一对应映射得到的PO和Hibernate 这种对象化映射得到的PO是截然不同的,本质区别 在于这种PO是扁平化的,不像Hibernate映射的PO 是可以表达立体的对象继承,聚合等等关系的,这 将会直接影响到你的整个软件系统的设计思路。 报告完毕,谢谢!
还剩63页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

hanfre

贡献于2017-01-18

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf