iBATIS课堂笔录_1001

来源:互联网 发布:淘宝联盟订单查询 编辑:程序博客网 时间:2024/05/17 09:17
orm框架 ------------ object relation mapping  对象关系映射


一 ORM:ORM<object relation mapping>关系数据库.


1.1:产生的原因:对象数据库的不同步.


ORM是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。
简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,
将java程序中的对象自动持久化到关系数据库中。
本质上就是将数据从一种形式转换到另外一种形式.
 
1.2  常见ORM框架
   1.Hibernate
灵活的设计,优秀的性能,齐全的文档
   2.Entity Bean(ejb)
重量级,成本高,开发周期长,学习曲线非常陡
   3.IBATIS  apache子项目
SQL-MAPPING,相对于hibernate的完全面向对象,IBATIS更加灵活。
但需要的代码量更大,而且需要直接编写SQL语句。
   4.TOPLink  (收费) 
   5.JDO  java-data-object






1 特点
   1. ibatis把sql语句从Java源程序中独立出来,放在单独的XML文件中编写,给程序的维护带来了很大便
利。
    2. ibatis封装了底层JDBC API的调用细节,并能自动将结果集转换成Java Bean对象,大大简化了Java数
据库编程的重复工作。
    3. 简单易于学习,易于使用, 非常实用。
    4. 因为Ibatis需要程序员自己去编写sql语句,程序员可以结合数据库自身的特点灵活控制sql语句,因
此能够实现比hibernate等全自动orm框架更高的查询效率,能够完成复杂查询。




2 与 hibernate的比较
                             IBATIS                             HIBERNATE
    ORM类型                  半自动                                一站式全自动
    映射关系               实体类和SQL语句                          实体类和数据库
    学习门槛                 容易                                  3倍于IBATIS
    SQL 的 优化           方便,进行细粒度的优化                    1 一般情况下,HIBERNATE 会把所有的字段都SELECT 2 UPDATE一般也是更新所有字段
    开发效率             IBATIS要求开发者编写具体的SQL 语句         HIBERNATE会自动生成SQL 语句
    数据库移植           标准SQL方便移植                             不同数据库类型的支持


3 使用 ibaitis
     <1>导包
     <2>数据库连接配置以及映射文件导入  假设文件名为sqlMapConfig.xml
     


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">


<sqlMapConfig>


<properties resource="sqlMapConf.properties" />

<transactionManager type="JDBC" >
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${username}"/>
<property name="JDBC.Password" value="${password}"/>
</dataSource>
</transactionManager>
<!-- 把对应的xml文件添加到这里 -->
<sqlMap resource="person.xml" />


</sqlMapConfig>
    
     
          上述中的sqlMapConf.properties示例
       driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/j2ee
username=root
password=123456


       当然也可以不用qlMapConf.properties文件,直接在配置文件写












     <3>编写映射文件,示例
   <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap>
<!-- 给类定义别名 -->
<typeAlias alias="person" type="com.Person"/>

<!-- bean属性和数据库字段的对应关系 -->
<resultMap id="pResultMap" class="person">
<result property="id" column="id"  />
<result property="name" column="name"/>
</resultMap> 

<!-- 获得所有列表 -->
<statement id="getList" resultMap="pResultMap">
SELECT * 
FROM person
</statement>
                     
                      <!-- 插入一条记录-->
     <statement id="insertPerson" parameterClass="person">
insert into person(id,name,age) 
values(#id#,#name#,#age#)
</statement>
                        
<!-- 更新一条记录-->
<statement id="updatePerson" parameterClass="person">
update person set 
name=#name#,
age=#age#
where id=#id#
</statement>
<!-- 删除一条记录-->
                      <statement id="deletePerson" parameterClass="int">
                 delete from person where id=#id#
                </statement>
<!-- 根据id加载-->
                      <statement id="getById" parameterClass="int" resultMap="pResultMap">
                 select *  from person where id=#id#
             </statement>


      <!-- 根据map加载-->
<statement id="getByMap" parameterClass="java.util.Map" resultMap="pResultMap">
                      select *  from person where name like #name# and age>=#age#
               </statement>


   </sqlMap>


    <3> 客户端使用
        获得 SqlMapClient实例
                Reader reader = Resources.getResourceAsReader("sqlMapConf.xml");
       SqlMapClient  sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
        sqlMap.queryForList("getList")//getList为映射文件中的某个id
               
//map条件使用示例


Map map=new HashMap();
map.put("name", "%a");
map.put("age", 20);
List<Person> list=qlMap.queryForList("getByMap",map);
for(Person p:list)
System.out.println(p.getName()+"--"+p.getId());


4  iBATIS事务


   看看上面连接数据库的配置
     <transactionManager type="JDBC" >
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${username}"/>
<property name="JDBC.Password" value="${password}"/>
</dataSource>
</transactionManager>
     
<transationManager>元素让您为SQL Map配置事务管理服务。 
属 性type指定所使用的事务管理器类型。 
这个属性值可以是一个类名,也可以是一个别 名。 
包含在框架的三个事务管理器分别是:JDBC,JTA和EXTERNAL。 


JDBC: 通过常用的Connection commit()和rollback()方法,让JDBC管理事务。 


JTA: 本事务管理器使用一个JTA全局事务,使SQL Map的事务包括在更大的事务范围内, 
这 个更大的事务范围可能包括了其他的数据库和事务资源。 
这个配置需要一个 UserTransaction属性,以便从JNDI获得一个UserTransaction。 


EXTERNAL: 这个配置可以让您自己管理事务。您仍然可以配置一个数据源, 
但事 务不再作为框架生命周期的一部分被提交或回退。 
这意味着 SQL Map外部应用的一部分必须自己管理事务。 
这个配置也可 以用于没有事务管理的数据库(例如只读数据库)。 


    程序中启动事务
      qlMap.startTransaction();
.........


     qlMap.commitTransaction();
      qlMap.endTransaction();






4  ibatis 分页
    一直以来ibatis的分页都是通过滚动ResultSet实现的,应该算是逻辑分页吧。逻辑分页虽然能很干净地独立于特定数据库,但效率在多数情
况下不及特定数据库支持的物理分页,而hibernate的分页则是直接组装sql,充分利用了特定数据库的分页机制,效率相对较高
 


      PaginatedList list = sqlMap.queryForPaginatedList (“getProductList”, 10);
      list.nextPage();
     list.previousPage();


     对于一个刚刚学习ibatis初学者来说,看到这个方法一定会很高兴,因为他可以让我们更加容易的进行过分页,但是当我们打开帮我文档的时候我们会发现这个方法已经过时了,我们于是可能会联想到是不是又有啥跟好的方法了,其实不是的,这个方法不像hibernate自带的分页方法,会根据不同的数据库进行优化,他完全是依赖jdbc驱动程序来实现分页的。


调用次序如下SqlMapClientImpl.queryForPaginatedList->SqlMapSessionImpl.queryForPaginatedList 
->SqlMapExecutorDelegate.queryForPaginatedList->GeneralStatement.executeQueryForList 
->GeneralStatment.executeQueryWithCallback->GeneralStatment.executeQueryWithCallback 
->SqlExecutor.executeQuery->SqlExecutor.handleMultipleResults() 


他取出来的数据要放到内存中,这个一来,如果数据量很大的,会严重的影响系统的性能,因此我不建议大家使用这种方式进行分页






5  spring 集成  ibaitis


spring 中有一个类叫
org.springframework.orm.ibatis.SqlMapClientFactoryBean  给它注入ibatis的配置文件以及datasource,用spring的datasource整合ibatis中的datasource
配置如下
<bean id="sqlMapClient"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<description>
iBATIS SQL Mapping配置文件名,系统要能够在CLASSPATH中找到该文件
</description>
<value>classpath:sqlmap-config.xml</value><!--对应文件在src目录下-->
</property>


<property name="dataSource"><ref local="dataSource"></ref></property><!--整合dataSource-->


</bean>





而在sqlmap-config.xml中则是存放其它的需要的配置文件资源

<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<settings cacheModelsEnabled="true"
enhancementEnabled="false"
lazyLoadingEnabled="false"
maxRequests="3000"
maxSessions="3000"
maxTransactions="3000"
useStatementNamespaces="false"/>
<sqlMap resource="sqlmap-mapping-mailmanage.xml"/>
</sqlMapConfig>


                 
         有了 SqlMapClient实例,我们就可以操作了




 当然spring 提供类SqlMapClientDaoSupport以及SqlMapClientTemplate来对ibatis的支持




使用的时候,我们只要继承SqlMapClientDaoSupport,并注入SqlMapClient实例 之
那么.就可以在代码中.
getSqlMapClientTemplate().queryForList(sqlStmID,param);




5  ibatis主键生成的不同数据库实现
<!-- oracle Example --> 
<insert id="insertProduct-ORACLE" parameterClass="product">   
   <selectKey resultClass="int" type="pre" keyProperty="id" >   
SELECT STOCKIDSEQUENCE.NEXTVAL AS VALUE FROM DUAL   
   </selectKey>   
   insert into PRODUCT (PRD_ID,PRD_DESCRIPTION) values (#id#,#description#)   
</insert>   
  
<!-- Microsoft SQL Server IDENTITY Column Example -->   
<insert id="insertProduct-MS-SQL" parameterClass="product">   
   insert into PRODUCT (PRD_DESCRIPTION)   
   values (#description#)   
   <selectKey resultClass="int" type="post" keyProperty="id" >   
select @@IDENTITY as value   
   </selectKey>   
</insert>   
  
<!-- MySQL Example -->   
<insert id="insertProduct-MYSQL" parameterClass="product">   
   insert into PRODUCT (PRD_DESCRIPTION)   
   values (#description#)   
   <selectKey resultClass="int" type="post" keyProperty="id" >   
select LAST_INSERT_ID() as value   
   </selectKey>   
</insert>  



原创粉丝点击