码迷,mamicode.com
首页 > 其他好文 > 详细

mybatis 使用经验小结

时间:2015-01-29 23:52:20      阅读:287      评论:0      收藏:0      [点我收藏+]

标签:

一、多数据源问题

主要思路是把dataSource、sqlSesstionFactory、MapperScannerConfigurer在配置中区分开,各Mapper对应的包名、类名区分开

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 4        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
 5        xmlns:context="http://www.springframework.org/schema/context"
 6        xsi:schemaLocation="
 7      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
 8      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 9      http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
10      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
11      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
12        default-autowire="byName">
13 
14     <bean id="dataSource1" class="org.h2.jdbcx.JdbcConnectionPool"
15           destroy-method="dispose">
16         <constructor-arg>
17             <bean class="org.h2.jdbcx.JdbcDataSource">
18                 <property name="URL" value="jdbc:h2:r:/h2db/awbprint/a"/>
19                 <property name="user" value="sa"/>
20                 <property name="password" value="sa"/>
21             </bean>
22         </constructor-arg>
23     </bean>
24 
25 
26     <bean id="dataSource2" class="org.h2.jdbcx.JdbcConnectionPool"
27           destroy-method="dispose">
28         <constructor-arg>
29             <bean class="org.h2.jdbcx.JdbcDataSource">
30                 <property name="URL" value="jdbc:h2:r:/h2db/awbprint/b"/>
31                 <property name="user" value="sa"/>
32                 <property name="password" value="sa"/>
33             </bean>
34         </constructor-arg>
35     </bean>
36 
37     <bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean">
38         <property name="dataSource" ref="dataSource1"/>
39         <property name="configLocation" value="classpath:mybatis-config.xml"></property>
40         <property name="typeAliasesPackage" value="awbprint.mybatis.entity"></property>
41         <property name="mapperLocations" value="classpath:mybatis/a/**/*.xml"></property>
42     </bean>
43 
44     <bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean">
45         <property name="dataSource" ref="dataSource2"/>
46         <property name="configLocation" value="classpath:mybatis-config.xml"></property>
47         <property name="typeAliasesPackage" value="awbprint.mybatis.entity"></property>
48         <property name="mapperLocations" value="classpath:mybatis/b/**/*.xml"></property>
49     </bean>
50 
51     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
52         <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory1"></property>
53         <property name="basePackage" value="awbprint.mybatis.mapper.a"/>
54     </bean>
55 
56     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
57         <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2"></property>
58         <property name="basePackage" value="awbprint.mybatis.mapper.b"/>
59     </bean>
60 
61 
62 </beans>

上面的配置,一个连h2的a数据库,一个连h2的b数据库,至于事务管理器,大家可参考这个思路,建二个,各管各的。

项目中mapper接口及映射文件均用包名区分开,如下图:

技术分享

 

二、如何使用Map做为参数及动态条件生成

 1     <resultMap id="BaseResultMap" type="awbprint.mybatis.entity.PrintLayout">
 2         <id column="D_RECID" property="recid" jdbcType="DECIMAL"/>
 3         <result column="D_USER_NAME" property="userName" jdbcType="VARCHAR"/>
 4         <result column="D_NAME" property="name" jdbcType="VARCHAR"/>
 5         <result column="D_TYPE" property="type" jdbcType="VARCHAR"/>
 6         ...
 7        
 8     </resultMap>
 9 
10    <sql id="Base_Column_List">
11         D_RECID, D_USER_NAME, D_NAME, D_TYPE, ...
12     </sql>
13 
14     <select id="select" resultMap="BaseResultMap"
15             parameterType="java.util.Map">
16         select
17         <include refid="Base_Column_List"/>
18         from T_PRINT_LAYOUT
19         where D_USER_NAME = #{userName,jdbcType=VARCHAR} and D_TYPE = #{awbType,jdbcType=VARCHAR}
20         <if test="recId != null">
21             and D_RECID = #{recId,jdbcType=DECIMAL}
22         </if>
23         <if test="ids != null">
24             or D_RECID in
25             <foreach item="item" index="index" collection="ids"
26                      open="(" separator="," close=")">
27                 #{item}
28             </foreach>
29         </if>
30 
31     </select>

14-31演示了如何使用Map做为参数,动态传入查询条件,及List参数生成in(...)条件

java端代码示例:

 1         PrintLayoutMapper mapper = context.getBean(PrintLayoutMapper.class);
 2         
 3         Map<String, Object> map = new HashMap<String, Object>();
 4         map.put("userName", "ADMIN");
 5         map.put("awbType", "CARGOLABEL_MU");
 6         map.put("recId", 1);
 7         
 8         List<Integer> ids = new ArrayList<Integer>();
 9         ids.add(0, 1);
10         ids.add(0, 2);
11         ids.add(0, 3);
12         
13         map.put("ids", ids);
14 
15         List<?> list = mapper.select(map);

其实PrintLayoutMapper接口的定义为:

1 public interface PrintLayoutMapper {    
2     ...
3     
4     List<PrintLayout> select(Map<String, Object> map);
5 }

最终生成的SQL语句为:

1 select D_RECID, D_USER_NAME, D_NAME, D_TYPE, ... from T_PRINT_LAYOUT where D_USER_NAME = ? and D_TYPE = ? and D_RECID = ? or D_RECID in ( ? , ? , ? )

 

三、兼容不同的数据库

 1 <insert id="insert">
 2  <selectKey keyProperty="id" resultType="int" order="BEFORE">
 3  <if test="_databaseId == oracle">
 4  select seq_users.nextval from dual
 5  </if>
 6  <if test="_databaseId == db2">
 7  select nextval for seq_users from sysibm.sysdummy1"
 8  </if>
 9  </selectKey>
10  insert into users values (#{id}, #{name})
11 </insert>

这是官方文档上的示例,演示了如何兼容oracle与db2这二种不同的数据库,来获取序列的下一个值

 

四、加强版的分支、选择判断

 1 <select id="findActiveBlogLike"
 2  resultType="Blog">
 3  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
 4  <choose>
 5  <when test="title != null">
 6  AND title like #{title}
 7  </when>
 8  <when test="author != null and author.name != null">
 9  AND author_name like #{author.name}
10  </when>
11  <otherwise>
12  AND featured = 1
13  </otherwise>
14  </choose>
15 </select>

这也是官方文档上的示例,因为<if>...</if>并没对应的<else>标签,所以要达到<if>...<else>...</else> </if>的效果,得借助<choose>、<when>、<otherwise>组合使用。

 

五、避免Where 空条件的尴尬

1 <select id="findActiveBlogLike" resultType="Blog">
2  SELECT * FROM BLOG
3  WHERE
4  <if test="state != null">
5  state = #{state}
6  </if> 
7 </select>

如果state参数为空时,最终生成SQL语句为 

1  SELECT * FROM BLOG
2  WHERE

执行会出错,当然,你可以在where 后加一个1=1,改成

1 <select id="findActiveBlogLike" resultType="Blog">
2  SELECT * FROM BLOG
3  WHERE 1=1
4  <if test="state != null">
5  and state = #{state}
6  </if> 
7 </select>

但是这个做法不太“环保”(毕竟引入了一个垃圾条件),其实只要改成<where>...</where>即可

1 <select id="findActiveBlogLike" resultType="Blog">
2  SELECT * FROM BLOG
3  <where>
4      <if test="state != null">
5          and state = #{state}
6      </if>
7  </where> 
8 </select>

 

六、$与#的区别

1  select * from T_PRINT_LAYOUT where  D_RECID = ${recId}

最后生成的SQL为:

1 select * from T_PRINT_LAYOUT where  D_RECID = 1

即:直接将参数值替换到了原来${recId}的位置,相当于硬拼SQL

 

1  select * from T_PRINT_LAYOUT where  D_RECID = #{recid,jdbcType=DECIMAL}

最后生成的SQL为:

1 select * from T_PRINT_LAYOUT where  D_RECID = ?

即:#{...}被识别为一个SQL参数

mybatis 使用经验小结

标签:

原文地址:http://www.cnblogs.com/yjmyzz/p/4261024.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!