笔 试 题
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"/> <!--全局关闭2级缓存 --> <!--<setting name="cacheEnabled" value="false"/>--> </settings> <!--创建类的别名--> <typeAliases> <!--只要是在mapper.xml文件中使用了cn.pb.bean包下面的任意类的时候,无需再用全类名 使用简写的类名 之前应该 cn.pb.bean.Student 现在 Student --> <package name="cn.pb.bean"/> </typeAliases> <!--设置mybatis运行环境 default默认的运行环境====environment id的属性值--> <environments default="mysql"> <environment id="mysql"> <!--配置事务管理器--> <transactionManager type="JDBC"></transactionManager> <!--配置数据源 POOLED:mybatis自带的数据源--> <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> <!--配置需要的mapper文件--> <mappers> <mapper resource="mapper/StudentMapper.xml"/> </mappers></configuration>
2请写出Mybatis框架的优缺点?
优点:
1. 易于上手和掌握。
2. sql写在xml里,便于统一管理和优化。
3. 解除sql与程序代码的耦合。
4. 提供映射标签,支持对象与数据库的orm字段关系映射
5. 提供对象关系映射标签,支持对象关系组建维护
6. 提供xml标签,支持编写动态sql。
缺点:
1. sql工作量很大,尤其是字段多、关联表多时,更是如此。
2. sql依赖于数据库,导致数据库移植性差。
3. 由于xml里标签id必须唯一,导致DAO中方法不支持方法重载。
4. 字段映射标签和对象关系映射标签仅仅是对映射关系的描述,具体实现仍然依赖于sql。(比如配置了一对多Collection标签,如果sql里没有join子表或查询子表的话,查询后返回的对象是不具备对象关系的,即Collection的对象为null)
5. DAO层过于简单,对象组装的工作量较大。
6. 不支持级联更新、级联删除。
7. 编写动态sql时,不方便调试,尤其逻辑复杂时。
8 提供的写动态sql的xml标签功能简单(连struts都比不上),编写动态sql仍然受限,且可读性低。
9. 若不查询主键字段,容易造成查询出的对象有“覆盖”现象。
10. 参数的数据类型支持不完善。(如参数为Date类型时,容易报没有get、set方法,需在参数上加@param)
11. 多参数时,使用不方便,功能不够强大。(目前支持的方法有map、对象、注解@param以及默认采用012索引位的方式)
12. 缓存使用不当,容易产生脏数据。
总结:
mybatis的优点其实也是mybatis的缺点,正因为mybatis使用简单,数据的可靠性、完整性的瓶颈便更多依赖于程序员对sql的使用水平上了。sql写在xml里,虽然方便了修改、优化和统一浏览,但可读性很低,调试也非常困难,也非常受限,无法像jdbc那样在代码里根据逻辑实现复杂动态sql拼接。mybatis简单看就是提供了字段映射和对象关系映射的jdbc,省去了数据赋值到对象的步骤而已,除此以外并无太多作为,不要把它想象成hibernate那样强大,简单小巧易用上手,方便浏览修改sql就是它最大的优点了。
mybatis适用于小型且程序员能力较低的项目和人群使用,对于中大型项目来说我并不推荐使用,如果觉得hibernate效率低的话(实际上也是使用不当所致,hibernate是实际上是不适用于拥有高负载的工程项目),还不如直接用spring提供的jdbc简单框架(Template),同样支持对象映射。
3.什么是数据持久化以及ORM?
4请写出MybatisUtil工具类
package cn.pb.util; import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException;import java.io.InputStream; public class SessionFactoryUtil { //01.创建需要单例的对象实例 private static SqlSessionFactory sessionFactory; //02.私有化构造 private SessionFactoryUtil(){} /** * 03.对外提供访问的接口 * 001.SqlSession的创建依赖SqlSessionFactory * 002.SqlSessionFactory依赖于SqlSessionFactoryBuilder * 003.SqlSessionFactoryBuilder依赖于配置文件 * 004.获取配置文件 */ public static synchronized SqlSession getSession(){ //给我一个文件 返回一个输入流 到 内存中 try { InputStream stream = Resources.getResourceAsStream("mybatis.xml"); //判断SqlSessionFactory是否为空 if (sessionFactory==null){ sessionFactory=new SqlSessionFactoryBuilder().build(stream); } } catch (IOException e) { e.printStackTrace(); } /** * 之前还需要写一个finally用来关闭流! 现在不需要 为什么不需要?? * 01.查询源码build(stream) * 02.SqlSessionFactoryBuilder类中已经关闭reader.close() * 03.所以我们如果关闭流 会报错! */ return sessionFactory.openSession(); //创建session返回 }}
5.请使用association节点实现根据用户id查询用户信息以及对应角色信息(Role实体类中有一个对象User,只写SQL映射文件)?
<!-- 01. 根据角色id 查询出角色信息--><select id="selectRoleById" resultMap="roleMap">select id,name,userid from role where id=#{xxx}</select> <!-- 02. 根据角色表中查询结果中的userid 查询用户信息 xxx就是resultmap中传递来的 userid--><select id="selectUserByUserId" resultType="User">select userid,name from user where userid=#{xxx}</select> <!--对应的roleMap 这种方式 推荐使用 因为使用延迟加载--><resultMap id="rolrMap" type="Role"><id property="id" column="id"/><result property="name" column="name"/><!-- Role有一个属性的类型是 user 域属性javaType:域属性对应的类型 --><association property="user" javaType="User" select="selectUserByUserId" column="userid"/></resultMap>
6.请使用collection节点实现获取指定用户的相关信息和地址列表(User实体类中有一个复杂类型的Address集合,只写SQL映射文件)?
<!-- 01. 根据用户id 查询出用户信息--><select id="selectUserById" resultMap="userMap">select id,name from user where id=#{xxx}</select> <!-- 02. 根据用户表中查询结果中的userid 查询地址信息 xxx就是resultmap中传递来的 userid--><select id="selectAddressByUserId" resultType="Address">select id,name,userid from address where userid=#{xxx}</select> <!--对应的userMap 这种方式 推荐使用 因为使用延迟加载--><resultMap id="userMap" type="User"><id property="id" column="id"/><result property="name" column="name"/><!-- User有一个属性的类型是 list javaType:域属性对应的类型 --><collection property="addresses" javaType="Address" select="selectAddressByUserId" column="userid"/></resultMap>