• 【MyBatis】MyBatis 理论 40 问(二)


    MyBatis 理论 40 问》包含以下 2 篇文章:


    21.如何获取生成的主键?

    新增标签中添加:keyProperty=“ID” 即可。

    <insert id="insert" useGeneratedKeys="true" keyProperty="userId" >
    	insert into user(user_name, user_password, create_time)
    	values(#{userName}, #{userPassword} , #{createTime, jdbcType=TIMESTAMP})
    insert>
    

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

    (1)通过在查询的 SQL 语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。

    <select id="getOrder" parameterType="int" resultType="com.jourwon.pojo.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="com.jourwon.pojo.Order" id="orderResultMap">
    	
    	<id property="id" column="order_id">
    	
    	<result property="orderno" column="order_no" />
    	<result property="price" column="order_price" />
    reslutMap>
    

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

    (1)接口实现类继承 SqlSessionDaoSupport:使用此种方法需要编写 mapper 接口,mapper 接口实现类、mapper.xml 文件。

    • sqlMapConfig.xml 中配置 mapper.xml 的位置。
    <mappers>
    	<mapper resource="mapper.xml 文件的地址" />
    	<mapper resource="mapper.xml 文件的地址" />
    mappers>
    
    • 定义 mapper 接口。
    • 实现类集成 SqlSessionDaoSupportmapper 方法中可以用 this.getSqlSession() 进行数据增删改查。
    • spring 配置。
    <bean id=" " class="mapper 接口的实现">
    	<property name="sqlSessionFactory" ref="sqlSessionFactory">property>
    bean>
    

    (2)使用 org.mybatis.spring.mapper.MapperFactoryBean

    • sqlMapConfig.xml 中配置 mapper.xml 的位置,如果 mapper.xmlmapper 接口的名称相同且在同一个目录,这里可以不用配置。
    • 定义 mapper 接口。
    <mappers>
    	<mapper resource="mapper.xml 文件的地址" />
    	<mapper resource="mapper.xml 文件的地址" />
    mappers>
    
    • mapper.xml 中的 namespacemapper 接口的地址。
    • mapper 接口中的方法名和 mapper.xml 中的定义的 statementid 保持一致。
    • Spring 中定义。
    <bean id="" class="org.mybatis.spring.mapper.MapperFactoryBean">
    	<property name="mapperInterface" value="mapper 接口地址" />
    	<property name="sqlSessionFactory" ref="sqlSessionFactory" />
    bean>
    

    (3)使用 mapper 扫描器。

    • mapper.xml 文件编写。
      • mapper.xml 中的 namespacemapper 接口的地址;
      • mapper 接口中的方法名和 mapper.xml 中的定义的 statementid 保持一致;
      • 如果将 mapper.xmlmapper 接口的名称保持一致则不用在 sqlMapConfig.xml 中进行配置。
    • 定义 mapper 接口。注意 mapper.xml 的文件名和 mapper 的接口名称保持一致,且放在同一个目录。
    • 配置 mapper 扫描器。
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    	<property name="basePackage" value="mapper 接口包地址">property>
    	<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    bean>
    
    • 使用扫描器后从 spring 容器中获取 mapper 的实现对象。

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

    接口绑定,就是在 MyBatis 中任意定义接口,然后把接口里面的方法和 SQL 语句绑定,我们直接调用接口方法就可以,这样比起原来的 SqlSession 提供的方法我们可以有更加灵活的选择和设置。

    接口绑定有两种实现方式:

    • 通过注解绑定,就是在接口的方法上面加上 @Select@Update 等注解,里面包含 SQL 语句来绑定;
    • 通过 xml 里面写 SQL 来绑定, 在这种情况下,要指定 xml 映射文件里面的 namespace 必须为接口的全路径名。当 SQL 语句比较简单时候,用注解绑定, 当 SQL 语句比较复杂时候,用 xml 绑定,一般用 xml 绑定的比较多。

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

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

    26.这个 Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗?

    • Dao 接口的工作原理是 JDK 动态代理,MyBatis 运行时会使用 JDK 动态代理为 Dao 接口生成代理 proxy 对象,代理对象 proxy 会拦截接口方法,转而执行 MappedStatement 所代表的 SQL,然后将 SQL 执行结果返回。
    • Dao 接口里的方法是不能重载的,因为是 全限名+方法名 的保存和寻找策略。

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

    • 不同的 Xml 映射文件,如果配置了 namespace,那么 id 可以重复;如果没有配置 namespace,那么 id 不能重复;毕竟 namespace 不是必须的,只是最佳实践而已。
    • 原因就是 namespace + id 是作为 M a p < S t r i n g , M a p p e d S t a t e m e n t > Map Map<String,MappedStatement> 的 Key 使用的,如果没有 namespace,就剩下 id,那么,id 重复会导致数据互相覆盖。有了 namespace,自然 id 就可以重复,namespace 不同,namespace + id 自然也就不同。

    28.简述 MyBatis 的 Xml 映射文件和 MyBatis 内部数据结构之间的映射关系?

    MyBatis 将所有 Xml 配置信息都封装到 All-In-One 重量级对象 Configuration 内部。在 Xml 映射文件中, 标签会被解析为 ParameterMap 对象,其每个子元素会被解析为 ParameterMapping 对象。 标签会被解析为 ResultMap 对象,其每个子元素会被解析为 ResultMapping 对象。每一个