mybatis学习知识点摘录

前言:

Mybatis的使用是基于XML配置,不同于hibernate直接写在java代码中,所以其解耦性很好,而且轻量级,可以灵活处理各种SQL语句,要说缺点,暂时我能想的就是要写很多东西,而且XML是很难发现有报错的,但是一般而言一个模块写好的公共的resultMap以及sql后,后面的就方便了很多。这篇文章不是基础,而是针对基础的一些需要注意的知识点的总结摘录,尤其要注意的是Mybatis针对不同数据库,比如mysql和oracle在很多配置以及具体SQL写法上是有很多不同的,举个栗子批量插入数据时几乎完全不同!但是我们搜索的mybatis教程可以说100个里面99个都是拿mysql做例子,而实际中oracle用的也比较多。所以针对以上我做了具体摘录。
第一大部分是基础知识总结,第二部分进阶请等待我的更新。欢迎留言指出不足和纰漏!

一、Mybatis基础知识点:

1.动态代理技术使得mapper.xml类似于daoImpl,mapper.java只是interface,无实现类
2.mybatis-config里面的标签,比如等,注意,是有先后顺序的,不可颠倒。
3.自增主键(mysql支持自增)
非自增(oracle)


3.mybatis mapper接口怎么 传递多个参数 @Param()注解
3.1当传递一个参数的时候,不做特殊处理 直接#{}
3.2当传递多个参数的时候,mybatis会封装

这个mapper.java接口里面的两个参数是没加注解的
所以使用的时候就得传入mybatis封装的这种param1 param2的方式



当使用注解了后 就明确了参数

使用注解后mybatis会将多个参数自动封装成map

这样mapper.xml可以如下




以上这种@Params注解适用于 参数不多的情况(几个)
多个参数的话(比如一个对象)
需要如下三种方式(第二种直接封装成map比较常见,第三种是自定义扩展类,第一种就是原始的POJO)

Map封装参数如下:

mapper.xml里面直接拿map的key取值




几种特殊的传递参数




4.$ #区别:
#{}预编译,可以防止SQL注入。
#{}用来传查询参数
${}直接拼接在SQL语句里面
排序order by ${} 表明:select * from ${tableName} where id=#{id} order by ${name}

5. #{}扩展,对oracle数据库无法识别mybtais对null的处理,所以当数据为null时候插入数据会报错,解决办法: #{parameter,jdbcType=OTHER}
mysql是没这个问题的,可以识别NULL
但是实际应用中我们都是判断如果为NULL就不插入,以上是原生的情况

在向oracle插入数据时,mybatis3报Error setting null parameter. Most JDBC drivers require that the JdbcType must be specified for all nullable parameters,是由于参数出现了null值,对于Mybatis,如果进行操作的时候,没有指定jdbcType类型的参数,mybatis默认jdbcType.OTHER导致,给参数加上jdbcType可解决(注意大小写) 


6.当Mapper.java接口里面方法返回值为List的时候,这时对应Mapper.xml文件的select语句的resultType(不是resultMap)还是写Object对象名称 mybatis会自动处理封装返回结果集的。

7.返回值类型为Map
单条对象:
方法:public Map< String,Object> getEmpById(Integer id)
mapper.xml: resultMap="map"(不用写全称)
多条对象:
方法:加注解 MapKey("id") 每条对象数据的id作为Map的key public Map< Integer,Object> getEmpById(Integer id)
因为id是Integer类型所以key是Integer,如果用name做key,那么就用String
mapper.xml:resultMap="com.wonder.Emp" (对象路径)

8.关联查询配合延迟加载,会提升效率;比如查询Emp里面1对1关联Dept,这个Dept的查询是单独的然后和Emp的查询组合关联到一起,这样当配置延迟加载后,我们查Emp的时候如果不用Dept里面的属性,那么就执行查询Emp的一条SQL,如果用到了Dept里面的属性,就执行Emp Dept两条SQL。
如果没有配置延迟加载,那么查Emp不管是否用到Dept的属性都会执行两条SQL。

9.分步查询传多个参数:(dept是主表, emp是从表(List))
fetchType设置成eager就没延迟加载效果了(就会两个SQL一起发,而延迟加载是用到了才发从表Emp的SQL)

10.根据字段的取值进行处理结果,比如在此gender=0是女生 返回特定结果 gender=1是男生 根据情况再返回特定结果


resutType或者ResultMap不可缺少,这里用的是resultType,我们可以自定义用resultMap返回制定规则下数据


11. if 标签 OGNL表达式
id=#{id} and
last_name like #{lastName} and
email=#{email} and
gender=#{gender}

12、查询条件多出的and 或者or 解决办法
1)where 1=1 或者
2) 推荐:标签 将所有的查询条件包括在内 这个where会处理
andemail=#{email}
这种and在参数前的情况,但是没法解决 and在后这种 拼接还是会多出and
3)如果是:
email=#{email} and
得用 标签解决(自定义截取,也不是首选)
后面多出的and或者or where标签不能解决
prefix="":前缀:trim标签体中是整个字符串拼串 后的结果。
prefix给拼串后的整个字符串加一个前缀
prefixOverrides="":
前缀覆盖: 去掉整个字符串前面多余的字符
suffix="":后缀
suffix给拼串后的整个字符串加一个后缀
suffixOverrides=""
后缀覆盖:去掉整个字符串后面多余的字符

13. 标签

如果id和lastName都有值得话 那么也只是进入一个分支,id在前,就只进入id分支

14. 标签:可以去除 多余的 , 逗号
update tbl_employee
last_name=#{lastName},
email=#{email},
gender=#{gender}
where id=#{id}
或者:
Trim:更新拼串
update tbl_employee
suffixOverrides=" , ">
last_name=#{lastName},
email=#{email},
gender=#{gender}
where id=#{id}

15. 标签,Mapper.java传的是一个ids的List

16. MySQL下批量 保存------ 标签批量保存数据,Mapper.java:public void addEmps(@Param("emps") List emps);
第一种(常用),一条SQL,循环插入的数据对象:
insert into tbl_employee(
)
values
",">
(#{emp.lastName},#{emp.email},#{emp.gender},#{ emp.dept.id})
第二种( 这种形式也可以可以批量删除,修改 ),发送多条SQL,循环执行多条SQL语句:

17 .Oracle数据库批量操作
注意:和mysql不同
CSDN:下面来看一个Oracle例子:
 首先,在DataMapper. Java  接口类中加入接口:
[java]   view plain   copy
  1. int batchInsert(List datas);  
  然后,在xxxMapper.xml 中编写对应的实现sql,我使用的是oracle,如果是mysql或sqlserver,可能sql语句会略有区别吧:
[xml]   view plain   copy
  1.  id="batchInsert"parameterType="java.util.List">   
  2.  insert into DATA (ID, TEXT, STAUTS)   
  3.   close=")"collection="list"item="item"index="index"open="("separator="union">   
  4. select  
  5. #{item.id,jdbcType=VARCHAR},  
  6. #{item.text,jdbcType=VARCHAR},  
  7. #{item.stauts,jdbcType=VARCHAR}  
  8.  from dual   
  9.   
  10.   

Oracle第一种批量插入方式(执行多个单条插入的SQL------多个insert放在begin - end里面):
"end;">
insert into employees(employee_id,last_name,email)
values(employees_seq.nextval,#{emp.lastName},#{emp.email});

Oracle第二种批量插入方式(利用中间表):
insert into employees(
)
open="select employees_seq.nextval,lastName,email from("
close=")">
select #{emp.lastName} lastName,#{emp.email} email from dual

批量更新:


    begin  
         
            update Emp
            
            
                id = #{item.id},
            

           
                NAME= #{item.name},
            

           
            where id = #{item.id}
            
        ;end;
    

批量删除:


  delete from Emp
  
       
  id=#{item.id}
   

  

 



18.mybatis的两个内置参数:不只是方法传递过来的参数可以被用来判断,取值。
mybatis默认还有两个内置参数:
_parameter:代表整个参数
单个参数:_parameter就是这个参数
多个参数:参数会被封装为一个map;_parameter就是代表这个map
_databaseId:如果配置了databaseIdProvider标签。
_databaseId就是代表当前数据库的别名oracle

_databaseId是在mybatis-config.xml中配置的:


接口:public List getEmpsTestInnerParameter(Employee employee);