以下为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 expertGoodAtfrom ykat_expert AS eleft join ykat_expert_models AS em on e.id = em.expert_idleft 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.idorder by e.id desclimit #{page} , #{pageSize}
</select>

传递多个参数使用map形式

xml文件

<update id="storeStaffUpdate"  parameterType="java.util.Map">update ykat_store_satffset 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 ewhere 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 ewhere 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 != 0List<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不能为0params.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_ystrfrom 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_ystrfrom 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}||'%'   ORMDD like '%'||#{cfd}||'%'     ORXLMC 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_DUTYLINEwhere ID = #{id,jdbcType=VARCHAR}</select><!-- 判断任务名称是否重复,如果存在返回数量 --><select id="selectRwmcByLxmc"  parameterType="Map"  resultType="int">select count(xlmc)from T_ITMP_TSMS_DUTYLINEwhere 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_idfrom ykat_store_satffwhere 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日常开发总结相关推荐

  1. 日常安排php,PHP日常开发小技巧

    PHP日常开发小技巧 导语:PHP语言中,如果你懂得一些开发技巧,那么对你学PHP,会有很大的帮助.下面的是百分网小编为大家整理的PHP日常开发小技巧,希望对你能有所帮助. PHP批量取得checkb ...

  2. Java日常开发的21个坑,你踩过几个?

    前言 最近看了极客时间的<Java业务开发常见错误100例>,再结合平时踩的一些代码坑,写写总结,希望对大家有帮助,感谢阅读~ 1. 六类典型空指针问题 包装类型的空指针问题 级联调用的空 ...

  3. 【C#/.NET 日常开发技巧】JWT+ActionFilter 简便控制器代码

    微信公众号:趣编程ACE 关注可了解更多.NET日常开发技巧,如需源码,请公众号留言 源码; JWT+ActionFilter 简便控制器代码 这是微软关于过滤器的介绍:https://docs.mi ...

  4. 代码智能技术如何应用到日常开发?

    简介: 原理与演示. 01/  从开发者的烦恼说起 开发者在编写代码时,需要花费大量时间在低层次的重复编码上,特别是针对一些语法比较冗余的开发语言. 同时,开发者经常被戏称为面向搜索引擎编程,因为我们 ...

  5. 如何使用Arthas提高日常开发效率?

    简介: 1. Arthas有什么功能,怎么用,请看:Arthas使用手册 2. Arthas命令比较复杂,一个帮助生成命令的IDEA插件:arthas idea plugin 使用文档 3. 基于Ar ...

  6. Android日常开发问题总结:这些问题火候不够,随时变成删库跑路!

    日常开发中碰到了各种开发问题,捡选了一部分分享出来.有些问题非常简单,属于编码规范类,有些属于特定情况下碰到的问题,不是很常见.不太准确的地方,欢迎共同探讨下~ 1.requestFeature() ...

  7. NC65在日常开发中常用的代码写法

    标题 NC65开发相关代码 版本 1.0.1 作者 walton 说明 收集NC在日常开发中常用的代码写法,示例展示 1.查询 1.1 通过BaseDAO查询结果集并转换 //通过BaseDAO进行查 ...

  8. 推荐10个实用的日常开发和写作必备工具

    前言 分享几个我日常开发或写作过程中经常用到的工具软件和网站,看看哪些是你没用过的,喜欢的话可以点赞和收藏哦-. 1. 截图工具(snipaste) 官网地址 snipaste是一款截图+贴图工具,按 ...

  9. 【Unity3D日常开发】Unity3D中实现计时器工具类-正计时、倒计时、暂停计时、加速计时

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

最新文章

  1. cmake使用教程(十一)-使用cpack打包源码并编写自动化脚本上传到仓库
  2. “开源”将成为物联网开发生态链的标准
  3. ​Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数
  4. 学计算机平面设计可以找什么工作,大学生学了平面设计之后能找什么样的工作...
  5. CodeForces 1110H. Modest Substrings
  6. ios多线程Android,iOS 关于多线程
  7. uva 10245 The Closest Pair Problem_枚举
  8. Redis系列教程(九):Redis的内存回收原理,及内存过期淘汰策略详解
  9. 自定义处理网页选区字符并实时显示(js)
  10. SCCM 2012 R2---安装客户端代理软件
  11. 520表白网页代码html 爱心网页制作
  12. 科技赋能时代 用ocr身份证识别
  13. ubuntu18.04引导界面、登录界面美化
  14. 国产计算机系统哪个好,5大国产手机操作系统分析评测,你更中意谁?
  15. 印会河《中医基础理论》笔记——阴阳学说、五行学说
  16. 你真的理解devDependencies和dependencies区别吗?
  17. 不重装系统解决win10更新错误0x800f0922
  18. 【GANs学习笔记】(十九)CycleGAN、StarGAN
  19. 一次kubenetes的rook-ceph创建pv失败的故障排查
  20. 由于超过32位java限制_Java 32位Xmx vs java 64位Xmx

热门文章

  1. CF156B - Suspects
  2. 百度内部培训PPT:数据分析的道与术
  3. CDH部署Livy服务
  4. 阿里云《云中谁送锦书来》活动热烈来袭 阿里云超大鼠标垫,cherry键盘
  5. EChats图表的使用
  6. wireshark按照域名过滤
  7. scala中伴生对象和伴生类
  8. 全概率公式、贝叶斯公式推导过程
  9. C++ typeid() 用法
  10. easyswoole数据库连接池_easyswoole快速实现一个网站的api接口程序