以下为mybaties在实际项目中运用总结,供参考

数据库:mysql 或者oracle,开发工具eclipse,开发技术mybaties+spring+springmvc


使用mysql数据库插入数据id自动增长写法

<insert id="addSign" useGeneratedKeys="true" keyProperty="id"  parameterType="com.suwei.sysMng.bean.YkatUserSign">
  insert into ykat_user_sign(user_id,user_name,user_type,create_time,serial_days,update_time,is_del)
  values(#{userId},#{userName},#{userType},#{createTime},#{serialDays},#{updateTime},1)
</insert>


使用like模糊查询,if条件判断

<select id="expertQuery"  parameterType="java.util.Map" resultType="java.util.Map">
	select e.id,e.expert_name AS expertName,e.phone,e.longitude,e.latitude,
	e.expert_address AS expertAddress,
	vm.id AS expertGoodAtId,
	GROUP_CONCAT(vm.models_name) AS expertGoodAt
	from ykat_expert AS e
	left join ykat_expert_models AS em on e.id = em.expert_id
	left join ykat_vehicle_models AS vm on em.vehicle_models_id = vm.id 
	where 1=1 and e.is_del=1
	<if test="expertName!=null  and  expertName!='' ">
		and  e.expert_name  like  '%${expertName}%'  
	</if>
	<if test="expertGoodAt!=null  and expertGoodAt!='' ">
		and vm.id=#{expertGoodAt}
	</if>
	group by e.id
	order by e.id desc
	limit #{page} , #{pageSize}
</select>


传递多个参数使用map形式

xml文件

<update id="storeStaffUpdate"  parameterType="java.util.Map">
    update ykat_store_satff
    set integral=#{integral}
    where user_id=#{userId}
</update>

dao层

int storeStaffUpdate(Map<String, Object> params);
service层

Map<String, Object> driverMap=new HashMap<String, Object>();
driverMap.put("integral", integral);
driverMap.put("userId", userId);
driverDao.updateDriverByUserId(driverMap);

总结:#{xxx}里面的值必须与map的可以值一致,否则报错


传递参数类型为List,Array,Map等写法,foreach使用

foreach介绍:

foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close。item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,在不同情况下,该属性的值是不一样的,主要有一下3种情况:
1.如果传入的是单参数且参数类型是一个List的时候,collection属性值为list

2.如果传入的是单参数且参数类型是一个Array数组的时候,collection的属性值为array

3.如果传入的参数是多个的时候,我们就需要把它们封装成一个Map,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key值名称

案例:

实体类:

public class Employees {
  private Integer employeeId;
  private String firstName;
  private String lastName;
  private String email;
  private String phoneNumber;
  private Date hireDate;
  private String jobId;
  private BigDecimal salary;
  private BigDecimal commissionPct;
  private Integer managerId;
  private Short departmentId;
}
xml文件:

1.传递参数类型为List,foreache中的collection属性类型必须是List,collection的值必须是list,item的值任意,但是必须与#{xxx}里面的值一致,index的值任意,Dao中参数名任意

<select id="getEmployeesListParams"resultType="Employees">
  select *
  from EMPLOYEES e
  where e.EMPLOYEE_ID  in
  <foreach collection="list" item="employeeId" index="index"
    open="(" close=")" separator=",">
    #{employeeId}
  </foreach>
</select>

2.传递参数类型为Array,foreach中的collection属性类型必须是Array,collection的值必须是array,item的值任意,但是必须与#{xxx}里面的值一致,index的值任意,Dao中参数名任意

<select id="getEmployeesArrayParams" resultType="Employees">
  select *
  from EMPLOYEES e
  where e.EMPLOYEE_ID in
  <foreach collection="array" item="employeeId" index="index"
    open="(" close=")" separator=",">
    #{employeeId}
  </foreach>
</select>
3.传递的参数类型为Map,foreach中的collection属性值必须是map的key值,其他属性值必须都是map的key值,比如下面的salary,Dao中参数名任意

<select id="getEmployeesMapParams"  resultType="Employees">
  select *
  from EMPLOYEES e
  <where>
    <if test="employeeIdsArray!=null and employeeIdsArray.length!=0">
       e.EMPLOYEE_ID in
      <foreach collection="employeeIdsArray" item="employeeId"
        index="index" open="(" close=")" separator=",">
        #{employeeId}
      </foreach>
    </if>  
    <if test="salary!=null">
        order by ${salary} desc
    </if>
    <if test="page!= null and page!="" and pageSize!= null and pageSize!= '' ">            
       limit ${page},${pageSize}        
    <if>
  </where>
</select>

Mapper类:

public interface EmployeesMapper { 
  List<Employees> getEmployeesListParams(List<String> employeeIds);
  List<Employees> getEmployeesArrayParams(String[] employeeIds);
  List<Employees> getEmployeesMapParams(Map<String,Object> params);
}

测试类:

@Test
public void testGetResultsMapParmas(){
    //参数是数组,则在xml文件中if判断时,taskIds.length != 0
//    int[] array = new int[5];
//    array[0] = 9;
//    array[1] = 12;

    //参数是列表,则在xml文件中if判断时,taskIds.size != 0
    List<Integer> taskIds = new ArrayList<>();
    taskIds.add(9);
    taskIds.add(12);

    Map<String, Object> params = new HashMap<>();
    BigDecimal salary=122521541;
    params.put("employeeIdsArray",array);
    params.put("salary", salary);
    //设置分页page可以为0,pageSize不能为0
    params.put("page", 0);
    params.put("pageSize",1);

    List<TestResult> results = testResultDao.getResultsMapParmas(params);
    for(TestResult result : results){
        System.out.println("resultId:" + result.getResultId() + " ** startTime:" + result.getStartTime());
    }
}

总结:

1.如果Map中value为数组或者链表,那么在foreach标签中的collection值必须与它的key值一样,否则会报错。当value为数组时,在if标签中判断时为taskIds.length != 0,当value为链表时,则在if标签中判断时为taskIds.size != 0。

2.使用mybatis-generator自动生成dao,则可以对某张表配置enableSelectByExample=”true”,然后使用Example来传入List参数,并添加其他条件。

3.对传递的参数一定要进行非空判断,在前台获得的参数进行非空判断,或者在xml文件中进行非空判断。

4.以上案例均用到了批量查询操作,可以参考


在日常开发中日期数据库设计为datetime类型,实体类型为Date类型,而在页面显示往往是string类型,显示格式为“yyyy-MM-dd”或者“yyyy-MM-dd”,则在进行数据库查询时我们需要将数据库查询的Date日期转换为字符串类型,以下为mysql和oracle中日期转换格式写法:

mysql数据库,Date日期类型,在xml文件中格式化写法:(常用)

<sql id="Base_Column_List2">
    id,user_id,user_name,user_type,trade_points,trade_type,points_reward,points_avail,
    date_format(create_time_time,'%Y-%m-%d %H:%i:%S') AS createTime,
    date_format(update_time_time,'%Y-%m-%d %H:%i:%S') AS updateTime
</sql>

oracle数据库,Date日期类型,在xml文件中格式化写法(常用)

<sql id="Base_Column_List" >
    JQID, JJDID, GLJJDBH, BJFS, JJDW, JJYBH, JJYXM, BJSJ,to_char(BJSJ,'yyyy-MM-dd HH24:mi:ss') bjsj_str, JJSC, BJDH, BJRXM, BJRXB, LXDH, 
    ZZDW, AFDD, SYXX, ZBXX, BJNR, GXDW, JWQ, BKRS, SSRS, SWRS, JQZT, GXZT, BYZD1, BY2, 
  </sql>
备注:转换成字符串则要在实体类中定义string类型的日期

oracle数据库,2个日期比较,如开始时间,结束时间

<select id="findjqztEvents5" parameterType="java.util.Map" resultType="com.doron.tcs.model.TItmpTcsEvents">
      select jqid, to_char(BJSJ,'HH24:mi') bjsj_str, bjnr, x, y,to_char(bjsj,'yyyy-MM-dd HH24:mi') bjsj_ystr
      from t_itmp_tcs_events 
      where jqzt = 5 and isvalid=1
      <if test="bjnr!=null and bjnr!=''">
	  and bjnr like '%${bjnr}%'
      </if>
      <if test="bjjb!=null and bjjb!=''">
	  and bjjb = #{bjjb}
      </if>
      <if test="kssj!=null and kssj!=''">
         and to_date(to_char(bjsj,'yyyy-MM-dd'),'yyyy-MM-dd') >= to_date(#{kssj},'yyyy-MM-dd')
      </if>
      <if test="jssj!=null and jssj!=''">
           <![CDATA[and to_date(to_char(bjsj,'yyyy-MM-dd'),'yyyy-MM-dd') <= to_date(#{jssj},'yyyy-MM-dd')]]>
      </if> 
	order by BJSJ desc
  </select>
、
备注:
mybaties报元素内容必须由格式正确的字符数据或标记组成
原因:mybatis查询的时候,需要用到运算符 小于号:< 和 大于号: >,在mybatis配置文件里面,这种会被认为是标签,所以解析错误
故解决方法为:
1.<![CDATA[and to_date(to_char(bjsj,'yyyy-MM-dd'),'yyyy-MM-dd') <= to_date(#{jssj},'yyyy-MM-dd')]]>
或者 : 将 < 号换成 &lt; > 号 换成&gt; 等于号用eq;


批量更新:
<update id="updateEventByAllJqid"  parameterType="java.util.Map" >
    update   T_ITMP_TCS_EVENTS  
    set   ISVALID = #{isvalid}  
    where  JQID  in
    <foreach collection="jqid"  item="idItem"  open="("  separator=","  close=")"  >
       #{idItem}
    </foreach>
  </update>
备注:foreache循环的参数一定要进行非空判断,这里没有进行判断,那么必须在传入参数地方进行判断非空操作,否则报错。


xml文件中解析转换特殊字符如大于号,小于号等写法:![CDATA[]]

<select id="findjqztEvents5" parameterType="java.util.Map" resultType="com.doron.tcs.model.TItmpTcsEvents">
      select jqid, to_char(BJSJ,'HH24:mi') bjsj_str, bjnr, x, y, to_char(bjsj,'yyyy-MM-dd HH24:mi') bjsj_ystr
      from t_itmp_tcs_events 
      where  jqzt = 5 and isvalid=1
      <if test="bjnr!=null and bjnr!=''">
	   and bjnr like '%${bjnr}%'
      </if>
      <if test="bjjb!=null and bjjb!=''">
	   and bjjb = #{bjjb}
      </if>
      <if test="kssj!=null and kssj!=''">
	  and to_date(to_char(bjsj,'yyyy-MM-dd'),'yyyy-MM-dd') >= to_date(#{kssj},'yyyy-MM-dd')
      </if>
      <if test="jssj!=null and jssj!=''">
	  <![CDATA[and to_date(to_char(bjsj,'yyyy-MM-dd'),'yyyy-MM-dd') <= to_date(#{jssj},'yyyy-MM-dd')]]>
      </if>
	 order by BJSJ desc
  </select>

插入数据,判断字段是否为空

<insert id="insertSelective" parameterType="com.doron.tcs.model.TItmpTcsEvents" >
    insert into T_ITMP_TCS_EVENTS
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="jqid != null" >
        JQID,
      </if>
      <if test="jjdid != null" >
        JJDID,
      </if>
      <if test="gljjdbh != null" >
        GLJJDBH,
      </if>
      <if test="bjfs != null" >
        BJFS,
      </if>
      <if test="jjdw != null" >
        JJDW,
      </if>
      <if test="jjybh != null" >
        JJYBH
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="jqid != null" >
        #{jqid,jdbcType=VARCHAR},
      </if>
      <if test="jjdid != null" >
        #{jjdid,jdbcType=VARCHAR},
      </if>
      <if test="gljjdbh != null" >
        #{gljjdbh,jdbcType=VARCHAR},
      </if>
      <if test="bjfs != null" >
        #{bjfs,jdbcType=DECIMAL},
      </if>
      <if test="jjdw != null" >
        #{jjdw,jdbcType=DECIMAL},
      </if>
      <if test="jjybh != null" >
        #{jjybh,jdbcType=VARCHAR}
      </if>
    </trim>
  </insert>


mybaties中多表关联查询,2个实体合并成一个实体则xml文件这样写:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.doron.tsms.dao.TItmpTsmsDutylineMapper" >
  <resultMap id="BaseResultMap" type="com.doron.tsms.model.TItmpTsmsDutyline" >
    <id column="ID" property="id" jdbcType="VARCHAR" />
    <result column="XLMC" property="xlmc" jdbcType="VARCHAR" />
    <result column="CFD" property="cfd" jdbcType="VARCHAR" />
    <result column="MDD" property="mdd" jdbcType="VARCHAR" />
    <result column="JGLK" property="jglk" jdbcType="VARCHAR" />
    <result column="LXCD" property="lxcd" jdbcType="DECIMAL" />
    <result column="PJSS" property="pjss" jdbcType="DECIMAL" />
    <result column="DWBH" property="dwbh" jdbcType="VARCHAR" />
    <result column="SJ" property="sj" jdbcType="TIMESTAMP" />
    <result column="YJSJ" property="yjsj" jdbcType="VARCHAR" />
  </resultMap>
  <resultMap id="ResultMapWithBLOBs" type="com.doron.tsms.model.TItmpTsmsDutyline" extends="BaseResultMap" >
    <result column="DLZB" property="dlzb" jdbcType="BLOB" />
  </resultMap>
  <sql id="Base_Column_List" >
    ID, XLMC, CFD, MDD, JGLK, LXCD, LXCD as lxcd_str,PJSS, PJSS as pjss_str, DWBH, SJ,to_char(SJ,'yyyy-MM-dd hh24:mi') as sj_str, YJSJ
  </sql>
  <sql id="Blob_Column_List" >
    DLZB
  </sql>
  <select id="selectAllList" resultMap="BaseResultMap">
     select
     <include refid="Base_Column_List" />,<include refid="Blob_Column_List" />,(select count(1) from T_ITMP_TSMS_DUTYTASK t where t.lxbh=p.id) sycs 
     from T_ITMP_TSMS_DUTYLINE p
     <where> 
	 1=1
	 <if test="cfd != null">
		and
		(CFD like '%'||#{cfd}||'%' 	 
		OR
		MDD like '%'||#{cfd}||'%' 	 
		 OR
		 XLMC like '%'||#{cfd}||'%') 	
	 </if>
	 <if test="dwbh!=null">
	  	and DWBH =#{dwbh}
	 </if>
	 </where>
	 order by sj desc
  </select>
  <!--查询关联2个字段-->
  <select id="selectByPrimaryKey" resultMap="ResultMapWithBLOBs" parameterType="java.lang.String" >
    select 
    <include refid="Base_Column_List" />,<include refid="Blob_Column_List" />
    from T_ITMP_TSMS_DUTYLINE
    where ID = #{id,jdbcType=VARCHAR}
  </select>
  
   <!-- 判断任务名称是否重复,如果存在返回数量 -->
   <select id="selectRwmcByLxmc"  parameterType="Map"  resultType="int">
    select count(xlmc)
    from T_ITMP_TSMS_DUTYLINE
    where XLMC = #{xlmc,jdbcType=VARCHAR} 
   <if test="''!=id and id != null" >
       and  ID != #{id,jdbcType=VARCHAR}
   </if>
  </select>
</mapper>

批量插入:

方法一:

oracle数据库

<insert id="insertBatch" parameterType="java.util.List" >
    insert into T_ITMP_TSMS_EXECUTECALL (ID, RWBH, JYBH, ZT, SJ, GWBH)
    <foreach collection="list" item="item" index="index" separator="union all" >
     (select #{item.id,jdbcType=VARCHAR}, #{item.rwbh,jdbcType=VARCHAR}, #{item.jybh,jdbcType=VARCHAR}, 
      #{item.zt,jdbcType=VARCHAR}, #{item.sj,jdbcType=VARCHAR}, #{item.gwbh,jdbcType=VARCHAR} from dual)
    </foreach>
</insert>

备注:这里一定要用select标签不能insert或者update


mysql数据库

<insert id="insertBatch" useGeneratedKeys="true" parameterType="java.util.List">  
    <selectKey resultType="long" keyProperty="id" order="AFTER">  
        SELECT  LAST_INSERT_ID()  
    </selectKey>  
    insert into t_train_record (add_time,emp_id,activity_id,flag)   
    values  
    <foreach collection="list" item="item" index="index" separator="," >  
        (#{item.addTime},#{item.empId},#{item.activityId},#{item.flag})  
    </foreach>  
</insert>

或者:

<insert id="batchSave" parameterType="java.util.List">
     INSERT INTO TABLE_NAME(ID,NAME) VALUES
     <foreach collection="list"  item="itm" separator=",">
        (#{itm.id},#{itm.name})
    </foreach>
</insert>

方法二:

<insert id="insertbatch" parameterType="java.util.List">
  <selectKey keyProperty="id" order="BEFORE"  resultType="long">
     SELECT CURRENT_TIMESTAMP()
  </selectKey>
  insert into T_ITMP_TSMS_EXECUTECALL(ID, RWBH, JYBH, ZT, SJ, GWBH) values
  <foreach collection="list" item="item" index="index" separator=",">
  (#{item.id,jdbcType=VARCHAR}, #{item.rwbh,jdbcType=VARCHAR}, #{item.jybh,jdbcType=VARCHAR},#{item.zt,jdbcType=VARCHAR}, #{item.sj,jdbcType=VARCHAR},
  #{item.gwbh,jdbcType=VARCHAR)
</foreach>
</insert>

 

总结:

其属性如下:

parameterType,入参的全限定类名或类型别名

keyColumn,设置数据表自动生成的主键名。对特定数据库(如PostgreSQL),若自动生成的主键不是第一个字段则必须设置

keyProperty,默认值unset,用于设置getGeneratedKeys方法或selectKey子元素返回值将赋值到领域模型的哪个属性中

useGeneratedKeys,取值范围true|false(默认值),设置是否使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。MySQL和SQLServer执行auto-generated key field,因此当数据库设置好自增长主键后,可通过JDBC的getGeneratedKeys方法获取。但像Oralce等不支持auto-generated key field的数据库就不能用这种方法获取主键了

statementType,取值范围STATEMENT,PREPARED(默认值),CALLABLE

flushCache,取值范围true(默认值)|false,设置执行该操作后是否会清空二级缓存和本地缓存

timeout,默认为unset(依赖jdbc驱动器的设置),设置执行该操作的最大时限,超时将抛异常

databaseId,取值范围oracle|mysql等,表示数据库厂家,元素内部可通过`<if test="_databaseId = 'oracle'">`来为特定数据库指定不同的sql语句

order属性,取值范围BEFORE|AFTER,指定是在insert语句前还是后执行selectKey操作

注意:selectKey操作会将操作查询结果赋值到insert元素的parameterType的入参实例下对应的属性中。并提供给insert语句使用

批量删除:

<delete id="deleteBatch" parameterType="java.util.List">
    DELETE FROM STUDENT WHERE id IN
    <foreach collection="list" index="index" item="item" open="(" separator="," close=")"> 
        #{item} 
    </foreach>
</delete>


mybaties查询返回数组:resultType="string"表示返回string数组

xml文件:

<!-- 根据门店id查询所有用户id -->
	<select id="queryByOrderId"   parameterType="java.lang.Long"  resultType="string">
		select user_id
		from ykat_store_satff
		where store_id=#{storeId} and is_del=1
	</select>
则dao层:

/**
* @descript: 根据门店id查询所有用户id 
* @param storeId 门店id
* @return
*/
String []  queryByOrderId(@Param("storeId")Long storeId);
server层:

//根据门店id查询所有用户id
String []userId=storeDao.queryByOrderId((long) mapTemp.get("storeId"));
执行结果截图:






更多相关文章

  1. MYSQL5.5和5.6参数的差异
  2. 如何使用基于条件的PHP来改变CSS属性?
  3. 存储过程,参数数量不正确bug?
  4. MySQL数据库 prompt参数详解
  5. MyBatis排序时使用order by 动态参数时需要注意,用$而不是# 用$传
  6. 如果发现自己的mysql没有充分利用CPU该关注那些参数?
  7. 解析innodb status各项参数
  8. 关于如何更好的监听元素属性的变化(转)
  9. JavaScript 中 Object ,Prototype 相关的属性和方法

随机推荐

  1. OpenWrt上运行Android OS
  2. ScrollView嵌套webview因焦点问题导致自
  3. Android 开发判断用户是否安装微信和QQ并
  4. Android EditText 自动获取焦点,并弹出键
  5. 判断客户端类型
  6. Android一日笔记
  7. Android:控件的对象修改控件的值
  8. Android中JNI实现
  9. 判断android devices是否联网
  10. Android TextView背景跟随焦点的变化