Mybatis 常考面试题汇总(附答案),学习 SpringBoot
<select id="getOrder" parameterType="int" resultMap="orderresultmap">
select * from orders where order_id=#{id}
</select>
<resultMap type=”me.gacl.domain.order” id=”orderresultmap”>
<!–用 id 属性来映射主键字段–>
<id property=”id” column=”order_id”>
<!–用 result 属性来映射非主键字段,property 为实体类属性名,column 为数据表中的属性–>
<result property = “orderno” column =”order_no”/>
<result property=”price” column=”order_price” />
</reslutMap>
我认为第二种方式会好一点。
3、如何获取自动生成的(主)键值?
如何获取自动生成的(主)键值?
如果我们一般插入数据的话,如果我们想要知道刚刚插入的数据的主键是多少,我们可以通过以下的方式来获取
需求:
user 对象插入到数据库后,新记录的主键要通过 user 对象返回,通过 user 获取主键值。
解决思路:
通过 LAST_INSERT_ID()获取刚插入记录的自增主键值,在 insert 语句执行后,执行 select LAST_INSERT_ID()就可以获取自增主键。
mysql:
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<selectKey keyProperty="id" order="AFTER" resultType="int">
select LAST_INSERT_ID()
</selectKey>
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
</insert>
oracle:
实现思路:
先查询序列得到主键,将主键设置到 user 对象中,将 user 对象插入数据库。
<!-- oracle
在执行 insert 之前执行 select 序列.nextval() from dual 取出序列最大值,将值设置到 user 对象 的 id 属性
-->
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<selectKey keyProperty="id" order="BEFORE" resultType="int">
select 序列.nextval() from dual
</selectKey>
INSERT INTO USER(id,username,birthday,sex,address) VALUES( 序列.nextval(),#{username},#{birthday},#{sex},#{address})
</insert>
4、在 mapper 中如何传递多个参数?
在 mapper 中如何传递多个参数?
**第一种:使用占位符的思
想**
在映射文件中使用 #{0},#{1}代表传递进来的第几个参数
**使用 @param 注解:来命名参数 **
#{0},#{1}方式
//对应的 xml,#{0}代表接收的是 dao 层中的第一个参数,#{1}代表 dao 层中第二参数,更多参数一致往后加即可。
<select id="selectUser"resultMap="BaseResultMap">
select * fromuser_user_t whereuser_name = #{0} anduser_area=#{1}
</select>
@param 注解方式
public interface usermapper {
user selectuser(@param(“username”) string username,
@param(“hashedpassword”) string hashedpassword);
}
<select id=”selectuser” resulttype=”user”>
select id, username, hashedpassword
from some_table
where username = #{username}
and hashedpassword = #{hashedpassword}
</select>
第二种:使用 Map 集合作为参数来装载
try{
//映射文件的命名空间.SQL 片段的 ID,就可以调用对应的映射文件中的 SQL
/**
由于我们的参数超过了两个,而方法中只有一个 Object 参数收集
因此我们使用 Map 集合来装载我们的参数
*/
Map<String, Object> map = new HashMap();
map.put("start", start);
map.put("end", end);
return sqlSession.selectList("StudentID.pagination", map);
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
<select id="pagination" parameterType="map" resultMap="studentMap">
/根据 key 自动找到对应 Map 集合的 value/
select * from students limit #{start},#{end};
</select>
5、Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql 的执行原理不?
Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql 的执行原理不?
Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。
Mybatis 提供了 9 种动态 sql 标签:trim|where|set|foreach|if|choose|when|otherwise|bind。
其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。
6、Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?
Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?
如果配置了 namespace 那么当然是可以重复的,因为我们的 Statement 实际上就是 namespace+id
如果没有配置 namespace 的话,那么相同的 id 就会导致覆盖了。
7、为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?
为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?
Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
而 Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。
8、通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗?
通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗?
Dao 接口,就是人们常说的 Mapper 接口,接口的全限名,就是映射文件中的 namespace 的值,接口的方法名,就是映射文件中 MappedStatement 的 id 值,接口方法内的参数,就是传递给 sql 的参数。
Mapper 接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为 key 值,可唯一定位一个 MappedStatement
举例:
com.mybatis3.mappers.StudentDao.findStudentById,
可以唯一找到 namespace 为 com.mybatis3.mappers.StudentDao 下面 id = findStudentById 的 MappedStatement。在 Mybatis 中,每一个<select>、<insert>、<update>、<delete>标签,都会被解析为一个 MappedStatement 对象。
Dao 接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。
Dao 接口的工作原理是 JDK 动态代理,Mybatis 运行时会使用 JDK 动态代理为 Dao 接口生成代理 proxy 对象,代理对象 proxy 会拦截接口方法,转而执行 MappedStatement 所代表的 sql,然后将 sql 执行结果返回。
详情可参考:
评论