1、什么是 Mybatis?
2、Mybaits 的优点:
3、MyBatis 框架的缺点:
4、MyBatis 框架适用场合:
5、MyBatis 与 Hibernate 有哪些不同?
6、#{}和${}的区别是什么?
7、当实体类中的属性名和表中的字段名不一样 ,怎么办 ?


8、 模糊查询 like 语句该怎么写?


9、通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原 理是什么?Dao 接口里的方法,参数不同时,方法能重载吗?

10、Mybatis 是如何进行分页的?分页插件的原理是什么?
11、Mybatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式?
12、如何执行批量插入?


13、如何获取自动生成的(主)键值?


14、在 mapper 中如何传递多个参数?



15、Mybatis 动态 sql 有什么用?执行原理?有哪些动态 sql?
16、Xml 映射文件中,除了常见的 select|insert|updae|delete 标签之外,还有哪些标签?
17、Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?
18、为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?
19、 一对一、一对多的关联查询 ?

20、MyBatis 实现一对一有几种方式?具体怎么操作的?
21、MyBatis 实现一对多有几种方式,怎么操作的?
22、Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?
23、Mybatis 的一级、二级缓存:
24、什么是 MyBatis 的接口绑定?有哪些实现方式?
25、使用 MyBatis 的 mapper 接口调用时有哪些要求?
26、Mapper 编写有哪几种方式?
(1)在 sqlMapConfig.xml 中配置 mapper.xml 的位置
<mappers>
<mapper resource="mapper.xml 文件的地址" />
<mapper resource="mapper.xml 文件的地址" />
</mappers>
(2)定义 mapper 接口
(3)实现类集成 SqlSessionDaoSupport
mapper 方法中可以 this.getSqlSession()进行数据增删改查。
(4)spring 配置
<bean id=" " class="mapper 接口的实现">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
(1)在 sqlMapConfig.xml 中配置 mapper.xml 的位置,如果 mapper.xml 和
mappre 接口的名称相同且在同一个目录,这里可以不用配置
<mappers>
<mapper resource="mapper.xml 文件的地址" />
<mapper resource="mapper.xml 文件的地址" />
</mappers>
(2)定义 mapper 接口:
①mapper.xml 中的 namespace 为 mapper 接口的地址
②mapper 接口中的方法名和 mapper.xml 中的定义的 statement 的 id 保持一致
③Spring 中定义
<bean id="" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="mapper 接口地址" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
(1)mapper.xml 文件编写:
mapper.xml 中的 namespace 为 mapper 接口的地址;
mapper 接口中的方法名和 mapper.xml 中的定义的 statement 的 id 保持一致;
如果将 mapper.xml 和 mapper 接口的名称保持一致则不用在 sqlMapConfig.xml
中进行配置。
(2)定义 mapper 接口:
注意 mapper.xml 的文件名和 mapper 的接口名称保持一致,且放在同一个目录
(3)配置 mapper 扫描器:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="mapper 接口包地址"></property>
<property name="sqlSessionFactoryBeanName"
value="sqlSessionFactory"/>
</bean>
(4)使用扫描器后从 spring 容器中获取 mapper 的实现对象。
27、简述 Mybatis 的插件运行原理,以及如何编写一个插件。
27、批量删除:(choose when foreach )
一:
dao层:传入多个id
/**
* 基于id删除多条日志信息
* @param ids
* @return
*/
int deleteObjects(Integer...ids);
<delete id="deleteObjects">
delete from sys_logs
<where>
<choose>
<when test="ids!=null and ids.length>0">
id in
<foreach collection="ids" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</when>
<otherwise>
or 1=2
</otherwise>
</choose>
</where>
</delete>
二:
public class FastDFSModel {
private String pathId;
private String modelId;
private String csvpath;
private String resultpath;
private String updatetime;
}
dao:
import org.apache.ibatis.annotations.Param;
void deleteDateById(@Param("list") List<FastDFSModel> deleteList);
mapper:
其中parameterType写为list,foreach 中的collection写为"list",item 为遍历的每一项,代表着model在变量中用#{item.pathId}来获取值此业务为通过id进行删除其中open="(" separator="," close=")"为拼接的in查询,把id用逗号拼接起来
<delete id="deleteDateById" parameterType="java.util.List">
delete from T_FASTDFS_PATH t where t.path_id in
<foreach item="item" collection="list" open="(" separator="," close=")">
#{item.pathId,jdbcType=VARCHAR}
</foreach>
</delete>
控制台打印:
delete from T_FASTDFS_PATH t where t.path_id in ( ? , ? , ? )
PreparedStatement - ==> Parameters: 2(String), 1(String), 3(String)
附加案例
<?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="cn.sz.hcq.pojo.Emp">
<!-- 批量删除 -->
<delete id="deleteMoreEmp" parameterType="int[]">
<!-- delete from emp where empno in(7789,7790) -->
<!-- forEach : 用来循环 collection : 用来指定循环的数据的类型 可以填的值有:array,list,map item
: 循环中为每个循环的数据指定一个别名 index : 循环中循环的下标 open : 开始 close : 结束 separator : 数组中元素之间的分隔符 -->
delete from emp where empno in
<foreach collection="array" item="arr" index="no" open="("
separator="," close=")">
#{arr}
</foreach>
</delete>
</mapper>
28:批量插入:
int insertList(List<WaterEle> list);
<!--批量增加测试-->
<insert id="insertList" parameterType="java.util.List">
insert into t_enterprise_water_ele
(
/*方法一*/
-- WATER_ELE_ID,
-- ENTERPRISE_ID,
-- ENTERPRISE_USCC,
-- ENTERPRISE_NAME,
-- YEARMONTH,
-- WATER_SIZE,
-- WATER_AMOUNT,
-- ELE_SIZE,
-- ELE_AMOUNT,
-- STATUS,
-- OPERATOR,
-- OPERATE_TIME
/*方法二*/
<include refid="Base_Column_List"/>
)
VALUES
<foreach collection="list" item="item" index="index" separator=",">
(
#{item.waterEleId,jdbcType=VARCHAR},
#{item.enterpriseId,jdbcType=VARCHAR},
#{item.enterpriseUscc,jdbcType=VARCHAR},
#{item.enterpriseName,jdbcType=VARCHAR},
#{item.yearmonth,jdbcType=VARCHAR},
#{item.waterSize,jdbcType=DECIMAL},
#{item.waterAmount,jdbcType=VARCHAR},
#{item.eleSize,jdbcType=DOUBLE},
#{item.eleAmount,jdbcType=VARCHAR},
#{item.status,jdbcType=INTEGER},
#{item.operator,jdbcType=VARCHAR},
#{item.operateTime,jdbcType=TIMESTAMP}
)
</foreach>
</insert>
对于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
使用批量插入执行的SQL语句应该等价于:
insert into redeem_code (batch_id, code, type, facevalue,create_user,create_time)
values (?,?,?,?,?,? ),(?,?,?,?,?,? ),(?,?,?,?,?,? ),(?,?,?,?,?,? )
29:批量更新
1、传list集合
单个字段
批量更新测试
<update id="updateByBatch" parameterType="java.util.List">
update t_goods
set NODE_ID=
<foreach collection="list" item="item" index="index"
separator=" " open="case" close="end">
when GOODS_ID=#{item.goodsId} then #{item.nodeId}
</foreach>
where GOODS_ID in
<foreach collection="list" index="index" item="item"
separator="," open="(" close=")">
#{item.goodsId,jdbcType=BIGINT}
</foreach>
</update>
单个字段方法二
<update id="updateByBatch" parameterType="java.util.List">
UPDATE
t_goods
SET NODE_ID = CASE
<foreach collection="list" item="item" index="index">
WHEN GOODS_ID = #{item.goodsId} THEN #{item.nodeId}
</foreach>
END
WHERE GOODS_ID IN
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item.goodsId}
</foreach>
</update>
以上单字段更新实际执行:
UPDATE t_goods SET NODE_ID = CASE WHEN GOODS_ID = ? THEN ? END WHERE GOODS_ID IN ( ? )
多个字段:
<update id="updateBatch" parameterType="java.util.List">
update t_user
<trim prefix="set" suffixOverrides=",">
<trim prefix="STATUS =case" suffix="end,">
<foreach collection="list" item="i" index="index">
<if test="i.status!=null">
when USER_ID=#{i.userId} then #{i.status}
</if>
</foreach>
</trim>
<trim prefix=" OPERATE_TIME =case" suffix="end,">
<foreach collection="list" item="i" index="index">
<if test="i.operateTime!=null">
when USER_ID=#{i.userId} then #{i.operateTime}
</if>
</foreach>
</trim>
<trim prefix="OPERATOR =case" suffix="end," >
<foreach collection="list" item="i" index="index">
<if test="i.operator!=null">
when USER_ID=#{i.userId} then #{i.operator}
</if>
</foreach>
</trim>
</trim>
where
<foreach collection="list" separator="or" item="i" index="index" >
USER_ID=#{i.userId}
</foreach>
</update>
https://www.jianshu.com/p/041bec8ae6d3
29:模糊查询:
Oracle数据库:
SELECT
*
FROM
user
WHERE
name like CONCAT('%',#{name},'%')
--或
SELECT
*
FROM
user
WHERE
name like '%'||#{name}||'%'
mysql数据库:
--Java代码
SELECT
*
FROM
user
WHERE
name like CONCAT('%',#{name},'%')
mapper文件:
<select id="findPageObjects" resultType="com.cy.pj.sys.pojo.SysLog">
select *
from sys_logs
<where>
<if test="username!=null and username!=''">
username like concat("%",#{username},"%")
</if>
</where>
order by createdTime desc
</select>