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?
请写出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,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}
6.请使用collection节点实现获取指定用户的相关信息和地址列表(User实体类中有一个复杂类型的Address集合,只写SQL映射文件)
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中两次执行相同的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 & 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.#{}和${}的区别是什么?
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}
只有在需要排序的时候 使用$ .
其他时候能用#绝对不用$