mybatis 使用经验小结

一、多数据源问题

主要思路是把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参数

时间: 2024-07-31 14:31:26

mybatis 使用经验小结的相关文章

mybatis入门小结(六)

入门小结---查询 1.1.1.1.1 #{}和${} #{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入. #{}可以接收简单类型值或pojo属性值. 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称. ${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型

自己开发过程中mybatis使用经验以及和hibernate的对比

mybatis和hibernate 第一步, 首先让我们对mybatis和hibernate对比了解下 相同点: 1. Hibernate :Hibernate 是当前非常流行的ORM框架,对数据库结构提供了较为完整的封装,都是为了简化Dao层的操作. Mybatis:Mybatis同样也是非常流行的ORM框架,主要着力点在于POJO 与SQL之间的映射关系,都是为了简化Dao层的操作. 2.Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生

mybatis学习小结

MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录. jdbc源码: <span style="font-size:18px;">public static voidmain(String[]

Mybatis框架--小结

在学习MyBatis框架的过程中,有一些相对比较底层的问题不是特别理解,在这里总结一下: 什么是MyBatis的接口绑定,有什么好处? 1. 什么是MyBatis的接口绑定,有什么好处? 参考链接:http://blog.csdn.net/chris_mao/article/details/48836039 接口映射就是在IBatis中任意定义接口,然后把接口里边的方法和SQL语句绑定,我们可以直接调用接口方法,比起SqlSession提供的方法我们可以有更加灵活的选择和设置 iBatis: i

Mybatis项目小结

一,什么是mybatis MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架. 二,mybatis的作用 MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索. MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan Old Java Objects,普通的Java对象)映射成数据库中的记录. 帮助减轻数据访问层的操作 三,怎么创建mybatis简单工程 1.使用J2EE创建一个简单的工程 2.配置pom.xml文

Struts2 interceptor使用经验小结

1. interceptor 调用Spring容器中的bean 在interceptor中常有需要调用Spring Bean的需要,其实很简单和Struts2的Action一样配置即可. Spring中的配置 <!--spring配置 -->1 <bean id="authorityInterceptor" class="com.xxx.interceptor.AuthorityInterceptor"/> 2 3 <bean id=&

ORM框架-MyBatis使用经验总结

使用Spring-Mybatis工具包,使用基于接口的映射器: 复杂的数据结构使用XML配置映射语句:简单的SQL语句建议直接使用Java注解来编写映射语句: 使用@Param对接口参数添加注解,将面向SQL的参数名和面向应用程序的参数名解耦: 禁用或者慎用Map类型的接口参数,当参数数量超过一定数量(如:5)时,建议使用Java类封装参数: 建议使用ResultMap映射结果集:禁止直接使用Map返回查询结果,使用Map返回查询结果不利于不同层级的代码之间的解耦,并且严重降低了修改程序的灵活性

Kafka使用经验小结

本文尽量从一个使用者的角度去记录一些在实战当中使用Kfaka所需要关注的要点,这样可能会贴切更多的读者,本文并不会介绍太多的Kafka的一些架构层次设计的知识,因为网上已经有一大堆的重复搬运的资料任由你们学习参考. 明确Kafka在你的系统中的定位 众所周知,Kafka的可用性和数据可靠性相对其他的高可用的MQ来说会低一点,但是带来的却是更大更高性能的消息吞吐量的优势,因此要是你的系统需要的是金融级别的高可靠高可用就尽量选择其他的MQ产品. Kafka比较适合那种容忍即使丢失一定量数据也不会带来

Mybatis学习小记

Mybatis学习小结 最近在学习Java的一些框架,Spring,Mybatis这些,总有点浮于表面的感觉,这里先记录一下使用的小知识. 1.初级尝试 这部分记录一下我第一次用Mybatis以及Spring做的小代码,比较简单,主要涉及环境的配置以及简单的使用,后续部分会有其他更深入的使用总结. 1.1 准备工作 这里准备一些基本的jar包,我是用maven管理的.用到的jar包如下.这里要特别注意mybatis-spring的版本和mybatis的版本需要匹配,否则会出现很多其他问题了.这里