mybatis题面试集合

1. #{}和${}

MyBatis将 #{…} 解释为JDBC prepared statement 的一个参数标记。而将 ${…} 解释为字符串替换。理解这两者的区别是很有用的, 因为在某些SQL语句中并不能使用参数标记(parameter markers)。

$多用于模糊查询

SELECT * FROM `user` WHERE username LIKE '%${value}%'

2. parameterType和resultType

parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。

resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中


3. selectOne和selectList

selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:

org.apache.ibatis.exceptions.TooManyResultsException: Expected oneresult (or null) to be returned by selectOne(), but found: 3

   atorg.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)

selectList可以查询一条或多条记录。

4. mysql自增主键返回

查询id的sql

SELECT LAST_INSERT_ID()

通过修改User.xml映射文件,可以将mysql自增主键返回:

如下添加selectKey 标签

<!-- 保存用户 -->

<insert id="saveUser"parameterType="cn.itcast.mybatis.pojo.User">

    <!-- selectKey 标签实现主键返回 -->

    <!-- keyColumn:主键对应的表中的哪一列 -->

    <!-- keyProperty:主键对应的pojo中的哪一个属性 -->

    <!-- order:设置在执行insert语句前执行查询id的sql,孩纸在执行insert语句之后执行查询id的sql -->

    <!-- resultType:设置返回的id的类型-->

    <selectKey keyColumn="id"keyProperty="id"order="AFTER"

       resultType="int">

       SELECTLAST_INSERT_ID()

    </selectKey>

    INSERTINTO `user`

    (username,birthday,sex,address)VALUES

    (#{username},#{birthday},#{sex},#{address})

</insert>

 

LAST_INSERT_ID():mysql的函数,返回auto_increment自增列新记录id

5. Mysql使用 uuid实现主键

需要增加通过select uuid()得到uuid值

<!-- 保存用户 -->

<insert id="saveUser"parameterType="cn.itcast.mybatis.pojo.User">

    <!-- selectKey 标签实现主键返回 -->

    <!-- keyColumn:主键对应的表中的哪一列 -->

    <!-- keyProperty:主键对应的pojo中的哪一个属性 -->

    <!-- order:设置在执行insert语句前执行查询id的sql,孩纸在执行insert语句之后执行查询id的sql -->

    <!-- resultType:设置返回的id的类型-->

    <selectKey keyColumn="id"keyProperty="id"order="BEFORE"

       resultType="string">

       SELECTLAST_INSERT_ID()

    </selectKey>

    INSERTINTO `user`

    (username,birthday,sex,address)VALUES

    (#{username},#{birthday},#{sex},#{address})

</insert>

注意这里使用的order是“BEFORE

6. Mybatis解决jdbc编程的问题

1、数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题。

解决:在SqlMapConfig.xml中配置数据连接池,使用连接池管理数据库链接。

2、Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。

解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。

3、向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。

解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。

4、对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。

解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。

7. mybatis与hibernate不同

Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。

8.Mapper接口开发需要遵循以下规范:

1、Mapper.xml文件中的namespace与mapper接口的类路径相同。

2、Mapper接口方法名和Mapper.xml中定义的每个statement的id相同

3、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同

4、Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

9.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的功能

10.Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

            第一种是使用<resultMap>标签,逐一定义列名和对象属性名之间的映射关系。第二种是使用sql列的别名功能,将列别名书写为对象属性名,比如T_NAME AS NAME,对象属性名一般是name,小写,但是列名不区分大小写,Mybatis会忽略列名大小写,智能找到与之对应对象属性名,你甚至可以写成T_NAME AS NaMe,Mybatis一样可以正常工作。

有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

11.Mybatis传递多个参数的解决办法(三种)

第一种方案

DAO层的函数方法

[java]  view plain  copy
  1. Public User selectUser(String name,String area);  

对应的Mapper.xml

[java]  view plain  copy
  1. <select id="selectUser" resultMap="BaseResultMap">  
  2. select * from user_user_t where user_name = #{0} and user_area=#{1}  
  3. </select>  

其中,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数,更多参数一致往后加即可。

第二种方案

此方法采用Map传多参数.

Dao层的函数方法

[java]  view plain  copy
  1. Public User selectUser(Map paramMap);  

对应的Mapper.xml

[java]  view plain  copy
  1. <select id=" selectUser" resultMap="BaseResultMap">  
  2. select * from user_user_t where user_name = #{userName,jdbcType=VARCHAR} and user_area=#{userArea,jdbcType=VARCHAR}  
  3. </select>  

Service层调用

[java]  view plain  copy
  1. Private User xxxSelectUser(){  
  2. Map paramMap=new hashMap();  
  3. paramMap.put(“userName”,”对应具体的参数值”);  
  4. paramMap.put(“userArea”,”对应具体的参数值”);  
  5. User user=xxx. selectUser(paramMap);}  

个人认为此方法不够直观,见到接口方法不能直接的知道要传的参数是什么。

第三种方案

Dao层的函数方法

[java]  view plain  copy
  1. Public User selectUser(@param(“userName”)Stringname,@param(“userArea”)String area);  

对应的Mapper.xml

[java]  view plain  copy
  1. <select id=" selectUser" resultMap="BaseResultMap">  
  2. select * from user_user_t where user_name = #{userName,jdbcType=VARCHAR} and user_area=#{userArea,jdbcType=VARCHAR}  
  3. </select>   

个人觉得这种方法比较好,能让开发者看到dao层方法就知道该传什么样的参数,比较直观,个人推荐用此种方案。



Mybatis传递多个参数的解决办法(三种)

猜你喜欢

转载自blog.csdn.net/bestkilly/article/details/80530167