Mybatis面试题

1请写出Mybatis核心配置文件MyBatis-config.xml的内容?

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

<!--通过properties文件链接数据库的四要素 -->
<properties resource="jdbc.properties"/>
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!--设置别名-->
<typeAliases>
<package name="cn.mybatis.bean"/>
</typeAliases>
<!--配置运行环境-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 加载映射文件信息 -->
<mappers>
<mapper resource="mapper/Mapper.xml"/>
</mappers>
</configuration>

2请写出Mybatis框架的优缺点?

优点:

1、简单、易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。

2、实用、提供了数据映射功能,提供了对底层数据访问的封装(例如ado.net),提供了DAO框架,可以使我们更容易的开发和配置我们的DAL层

3、灵活、通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多

4、功能完整:提供了连接管理,缓存支持,线程支持,(分布式)事物管理,通过配置作关系对象映射等数据访问层需要解决的问题。提供了DAO支持,并在DAO框架中封装了ADO.NET,NHibernate和DataMapper。

5、增强系统的可维护性:通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。

缺点:

1、滞后性:

  还没有明确对.NET2.0的支持。最新版本在2.0下编译可以,但有些单元测试不能通过。

  不成熟,工程实践较少:
  IbatisNet在实际项目中的使用较少。 只是理论上可行.
2、半ORM,工具支持较少:
  需要我们自己写sql,并且.NET下还未发现可以自动生成业务层类和配置文件的工具,这点和NHibernate不一样,NHibernate会为我们的数据库直接产生sql,并有一些辅助工具。因此使用Ibatis比NHibernate要多做一些工作。

3.什么是数据持久化以及ORM?

持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。
持久化是将程序数据在持久状态和瞬时状态间转换的机制。
ORM是 对象-关系映射(OBJECT/RELATIONALMAPPING,简称ORM),是随着面向对象的软件开发方法发展而产生的。用来把对象模型表示的对象映射到基于S Q L 的关系模型数据库结构中去。这样,我们在具体的操作实体对象的时候,就不需要再去和复杂的 SQ L 语句打交道,只需简单的操作实体对象的属性和方法 。O R M 技术是在对象和关系之间提供了一条桥梁,前台的对象型数据和数据库中的关系型的数据通过这个桥梁来相互转化

请写出MybatisUtil工具类

public class SessionFactoryUtil {
//私有化属性
private static SqlSessionFactory factory;
//私有化构造
private SessionFactoryUtil(){};
//对外提供访问接口
public static synchronized SqlSession getSession(){
try {
InputStream is= org.apache.ibatis.io.Resources.getResourceAsStream("mybatis.xml");
if(factory==null){
factory= new SqlSessionFactoryBuilder().build(is);

}
} catch (IOException e) {
e.printStackTrace();
}
return factory.openSession();
}
}

5.请使用association节点实现根据用户角色id获取该角色下的用户列表(User实体类中有一个复杂对象Role,只写SQL映射文件)

 <select id="userById" resultMap="userMap">
     select id,name from user where id=#{xxx}
  <select>

<resultMap id="userMap" type="User">
      <id property="id" column="id"/>
      <result property="name" column="name"/> 
      <association property="role" javaType="Role" select="selectUserId" column="id"></association>
</resultMap>

<select id="selectUserId" resultType="Role">
   select rid,rname from role where userId=#{xxx}

</select>

6.请使用collection节点实现获取指定用户的相关信息和地址列表(User实体类中有一个复杂类型的Address集合,只写SQL映射文件)

 <select id="selectUserById" resultMap="userMap" parameterType="User">
      select id,name,aid,aname from user,address where id=aid and id=#{xxx}   
  <select>
   <resultMap id="userMap"  type="User">
      <id property="id" column="id"/>
        <result property="name"  column="name"/>

       <collection property="provincials" ofType="Provincial">
           <id property="aId" column="aid"/>
           <result property="aName" column="aname"/>

       </collection>

   </resultMap>

7.MyBatis的一级缓存缓存的是什么,二级缓存缓存的是什么?

mybatis一级缓存缓存:

 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓 存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。

  一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓 存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不 存在了。Mybatis默认开启一级缓存。

  二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区 域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

8.如何开启MyBatis的二级缓

要开启二级缓存,只需要在你的Mapper
映射文件中添加一行:  
<cache /> 
它将采用默认的行为进行缓存:

  •  映射文件中所有的select语句将被缓存
  •  映射文件中所有的insert、update和delete语句将刷新缓存 
  •  缓存将使用LRU(Least Recently Used)最近最少使用策略算法来回收
  •  刷新间隔(no Flush Interval,没有刷新间隔),缓存不会以任何时间顺序来刷新
  •  缓存会存储列表集合和对象(无论查询方法返回什么)的1024个引用 
  •  缓存会被视为read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以安全的被调用者修改,而不干扰其他调用者或者线程所做的潜在修改

所有这些属性都可以通过缓存元素的属性来修改,比如: 

<cache 
 eviction="FIFO"  
 flushInterval="10800000"  size="512" 
 readOnly="true"  

/> 
这个更高级的配置创建了一个FIFO缓存,并每隔3个小时刷新缓存,储存结
果对象或列表的512个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改他们会导致冲突。

 

9.请根据商品名称(模糊查询),供应商,以及是否付款进行多条件查询和分页(只写SQL映射文件)

<select id="selectNameById" resultType="Product">

  select * from product 

  <where>

  <if test="productName!=null &amp; productName!=' ' ">and productName like concat("%",#{productName},"%")</if>

  <if test="productId>0">and productId=#{productId}</if>

  <if test="isPayment>0">and isPayment=#{isPayment}</if>

  </where>

</select>

10.#{}和${}的区别是什么?

 01.$ 不安全 底层实现是statement对象

    select * from student  where id=${id}
    如果我们id传入的是11    编译之后
    select * from student  where id=11

   # 安全   底层实现是PreparedStatement对象
    select * from student  where id=#{id}
    如果我们id传入的是11    编译之后
    select * from student  where id=?

02.在sql语句需要排序的时候
     order  by  ${id}
     只有在需要排序的时候 使用$ .
     其他时候能用#绝对不用$


posted @ 2017-09-25 16:27  East-M  阅读(450)  评论(0编辑  收藏  举报