Mybatis知识

1.Mybatis中#{}和${}的区别

#{}时预编译处理,在运行的时候会被替换成?;KaTeX parse error: Expected 'EOF', got '#' at position 12: {}会被替换成字符串 #̲{}有效的防止SQL注入;{}不能防止SQL注入
使用场景不同,当传递的参数时普通参数时,需要使用#{};当传递参数时SQL命令或SQL关键字时,需要使用${},来对SQL中的参数进行直接替换

2.Mybatis的缓存机制

MyBatis中的一级缓存作用域是同一个SqlSession,在同一个SqlSession中两次执行相同的语句,第一次执行完毕后会将查询到的结构放到一级缓存中,第二次执行的时候直接从缓存中取,不用查询数据库,从而提高效率。当一个sqlSession执行结束后该sqlSession中的一级缓存也就不存在了。一级缓存默认开启。

二级缓存是多个SqlSession共享,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递的参数也相同,即最终执行相同的sql语句。第一次执行后会将查询结果存到二级缓存中,第二次执行的时候会从缓存中取,从而提高效率。二级缓存不会默认开启,需要在setting全局参数中配置开启二级缓存

如果二级缓存是开启的,那么查询顺序是:二级缓存-》一级缓存-》数据库

3.Mybatis的延迟加载

4.Mybatis中 Dao接口和XML文件的SQL如何建立关联

(1)首先创建SqlSource和SqlNode
MyBatis会将每个SQL标签封装成SqlSource对象,根据SQL语句的不同,又分成动态SQL和静态SQL

<select id="getUserById" resultType="user">
    select * from user 
    <where>
        <if test="uid!=null">
            and uid=#{uid}
        </if>
    </where>
</select>  

上面这段sql生成的SqlSource是这样的
在这里插入图片描述
(2)创建mappedStatement
MyBatis会为XML中的每个SQL标签都生成MappedStatement对象。包含两个重要的属性: id + sqlSource
创建完的MappedStatement会被放到Configuration中,Configuration是Mybatis中的大管家,基本所有的配置信息都维护在这里。当把所有的SQL信息解析完,Configuration就包含所有的SQL信息。

xml文件解析完,我们就可以通过”全限定名+方法名“找到MappedStatement,然后解析里面的SQL并进行执行
(3)Dao接口代理
@MapperScan注解将包路径下的所有类注册到Spring Bean中,并将他们的beanClass设置为MapperFactoryBean。当我们通过@Autowired注入这个Dao接口时,返回的对象就是MapperFactoryBean这个工厂Bean中getObject()方法对象。这个方法的作用就是,通过JDK动态代理,返回Dao接口的代理对象MapperProxy,当我们通过@Autowired注入Dao接口时,注入的就是这个对象。我们调用Dao接口中的方法时,则会调用到MapperProxy对象的invoke()方法。
(3)执行:
通过statement拿到MapperStatement对象,然后通过执行器Executor去执行具体SQL并返回

5.一对一、一堆多怎么用MyBatis实现

<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> 

6.Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?

如果配置了namespace,不同的Xml映射文件,id是否可以重复;如果没有配置namespace,那么id不可重复

7.Mybatis是如何进行分页,分页插件的原理是什么

Mybatis使用RowBounds进行分页,属于逻辑分页而非物理分页,是在内存中进行分页

分页插件的原理:通过Mybatis提供插件接口,实现自定义插件,拦截器拦截要分页的sql语句,添加dialet(方言)和分页参数,重写sql

8.简述Mybatis的插件运行原理,以及如何编写一个插件

Mybatis使用JDK动态代理机制,为插件生成动态代理对象以实现接口方法的拦截功能。当执行ParameterHandler、ResultSetHandler、StatementHandler、Executor这四种接口对象的方法时,就会进入invocationHandler中的invoke方法,指挥拦截指定的方法。

编写插件:实现Mybatis中的Interceptor接口
重写intercept方法,指定要拦截的接口,在配置文件中配置编写的插件

9.Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?

Mybatis仅支持association关联对象和collection关联对象的延迟加载。association时一对一,collection是一对多。在Mybatis配置文件中配置 LazyLoadingEabled 的值为true或false

实现原理:当使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截方法。例如:a.get(B).getName(),此时a.get(B)是空,就会执行sql语句,查询B,再a.set(B),最后再执行a.get(B).getName()。

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

1.使用标签,逐一定义数据库列名和属性名的映射关系。
2.使用别名,将列的别名书写为对象的属性名

有了列名和属性名的映射关系,Mybatis通过反射创建对象,同时通过反射给属性逐一赋值并返回

11.Mybatis动态sql有什么用?执行原理?有哪些动态sql?

Mybatis在xml文件中以标签的形式编写sql,执行原理是根据表达式完成逻辑判断并拼接sql的功能。

动态标签有 where if foreach when otherwise

12.Xml映射文件中,除了常见的select|insert|updae|delete标签外,还有哪些标签?

、、、、,加上动态sql的9个标签 trim | where | set | foreach | if | choose | when | otherwise | bind 等,其中 为sql片段标签,通过标签引入sql片段,为不支持自增的主键生成策略标签。

13.使用MyBatis的mapper接口调用时有哪些要求?

Mapper接口方法名和mapper.xml中定义的每个sql的id相同;
Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同;
Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同;
Mapper.xml文件中的namespace即是mapper接口的类路径。

14.模糊查询like语句该怎么写?

1.在Java代码中添加通配符
2.在sql语句中拼接通配符,这样会引起sql注入

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

1.起别名的方式
2.通过resultMap标签实现数据库字段名和属性名对应

16.如何获取自动生成的(主)键值?

xml的方式

<!--添加检查组信息 void add
   useGeneratedKeys="true" keyProperty="id"
   取出数据库自动生成的主键,放在id属性中-->
<insert id=”add” usegeneratedkeys=”true” keyproperty=”id”> 
     insert into t_user values(null,#{birthday},#{gender},#{username},#{password},#{remark},#{station},#{telephone})
</insert>


注解的方式

	/*添加注解 @Options(useGeneratedKeys = true,keyProperty = "id")*/
	@Insert("insert into t_user values(null,#{birthday},#{gender},#{username},#{password},#{remark},#{station},#{telephone})")
    @Options(useGeneratedKeys = true,keyProperty = "id")
    void add(User user);

17.Mybatis中如何传递多个参数

(1)第一种:
//DAO层的函数
Public UserselectUser(String name,String area);  
//对应的xml,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数,更多参数一致往后加即可。
<select id="selectUser"resultMap="BaseResultMap">  
    select *  fromuser_user_t   whereuser_name = #{0} anduser_area=#{1}  
</select>  
 
(2)第二种: 使用 @param 注解:
public interface usermapper {
   user selectuser(@param(“username”) string username,@param(“hashedpassword”) string hashedpassword);
}
然后,就可以在xml像下面这样使用(推荐封装为一个map,作为单个参数传递给mapper):
<select id=”selectuser” resulttype=”user”>
         select id, username, hashedpassword
         from some_table
         where username = #{username}
         and hashedpassword = #{hashedpassword}
</select>
 
(3)第三种:多个参数封装成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();
 }

18.MyBatis实现一对一有几种方式?具体怎么操作的?

有联合查询和嵌套查询。联合查询是几个表联合查询,只查询一次,通过在resultMap里面的collection节点配置一对多的类就可以完成;嵌套查询是先查一个表,根据这个表里面的 结果的外键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的查询通过select节点配置。

19.Mapper编写有哪几种方式?

1.实现类继承SqlSessionDaoSupport
2.使用SqlSessionFactory
3.使用mapper扫描

20.什么是MyBatis的接口绑定?有哪些实现方式?

在mybatis中任意定义接口,将接口与xml语句绑定,直接调用方法名就可以。
实现方式:
1.使用注解,在接口上面加注解
2.使用xml文件,注意namespace必须为接口的全路径名

21.MyBatis与Hibernate有哪些不同?

1.Mybatis不完全是一个对象映射框架,开发者需要自行编写sql
2.Mybatis可以严格控制语句的执行时间、性能,非常适合关系数据模型不高的软件开发。Mybatis做到数据库无关性
3.Hibernate对象映射能力强,数据库无关性号,对关系模型要求高的软件,可以节省很多代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值