论坛首页 Java企业应用论坛

tiny-sqlmap1.0.1发布,用来弥补hibernate原生sql查询的不足

浏览 6555 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-06-05  

tiny-sqlmap的由来

最近给一个项目的框架做一些优化工作,该项目使用的是SSH这一套东西。似乎SSH在某些人眼里已经形成了一种惯性,做个web应用如果不用这SSH一套东西他都觉得那里不舒服似的,从不考虑自身应用的特点而选择合适的技术框架。不从实际出发乱选不合符本应用的技术框架必定带来不好的后果。对于我优化的这个项目而言,hibernate并没有给项目的开发效率提高,因为很多的查询都是使用了jdbcTemplate,导至以下问题:

 

1)  做个列表查询,用if判断查询条件,用StringBuffer拼装sql语句这样的代码占用整个业务方法,使得代码变得臃肿不可读。

2)  Sql写在程序文件里,用StringBuffer 拼装,这好比看了被压缩了得js代码一样难理解。

3)  SQL StringBuffer 拼装在应用随处可见,在Action,Service,Dao都有。

4)  SQL 注入得不到统一的控制。

 

Hibernate在对数据表的修改确实体现了极佳的开发效率,对上面这些问题的优化,我并没有选择推翻重来,而是在ibatis的基础上开发了个查询框架来解决上述的问题。

 

什么是tiny-sqlmap

 

tiny-sqlmap框架是从ibatis框架中剥离出来的,它非常的轻巧,也好扩冲。它仅提供sql的查询功能,对sql的查询操作,它支持SQL结果集映射、sql参数映射、动态sql的等功能。

 

tiny-sqlmap使用场景

如果你在便用hibernate的过程中也遇到像我这样的问题,你可以将其整合到你的项目中。

 

如果整合tiny-sqlmap

 

tiny-sqlmap通过SqlMapExecutor 接口向外部程序提供访问,先看看这个接口所提供的方法

 


 

它只提供了相关的数据查询方法。SqlMapExecutor对象由SqlMapExecutorFactoryBean工厂类,这是个spring的FactoryBean,所以要求在spring的环境中运行,SqlMapExecutorFactoryBean的配置如下:

 

 

<bean id="sqlMapExecutor" class="org.jorgie.dal.tinysqlmap.client.SqlMapExecutorFactoryBean">
  <property name="dataSource">
    <ref bean="dataSource"/>
  </property>
  <property name="sqlMapExecutorProperties">
     <props>
       <prop key="sql_executor_class" >org.jorgie.dal.tinysqlmap.engine.execution.LimitSqlExecutor</prop>
       <prop key="dialect_class" >org.jorgie.dal.tinysqlmap.engine.dialects.MySQLDialect</prop>
     </props>
  </property>
  <property name="sqlMapConfigLocation">
     <list>
       <value>test/entity/sqlMap/testSqlMap.xml</value>
       <value>test/entity/sqlMap/demoSqlMap.xml</value>
     </list>
  </property>
</bean>

 

 

 

dataSourcespring中配置的数据源对象。在sqlMapExecutorProperties中配置两个属性的作用是为了实现List queryForList(String id, Object parameterObject, int startIndex, int limit)实现分页功能。对于sqlmap xml文件的配置,配置方法和ibatis是一致的,只不过它只支持select语句的配置。

 

      如果保证与hibernate的事务一致?把tiny-sqlmap整合到你的应用中,你需要把你的事务管理器改成DataSourceTransactionManager,同时需要为配置在spring容器的LocalSessionFactoryBean对象将其useTransactionAwareDataSource属性设为true。 SqlMapExecutorFactoryBean内部会对数据源进行包装,通过使用TransactionAwareDataSourceProxy数据源来保证与hibernate在同一个事务中使用的是同一个Connection对象。

 

 

下面是具休的配置代码LocalSessionFactoryBean

 

<bean id="sessionFactory"
	class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource">
    <ref bean="dataSource" />
  </property>
  <property name="hibernateProperties">
    <props>
      <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
      <prop key="hibernate.show_sql">true</prop>
      <prop key="hibernate.generate_statistics">true</prop>
      <prop key="hibernate.connection.release_mode">auto</prop>
      <prop key="hibernate.autoReconnect">true</prop>
      <prop key="hibernate.jdbc.batch_size">30</prop>
    </props>
  </property>
  <property name="mappingDirectoryLocations"> 
     <list>
        <value>classpath:test/entity/</value>
     </list> 
  </property>
  <!--让hibernate Session使用TransactionAwareDataSourceProxy数据源 --> 
  <property name="useTransactionAwareDataSource" value="true"></property>
</bean>

 

    事务管理器,将HibernateTransactionManager改为DataSourceTransactionManager

 

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource" />  
</bean> 

 

 

 

 

   SqlMapExecutorFactoryBean对数据源的包装代码,这里的useTransactionAwareDataSource属生默认为true

 

if (this.dataSource != null) {
	DataSource dataSourceToUse = this.dataSource;
	if (this.useTransactionAwareDataSource
		&& !(this.dataSource instanceof TransactionAwareDataSourceProxy)) {
		dataSourceToUse = new TransactionAwareDataSourceProxy(
						this.dataSource);
	}
	state.setDataSource(dataSourceToUse);
	state.getConfig().getSqlMapExecutorImpl().setDataSource(dataSourceToUse);
}

 

 

 

附上源码及库文件,欢迎便用!

 

 

 

 

 

  • 大小: 22.2 KB
   发表时间:2013-06-06  
比较不错的想法!
0 请登录后投票
   发表时间:2013-06-07  
就给这点东西,都没有办法测试
0 请登录后投票
   发表时间:2013-06-08  
tangchao 写道
就给这点东西,都没有办法测试


现在还没有开发专门的测试工程,我对它的测试都是基于我们的项目而做的,你需要耐心一点。

我建议你这样处理一下,前提按上面我说的按把SqlMapExecutorFactoryBean配置在spring的容器中了:

1)在你的BaseDao中就定义个SqlMapExecutor类型的变量,通过spring的方式注入

2)新个sqlmap文件,把路径加到sqlMapConfigLocation下面

通过这么两步,你这可以调用 SqlMapExecutor里面的方法进行测试了,下面给一个sqlmap的格试
<?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="staffSqlMap" >
  <resultMap id="BaseResultMap" class="test.entity.Staff" >
    <result column="staff_id" property="staffId" jdbcType="VARCHAR" />
    <result column="dep_id" property="depId" jdbcType="INTEGER" />
    <result column="issn_id" property="issnId" jdbcType="VARCHAR" />
    <result column="name" property="name" jdbcType="VARCHAR" />
    <result column="staff_type" property="staffType" jdbcType="INTEGER" />
    <result column="passwd" property="passwd" jdbcType="VARCHAR" />
    <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
  </resultMap>
 
  <sql id="BaseColumnList" >
    staff_id, dep_id, issn_id, name, staff_type, passwd, create_time
  </sql>
  
  
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterClass="test.entity.Staff">
    select 
    <include refid="BaseColumnList" />
    from staff
    where staff_id = #staffId:VARCHAR#
  </select>
</sqlMap>
0 请登录后投票
   发表时间:2013-06-08  
看看mybatis吧,
0 请登录后投票
   发表时间:2013-06-09  
很方便,mark.
0 请登录后投票
   发表时间:2013-06-30  
这个想法不错,最好有个demo工程。
是否支持hibernate4,数据库是否支持oracle???
0 请登录后投票
   发表时间:2013-07-09  
有个Java的小工具类sql2o,也挺简单的,http://www.oschina.net/p/sql2o
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics