Loonframework-DAO-Alpha-0 1 0发布

Loonframework-DAO是一个轻量级的DAO框架实现,适用于小规模项目的快速开发。本文介绍了其配置、事务管理、数据操作模式及xml查询功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                ------------------------------
 Loonframework-DAO-Alpha-0.1.0 - 2008年2月24日
------------------------------

开发JDK: JDK1.4(所以此版本不支持Annotation)

文件名称:Loonframework-DAO-Alpha-0.1.0.jar
                    Loonframework-DAO-Alpha-0.1.0-src.zip

版本声明:此为测试用版本,是一个供测试与调整用的系统原型,不保证现有接口或函数实现在可见的未来无变更,不保证运行效率及错误会得到有效处理,强烈反对任何个人或组织将此版本投入到实际或自认为有用的项目中……

版权声明:Loonframework下属所有源码遵循Apache License 2.0协议,保留对其下代码的版权,任何对源代码的改进和变动,请告知原作者;不能将Loonframework全部或部分编译后再以其他项目名义发布, 不得经简单修改单独商品化销售.所有对Loonframework源码与文档的引用和转载请注明出处.

1.什么是Loonframework

Loonframework由三个子项目构成,分别对应DAO框架实现,WEB框架实现,以及一个2D的GAME框架实现,全部完成后将作为一个快速开发用综合框架而存在;目前三部分都尚处于开发阶段。

2.关于Loonframework-DAO

Loonframework-DAO是loonframework项目下的DAO实现,是一个轻量级、低外部依赖度的实现;为实现小规模项目的快速开发而诞生,目前提供了jdbc数据接口的封装及简单的pojo应用处理能力(但并不是彻底的orm)。loonframework-DAO本身是一个试验性质的项目,内部提供了事务、日志、Cache、异常处理等方面的简单实现,能够不依赖于任何第三方项目而单独运行,当然也可以通过接口选择和其它项目并用,将会陆续提供支持第三方的template以供调用。

3.关于Loonframework-DAO的文件构成


本次公开测试的代码部分如上图所示。

4.关于Loonframework-DAO的初始化设置

Loonframework-DAO通过读取cfg.lf.xml文件初始化设置,该文件基本配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<loon>
  <!-- 在loonframework中,配置会映射到一个对象实体进行操作,DAOFruit为数据驱动设定 --> 
  <pojo id="dao" class="org.loon.framework.pojo.sys.DAOFruit">
  <!-- 驱动别名,选填 -->
     <set name="alias"><value type="string">mysql</value></set>
  <!-- jdbc驱动类,可使用全写也支持'mysql'、'oralce'这样的简写方式 -->   
     <set name="jdbcClass"><value type="string">org.gjt.mm.mysql.Driver</value></set>
  <!-- url地址 -->            <set name="url"><value type="string">jdbc:mysql://localhost:3306/test?useUnicode=true</value></set>
  <!-- 用户名 -->    
     <set name="use"><value type="string">ltest</value></set>
  <!-- 密码 -->
     <set name="pwd"><value type="string"></value></set>
  <!-- 最小连接数,选填。loonframework-dao内置有一个小型的连接池,可通过DAOManager类启动-->     
     <set name="minconnection"><value type="int">100</value></set>
  <!-- 最大连接数,选填-->     
     <set name="maxconnection"><value type="int">100</value></set>
  <!-- 超时设定 -->
     <set name="timeout"><value type="int">5</value></set>
   </pojo>
   <pojo id="jtds" class="org.loon.framework.pojo.sys.DAOFruit">
     <set name="alias"><value type="string">jtds</value></set>
     <set name="jdbcClass"><value type="string">net.sourceforge.jtds.jdbc.Driver</value></set>
     <set name="url"><value type="string">jdbc:jtds:sqlserver://localhost:1433/test</value></set>
     <set name="use"><value type="string">sa</value></set>
     <set name="pwd"><value type="string"></value></set>
     <set name="minconnection"><value type="int">100</value></set>
     <set name="maxconnection"><value type="int">100</value></set>
     <set name="timeout"><value type="int">5</value></set>
   </pojo>
   <!-- LOGFruit为日志设定 -->
   <pojo id="log" class="org.loon.framework.pojo.sys.LOGFruit">
     <!-- 此项为生成的文件名,可以设定相关路径,无设置以默认路径保存 -->
     <set name="file"><value type="string">log.txt</value></set>
     <!-- 此项为log服务名,启动服务后有效 -->
     <set name="servername"><value type="string">logserver</value></set>
     <!-- 服务器所在地址 -->
     <set name="host"><value type="string">127.0.0.1</value></set>
     <!-- 服务器端口 -->
     <set name="port"><value type="string">8071</value></set>
     <!-- 是否在控制台显示log中信息 -->
     <set name="filesys"><value type="boolean">true</value></set>
     <!-- 是否保存log文件 -->
     <set name="filemark"><value type="boolean">false</value></set>
     <!-- 是否允许log服务启动 -->
     <set name="netmark"><value type="boolean">false</value></set>
   </pojo>
   <!-- 此项为基础配置,在0.1.0版本中未实装 -->
   <pojo id="cfg" class="org.loon.framework.pojo.sys.CFGFruit">
     <set name="encoding"><value type="string">utf-8</value></set>
     <set name="cache"><value type="boolean">true</value></set>
     <set name="timeout"><value type="long">60</value></set>
     <set name="sleep"><value type="long">10</value></set>
   </pojo>
</loon>

5.关于Loonframework-DAO的事务管理

package test;

import java.sql.SQLException;

import org.loon.framework.dao.DAOManager;
import org.loon.framework.dao.DAOTransaction;
import org.loon.framework.log.Log;
import org.loon.framework.log.LogFactory;

public class DAOTransactionTest ...{
    
    final static private Log log=LogFactory.getInstance(DAOTransactionTest.class);
    
    public static void main(String[]args)...{    
        //获得默认事务
        DAOTransaction transaction= DAOManager.getDefaultTransaction();
        try ...{
            System.out.println(transaction.getTransactionConnection().isClosed());
        }
 catch (SQLException e) ...{
            log.debug(e.getMessage());
        }

        
    }

}

通过DAOManager,我们得到了一个通过连接池获取的,简化了的事务操作。

DAOManager提供的部分方法如下:



利用DAOTransaction接口,我们可以构建一个简单的事务管理实现。

除了DAOManager外,本项目还提供了一个
javax.transaction.Transaction的实现,位于org.loon.framework.dao.jta下,需要用户提供UserTransaction实现。


6.关于Loonframework-DAO中的Engine

在Loonframework-DAO中,原则上所有的数据操作都要通过Engine类派生。此类位于org.loon.framework.dao下。

其中静态方法如下:



我们可以通过读取默认配置,设置connection、datasource、daofruit或者选择配置文件中指定的pojo创建Engine。

在Engine中,目前提供了两种数据处理模式可供选择。

1.通过Execute实现进行操作
//选择名为dao的数据源配置
Engine engine=Engine.begin("dao");
//获得一个Execute操作
Execute execute=engine.makeExecute();

Execute接口如下:


Execute接口是一个基于JDBC的常用CRUD操作封装,他将所有的SQLException封装为精简的LException异常进行处理,并提供了一个复刻ResultSet的Query结果集。

Query接口如下(部分,基本为ResultSet复刻):


Query结果集没有数据库依赖,是一个存在于内存中的ResultSet缓存,我们完全可以关闭数据库后如常使用Query接口,但这也意味着Query中的数据量始终不能保存过大,否则过多的Query将导致内存耗尽。在下一版本会提出解决方案。

Query接口基本用法如下:
//选择名为dao的数据源配置
Engine engine=Engine.begin("dao");
//获得一个Execute操作
Execute execute=engine.makeExecute();
Query query=execute.sqlQuery("select * from ltest");

  while(query.isNext())...{
            //输出数据
            System.out.println(query.getString(0));
            System.out.println(query.getString("name"));
  }

我们可以看出,Query接口缓存ResultSet后滚动结果集的方式几乎与ResultSet接口相同;区别在于,Query接口内部是通过数组及Map实现的,所以索引由0开始。

由于Query本质上是由一个数组内部封装Map实现,所以也提供了很多集合操作功能,如叠代器操作。
for(Iterator it=query.iterator();it.hasNext();)...{
            System.out.println(((Map)it.next()).get("id"));
}

Query甚至可以通过makeTo方法直接自身匹配为目标类型
//将query中数据映射到指定类中自动匹配,并返回对象数组
        Object[] ltests=query.makeTo(Ltest.class);
        //ArrayIterator为loonframework提供的数组叠代器
        ArrayIterator it=new ArrayIterator(ltests);
        for(;it.hasNext();)...{
            System.out.println("name="+((Ltest)it.next()).getName());
        }


在Execute接口的辅助工具中,还有如Select类这样的存在。

Select是一个简单的xml文件配置查询器,他用于查询及返回存在于xml中的sql语句。

比如,我有已配置好的sql语句如下:
<loon>
<sql>
      <list id="list1"><![CDATA[select * from ltest]]></list>
      <list id="list2"><![CDATA[select * from ltest where id>#id# and name like '%#name#%']]></list>
      <list id="list3"><![CDATA[select count(id) from ltest]]></list>
</sql>
</loon>

借助Select类可以这样获得动态的sql语句:
        Select select =new Select();
        //或者Select select=Select("/sql.lf.xml");
        //初始一个xml文档
        select.initializeConfigure("/sql.lf.xml");
        //以getSelect方式获得指定名称的节点数据
        List list=execute.sqlQueryToList(select.getSelect("list1"));
        for(Iterator it=list.iterator();it.hasNext();)...{
            System.out.println(((Map)it.next()).get("id"));
        }

        

Select还可以根据不同的设置读取任意xml文档,比如有ibatis演示用例的Account.xml:
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap      
    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"      
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Account">

  <!-- Use type aliases to avoid typing the full classname every time. -->
  <typeAlias alias="Account" type="com.mydomain.domain.Account"/>

  <!-- Result maps describe the mapping between the columns returned
       from a query, and the class properties.  A result map isn't
       necessary if the columns (or aliases) match to the properties 
       exactly. -->
  <resultMap id="AccountResult" class="Account">
    <result property="id" column="ACC_ID"/>
    <result property="firstName" column="ACC_FIRST_NAME"/>
    <result property="lastName" column="ACC_LAST_NAME"/>
    <result property="emailAddress" column="ACC_EMAIL"/>
  </resultMap>

  <!-- Select with no parameters using the result map for Account class. -->
  <select id="selectAllAccounts" resultMap="AccountResult">
    select * from ACCOUNT
  </select>

  <!-- A simpler select example without the result map.  Note the 
       aliases to match the properties of the target result class. -->
  <select id="selectAccountById" parameterClass="int" resultClass="Account">
    select
      ACC_ID as id,
      ACC_FIRST_NAME as firstName,
      ACC_LAST_NAME as lastName,
      ACC_EMAIL as emailAddress
    from ACCOUNT
    where ACC_ID = #id#
  </select>
   
  <!-- Insert example, using the Account parameter class -->
  <insert id="insertAccount" parameterClass="Account">
    insert into ACCOUNT (
      ACC_ID,
      ACC_FIRST_NAME,
      ACC_LAST_NAME,
      ACC_EMAIL
    values (
      #id#, #firstName#, #lastName#, #emailAddress#
    )
  </insert>

  <!-- Update example, using the Account parameter class -->
  <update id="updateAccount" parameterClass="Account">
    update ACCOUNT set
      ACC_FIRST_NAME = #firstName#,
      ACC_LAST_NAME = #lastName#,
      ACC_EMAIL = #emailAddress#
    where
      ACC_ID = #id#
  </update>

  <!-- Delete example, using an integer as the parameter class -->
  <delete id="deleteAccountById" parameterClass="int">
    delete from ACCOUNT where ACC_ID = #id#
  </delete>

</sqlMap>

    // 也可用于读取其他框架中通过xml进行的sql设置
        select.initializeConfigure("/Account.xml","sqlMap","select","id");
        System.out.println(select.getSelect("account"));

此时我们只要知道目标节点,下属子节点名以及属性就可以检索其中的sql语句

Select类也允许将object中数据自动匹配到获得的sql的#?#标记中

Ltest test=new Ltest();
System.out.println(select.matchObject(test, "list2"));

此时,会自动匹配所有符合条件的数据到sql中,完成sql语句。



2.通过Handle实现进行操作

该接口目前设置如下:


Handle是Execute的二次封装,他将Execute抽象为针对pojo映射进行操作。

Engine engine=Engine.begin();
//与Execute相同,Handle也需要通过Engine获得
Handle handle=engine.makeHandle();

获得Handle后,假设我有如下pojo对象。

public class Role...{

    int caseid;

    String name;

    long sex;

    Date day;

    boolean die;

    String death;

    public int getCaseid() ...{
        return caseid;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值