Mybatis面试题总结

1、#{}和${}的区别是什么?
#{} 是预编译处理,${}是字符替换
Mybatis在处理#{}时,会将sql中的#{}替换成?号,调用PreparedStatement方法来赋值
Mybatis在处理${}时,就是把${}替换成变量的值
使用#{}可以有效防止sql注入,提高系统的安全性

2、当实体类中的属性名和表中的字段名不一样 ,怎么办 ?

(1) 查询sql的时候定义别名,让字段的别名和实体类的属性名一致

<select id=”selectorder” parametertype=”int” resultetype=”me.gacl.domain.order”> 
       select order_id id, order_no orderno ,order_price price form orders where order_id=#{id}; 
</select> 

(2)通过来映射字段名和实体类属性名一一对应

    <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 = “ordernocolumn =”order_no”/> 
        <result property=”price” column=”order_price” /> 
    </reslutMap>

3、 模糊查询like语句该怎么写?
(1) 在jsp代码中添加sql的通配符

string wildcardname = “%smi%”; 
list<name> names = mapper.selectlike(wildcardname);

<select id=”selectlike”> 
     select * from foo where bar like #{value} 
</select>

(2) 在sql语句中拼接通配符,会引起sql注入

string wildcardname = “smi”; 
list<name> names = mapper.selectlike(wildcardname);

<select id=”selectlike”> 
     select * from foo where bar like "%"#{value}"%"
</select>

4 通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?
Dao接口,就是Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就是传递给sql的参数,当接口调用方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement.
如:com.mybatis3.mappers.StudentDao.findStudentById
可以唯一找到namespace为com.mybatis3.mappers.StudentDao下面id =findStudentById的MappedStatement。
在mybatis中,每一个、、、标签,都会被解析为一个MappedStatement对象。
Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。
Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。

5 如何获取自动生成的主键值?

insert 方法总是返回一个int值 - 这个值代表的是插入的行数。 
而自动生成的键值在 insert 方法执行完后可以被设置到传入的参数对象中。 
示例: 
usegeneratedkeys  打开主键自增
keyproperty   需要自增的主键
<insert id=”insertname” usegeneratedkeys=”true” keyproperty=”id”> 
     insert into names (name) values (#{name}) 
</insert>

    name name = new name(); 
    name.setname(“fred”); 

    int rows = mapper.insertname(name); 
    // 完成后,id已经被设置到对象中 
    system.out.println(“rows inserted = ” + rows); 
    system.out.println(“generated key value = ” + name.getid());

6 Mybatis 动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?

Mybatis动态sql可以让我们在xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能。
9种动态标签:trim | where | set | foreach | when | otherwise | bind | if | choose
执行原理:使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。

7 一对一、一堆多的查询

<mapper namespace="com.lcb.mapping.userMapper">  
    <!--association  一对一关联查询 -->  
    <select id="getClass" parameterType="int" resultMap="ClassesResultMap">  
        select * from class c,teacher t where c.teacher_id=t.t_id and c.c_id=#{id}  
    </select>  
    <resultMap type="com.lcb.user.Classes" id="ClassesResultMap">  
        <!-- 实体类的字段名和数据表的字段名映射 -->  
        <id property="id" column="c_id"/>  
        <result property="name" column="c_name"/>  
        <association property="teacher" javaType="com.lcb.user.Teacher">  
            <id property="id" column="t_id"/>  
            <result property="name" column="t_name"/>  
        </association>  
    </resultMap>  

    <!--collection  一对多关联查询 -->  
    <select id="getClass2" parameterType="int" resultMap="ClassesResultMap2">  
        select * from class c,teacher t,student s where c.teacher_id=t.t_id and c.c_id=s.class_id and c.c_id=#{id}  
    </select>  
    <resultMap type="com.lcb.user.Classes" id="ClassesResultMap2">  
        <id property="id" column="c_id"/>  
        <result property="name" column="c_name"/>  
        <association property="teacher" javaType="com.lcb.user.Teacher">  
            <id property="id" column="t_id"/>  
            <result property="name" column="t_name"/>  
        </association>  
        <collection property="student" ofType="com.lcb.user.Student">  
            <id property="id" column="s_id"/>  
            <result property="name" column="s_name"/>  
        </collection>  
    </resultMap>  
 </mapper>  

8 简述一下mybatis的一级缓存和二级缓存
一级缓存:
(1) mybatis的一级缓存是指SqlSession.一级缓存的作用域是一个SqlSession,mybatis默认开启一级缓存。
(2)在同一个SqlSession中,执行相同的查询sql(参数值也要相同),第一次会去查数据库,并写入缓存;第二次直接从缓存中去。当执行sql时两次查询中间发生了增删改操作,则SqlSession的缓存清空。
二级缓存:
(1)Mybatis的二级缓存是指mapper映射文件。二级缓存的作用域是同一个namespace下的mapper映射文件内容,多个SqlSession共享。Mybatis需要手动设置启动二级缓存
(2)在同一个namespace下的mapper文件中,执行相同的查询SQL,第一次回去查询数据库,并写到缓存中;第二次直接从缓存中取。当执行sql时两次查询中间发生了增删改查操作,则二级缓存清空。

开启二级缓存步骤:
1 在核心配置文件中加入

<setting name="cacheEnabled" value="true"/>

cacheEnabled:对在此配置文件下的所有cache 进行全局性开/关设置。默认为true

2 要在你的Mapper映射文件中添加一行:

<cache />

表示此mapper开启二级缓存。
3 实现序列化
二级缓存需要查询结果映射的pojo对象实现java.io.Serializable接口实现序列化和反序列化操作,注意如果存在父类、成员pojo都需要实现序列化接口。
public class Orders implements Serializable
public class User implements Serializable
….

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值