Mybatis常考面试题汇总附答案
1、#{}和${}的区别是什么?#{}和${}的区别是什么?在Mybatis中,有两种占位符#{}解析传递进来的参数数据${}对传递进来的参数原样拼接在SQL中#{}是预编译处理,${}是字符串替换。使用#{}可以有效的防止SQL注入,提高系统安全性。2、当实体类中的属性名和表中的字段名不一样 ,怎么办 ?当实体类中的属性名和表中的字段名不一样 ,怎么办 ?第1种: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致1 <select id=”selectorder” parametertype=”int” resultetype=”me.gacl.domain.order”>2 select order_id id, order_no orderno ,order_price price form orders where order_id=#{id};3 </select>第2种: 通过来映射字段名和实体类属性名的一一对应的关系1 <select id="getOrder" parameterType="int" resultMap="orderresultmap">2 select * from orders where order_id=#{id}3 </select>4 <resultMap type=”me.gacl.domain.order” id=”orderresultmap”>5 <!–用id属性来映射主键字段–>6 <id property=”id” column=”order_id”>7 <!–用result属性来映射非主键字段,property为实体类属性名,column为数据表中的属性–>8 <result property = “orderno” column =”order_no”/>9 <result property=”price” column=”order_price” />10 </reslutMap>我认为第二种方式会好一点。3、如何获取自动生成的(主)键值?如何获取自动生成的(主)键值?如果我们一般插入数据的话,如果我们想要知道刚刚插入的数据的主键是多少,我们可以通过以下的方式来获取需求:user对象插入到数据库后,新记录的主键要通过user对象返回,通过user获取主键值。解决思路:通过LAST_INSERT_ID()获取刚插入记录的自增主键值,在insert语句执行后,执行select LAST_INSERT_ID()就可以获取自增主键。mysql:1 <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">2 <selectKey keyProperty="id" order="AFTER" resultType="int">3 select LAST_INSERT_ID()4 </selectKey>5 INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})6 </insert>oracle:实现思路:先查询序列得到主键,将主键设置到user对象中,将user对象插入数据库。1 <!-- oracle2 在执行insert之前执行select 序列.nextval() from dual取出序列最大值,将值设置到user对象 的id属性3 -->4 <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">5 <selectKey keyProperty="id" order="BEFORE" resultType="int">6 select 序列.nextval() from dual7 </selectKey>89 INSERT INTO USER(id,username,birthday,sex,address) VALUES( 序列.nextval(),#{username},#{birthday},#{sex},#{address})10 </insert>4、在mapper中如何传递多个参数?在mapper中如何传递多个参数?第一种:使用占位符的思想在映射文件中使用#{0},#{1}代表传递进来的第几个参数**使用@param注解:来命名参数 **#{0},#{1}方式1 //对应的xml,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数,更多参数一致往后加即可。23 <select id="selectUser"resultMap="BaseResultMap">4 select * fromuser_user_t whereuser_name = #{0} anduser_area=#{1}5 </select>@param注解方式1 public interface usermapper {2 user selectuser(@param(“username”) string username,3 @param(“hashedpassword”) string hashedpassword);4 } 1 <select id=”selectuser” resulttype=”user”>2 select id, username, hashedpassword3 from some_table4 where username = #{username}5 and hashedpassword = #{hashedpassword}6 </select> 第二种:使用Map集合作为参数来装载1 try{2 //映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL345 /**6 * 由于我们的参数超过了两个,而方法中只有一个Object参数收集7 * 因此我们使用Map集合来装载我们的参数8 */9 Map<String, Object> map = new HashMap();10 map.put("start", start);11 map.put("end", end);12 return sqlSession.selectList("StudentID.pagination", map);13 }catch(Exception e){14 e.printStackTrace();15 sqlSession.rollback();16 throw e;17 }finally{18 MybatisUtil.closeSqlSession();19 } 1 <!--分页查询-->2 <select id="pagination" parameterType="map" resultMap="studentMap">34 /*根据key自动找到对应Map集合的value*/5 select * from students limit #{start},#{end};67 </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举例:1 com.mybatis3.mappers.StudentDao.findStudentById,23 可以唯一找到namespace为com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement。在Mybatis中,每一个<select>、<insert>、<update>、<delete>标签,都会被解析为一个MappedStatement对象。Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,