论坛首页 Java企业应用论坛

ibatis/Mybatis实战分享与讨论

浏览 13010 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-12-22  
悲剧了 写道
melin 写道
不太喜欢mybatis。封装的太深,有个问题还难定位。mybatis优势就是sql写在配置文件中。用spring jdbc+freemarker一样能够做到这样的,而且简洁


确实是sql写在配置文件是唯一优势,但是spring jdbc+freemaker要得到mybatis的效果有点难,你们具体是怎么做,动态sql这块,返回值这个映射?

很感兴趣啊,能给讲讲吗?

支持 spring jdbc。

我是使用了 SpringSide 中的方式,用 Velocity 来解析 xml 中的 sql 语句。

返回值这个映射,可以用 Spring 提供的 BeanPropertyRowMapper,自己不用操心。

  <!-- 多表 join 查询  sql 例子 -->
  <bean id="sqlRegistry" class="com.xyz.sql.SqlRegistry">
		<!-- 多表 join 查询  sql 例子 -->
		<property name="sqlForSearchCity">
			<value><![CDATA[
			SELECT c.id as id, c.name as name, c.other_name as other_name, c.people_num as people_num,
				c.sheng_id as sheng_id, c.insert_time as insert_time, c.last_update_time as last_update_time,
				s.name as shengName, s.other_name as shengOtherName, s.city_num as shengCityNum
			FROM city c
			left outer join sheng s on c.sheng_id = s.id
			WHERE 1=1
			
			## Dynamic Content
			#if ($param_shengId)
			AND c.sheng_id = :param_shengId
			#end
			
			ORDER BY c.id DESC
			]]></value>
		</property>
		
  </bean>
0 请登录后投票
   发表时间:2011-12-22  
虽然很忙,还是忍不住登录上来吐槽几句。

1.用mybatis的人基本都不用手写出来每一行SQL吧?用mybatis的代码生成器自动生成crud就可以了。

2.分页确实是个问题,稍微成型点的公司都有能力开发mybatis的代码生成器插件吧?实在不会开发的去看我写的插件,我博客里面有。所以分页不是问题,而且分页的性能绝对足够高,分页SQL怎么工作自己能控制。

3.n+1查询问题,这个通过配置关联关系就可以了,完全可以避免,不算事。

4.性能问题,淘宝用的ibatis,还用说别的么?在sql映射文件中合理的配置cache后速度绝对一流。

5.还是回到插件问题上头来,可以写代码生成器的插件生成action,service,xml,前台crud的模板代码,crud类项目开发速度绝对一流。

用hibernate的同志,将你的项目复制三份以上改名部署在同一个tomcat里面,不改jvm参数你去启动tomcat试试?不报内存不够用都对不起你!mybatis的绝对没问题,不服就部署10份对比一下?
2 请登录后投票
   发表时间:2011-12-22  
peihexian 写道
虽然很忙,还是忍不住登录上来吐槽几句。

1.用mybatis的人基本都不用手写出来每一行SQL吧?用mybatis的代码生成器自动生成crud就可以了。

2.分页确实是个问题,稍微成型点的公司都有能力开发mybatis的代码生成器插件吧?实在不会开发的去看我写的插件,我博客里面有。所以分页不是问题,而且分页的性能绝对足够高,分页SQL怎么工作自己能控制。

3.n+1查询问题,这个通过配置关联关系就可以了,完全可以避免,不算事。

4.性能问题,淘宝用的ibatis,还用说别的么?在sql映射文件中合理的配置cache后速度绝对一流。

5.还是回到插件问题上头来,可以写代码生成器的插件生成action,service,xml,前台crud的模板代码,crud类项目开发速度绝对一流。

用hibernate的同志,将你的项目复制三份以上改名部署在同一个tomcat里面,不改jvm参数你去启动tomcat试试?不报内存不够用都对不起你!mybatis的绝对没问题,不服就部署10份对比一下?

hibernate 同名类加载的问题,碰到过
0 请登录后投票
   发表时间:2011-12-22   最后修改:2011-12-22
hibernate用起来感觉很笨重,而且orm和hql让我们无法看到原始的sql,或者sql直接写在java代码中,用惯了ibatIS再来用hibernate觉得很不舒服,而且hibernate的性能也是一个大问题
0 请登录后投票
   发表时间:2011-12-22  
peihexian 写道
虽然很忙,还是忍不住登录上来吐槽几句。

1.用mybatis的人基本都不用手写出来每一行SQL吧?用mybatis的代码生成器自动生成crud就可以了。

2.分页确实是个问题,稍微成型点的公司都有能力开发mybatis的代码生成器插件吧?实在不会开发的去看我写的插件,我博客里面有。所以分页不是问题,而且分页的性能绝对足够高,分页SQL怎么工作自己能控制。

3.n+1查询问题,这个通过配置关联关系就可以了,完全可以避免,不算事。

4.性能问题,淘宝用的ibatis,还用说别的么?在sql映射文件中合理的配置cache后速度绝对一流。

5.还是回到插件问题上头来,可以写代码生成器的插件生成action,service,xml,前台crud的模板代码,crud类项目开发速度绝对一流。

用hibernate的同志,将你的项目复制三份以上改名部署在同一个tomcat里面,不改jvm参数你去启动tomcat试试?不报内存不够用都对不起你!mybatis的绝对没问题,不服就部署10份对比一下?

是的,crud全部自动生成,代码生成器具有不错的扩展。主要是SQL可控,上手快,效率也还可以。
0 请登录后投票
   发表时间:2011-12-22  
peihexian 写道
虽然很忙,还是忍不住登录上来吐槽几句。

1.用mybatis的人基本都不用手写出来每一行SQL吧?用mybatis的代码生成器自动生成crud就可以了。

2.分页确实是个问题,稍微成型点的公司都有能力开发mybatis的代码生成器插件吧?实在不会开发的去看我写的插件,我博客里面有。所以分页不是问题,而且分页的性能绝对足够高,分页SQL怎么工作自己能控制。

3.n+1查询问题,这个通过配置关联关系就可以了,完全可以避免,不算事。

4.性能问题,淘宝用的ibatis,还用说别的么?在sql映射文件中合理的配置cache后速度绝对一流。

5.还是回到插件问题上头来,可以写代码生成器的插件生成action,service,xml,前台crud的模板代码,crud类项目开发速度绝对一流。

用hibernate的同志,将你的项目复制三份以上改名部署在同一个tomcat里面,不改jvm参数你去启动tomcat试试?不报内存不够用都对不起你!mybatis的绝对没问题,不服就部署10份对比一下?

是的,crud全部自动生成,代码生成器具有不错的扩展。主要是SQL可控,上手快,效率也还可以。
0 请登录后投票
   发表时间:2011-12-22  
  <!-- 多表 join 查询  sql 例子 -->
  <bean id="sqlRegistry" class="com.xyz.sql.SqlRegistry">
		<!-- 多表 join 查询  sql 例子 -->
		<property name="sqlForSearchCity">
			<value><![CDATA[
			SELECT c.id as id, c.name as name, c.other_name as other_name, c.people_num as people_num,
				c.sheng_id as sheng_id, c.insert_time as insert_time, c.last_update_time as last_update_time,
				s.name as shengName, s.other_name as shengOtherName, s.city_num as shengCityNum
			FROM city c
			left outer join sheng s on c.sheng_id = s.id
			WHERE 1=1
			
			## Dynamic Content
			#if ($param_shengId)
			AND c.sheng_id = :param_shengId
			#end
			
			ORDER BY c.id DESC
			]]></value>
		</property>
		
  </bean>


一对多映射怎么解决呢
WHERE 1=1 自己实现的模板动态sql方面有点弱啊,你可以看写mybatis的文档,动态sql外加ognl 效果不是那么好实现的

0 请登录后投票
   发表时间:2011-12-23  
一对多映射怎么解决效率问题呢?
<resultMap type="Product" id="product">
        <id property="id" column="ID" javaType="java.lang.Integer" jdbcType="INTEGER"/>
        <result property="productId" column="PRODUCT_ID" javaType="java.lang.String" jdbcType="VARCHAR"/>
        <result property="title" column="TITLE" javaType="java.lang.String" jdbcType="VARCHAR"/>
        <result property="brand" column="BRAND" javaType="java.lang.String" jdbcType="VARCHAR"/>
        <collection property="images" ofType="java.util.List" select="getImageById" column="ID"/>
        <collection property="attributes" ofType="java.util.List" select="getAttrById" column="ID"/>
        <collection property="categories" ofType="java.util.List" select="getCatByProductId" column="ID"/>
        <collection property="proDetails" ofType="java.util.List" select="getProDetailByProductId" column="ID"/>
    </resultMap>

    <select id="getImageById" parameterType="java.lang.Integer" resultMap="image">
        <![CDATA[
            select t.*
            from images t where t.PRODUCT_ID = #{id}
        ]]>
    </select>

    <select id="getAttrById" parameterType="java.lang.Integer" resultMap="attribute">
         <![CDATA[
             select t.*
             from attribute t where t.PRODUCT_ID = #{id}
         ]]>
    </select>
......

查询所有商品时效率低的一塌糊涂,如何优化?
0 请登录后投票
   发表时间:2011-12-23  
yanwt 写道
一对多映射怎么解决效率问题呢?
<resultMap type="Product" id="product">
        <id property="id" column="ID" javaType="java.lang.Integer" jdbcType="INTEGER"/>
        <result property="productId" column="PRODUCT_ID" javaType="java.lang.String" jdbcType="VARCHAR"/>
        <result property="title" column="TITLE" javaType="java.lang.String" jdbcType="VARCHAR"/>
        <result property="brand" column="BRAND" javaType="java.lang.String" jdbcType="VARCHAR"/>
        <collection property="images" ofType="java.util.List" select="getImageById" column="ID"/>
        <collection property="attributes" ofType="java.util.List" select="getAttrById" column="ID"/>
        <collection property="categories" ofType="java.util.List" select="getCatByProductId" column="ID"/>
        <collection property="proDetails" ofType="java.util.List" select="getProDetailByProductId" column="ID"/>
    </resultMap>

    <select id="getImageById" parameterType="java.lang.Integer" resultMap="image">
        <![CDATA[
            select t.*
            from images t where t.PRODUCT_ID = #{id}
        ]]>
    </select>

    <select id="getAttrById" parameterType="java.lang.Integer" resultMap="attribute">
         <![CDATA[
             select t.*
             from attribute t where t.PRODUCT_ID = #{id}
         ]]>
    </select>
......

查询所有商品时效率低的一塌糊涂,如何优化?



常规处理:延迟加载+缓存+页面静态化
有点含量的处理,自己搭建基于数据库的冗余数据搜索引擎 简单的apache solr 复杂的自己基于lucene实现
0 请登录后投票
   发表时间:2011-12-23  
悲剧了 写道
  <!-- 多表 join 查询  sql 例子 -->
  <bean id="sqlRegistry" class="com.xyz.sql.SqlRegistry">
		<!-- 多表 join 查询  sql 例子 -->
		<property name="sqlForSearchCity">
			<value><![CDATA[
			SELECT c.id as id, c.name as name, c.other_name as other_name, c.people_num as people_num,
				c.sheng_id as sheng_id, c.insert_time as insert_time, c.last_update_time as last_update_time,
				s.name as shengName, s.other_name as shengOtherName, s.city_num as shengCityNum
			FROM city c
			left outer join sheng s on c.sheng_id = s.id
			WHERE 1=1
			
			## Dynamic Content
			#if ($param_shengId)
			AND c.sheng_id = :param_shengId
			#end
			
			ORDER BY c.id DESC
			]]></value>
		</property>
		
  </bean>


一对多映射怎么解决呢
WHERE 1=1 自己实现的模板动态sql方面有点弱啊,你可以看写mybatis的文档,动态sql外加ognl 效果不是那么好实现的


为什么要用where 1 = 1 呢?

<where >
        <if test="lid != null" >
        and LID = #{lid,jdbcType=DECIMAL}
      </if>
      <if test="userId != null" >
        and USER_ID = #{userId,jdbcType=VARCHAR}
      </if>
      <if test="accountName != null" >
        and ACCOUNT_NAME = #{accountName,jdbcType=VARCHAR}
      </if>
      <if test="creationTime != null" >
        and CREATION_TIME = #{creationTime,jdbcType=TIMESTAMP}
      </if>
      <if test="intranetIp != null" >
        and INTRANET_IP = #{intranetIp,jdbcType=VARCHAR}
      </if>
      <if test="externalNetIp != null" >
        and EXTERNAL_NET_IP = #{externalNetIp,jdbcType=VARCHAR}
      </if>
      <if test="accessUrl != null" >
        and ACCESS_URL = #{accessUrl,jdbcType=VARCHAR}
      </if>
      <if test="operationType != null" >
        and OPERATION_TYPE = #{operationType,jdbcType=VARCHAR}
      </if>
      <if test="operationResult != null" >
        and OPERATION_RESULT = #{operationResult,jdbcType=VARCHAR}
      </if>
      <if test="remarksInfo != null" >
        and REMARKS_INFO = #{remarksInfo,jdbcType=VARCHAR}
      </if>
    </where>

这里面随你折腾,不会出现你担心的多一个and,少一个or的情况,这些情景MyBatis早就想到了。

你可以看看MyBatis的官方文档,动态sql部分写得非常详细。
0 请登录后投票
论坛首页 Java企业应用版

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