mybaties日常开发总结详解编程语言

以下为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"));

执行结果截图:

mybaties日常开发总结详解编程语言

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/11209.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论