A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 梦想飞翔的猪 于 2018-2-1 17:42 编辑

【石家庄校区】总复习系列贴-mybatis

Mybatis简介      

MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

Mybatis架构

1、  mybatis配置
       SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。

mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

2、  通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂

3、  由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

4、  mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。

5、  Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象, sql的id即是Mapped statement的id。

6、  Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。

7、  Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

Mybatis与hibernate的区别

Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。
Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。

Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。

加载Mapper.xml的方式
      原始Dao开发     原始dao开发方法需要程序员编写Dao接口和Dao实现类。使用方法  
     Xml配置
[XML] 纯文本查看 复制代码
  <?xml version="1.0"  encoding="UTF-8" ?>
  <!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD  Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  <mapper  namespace="test">
  <!-- 根据id获取用户信息 -->
         <select  id="findUserById" parameterType="int"  resultType="cn.itcast.mybatis.po.User">
                select  * from user where id = #{id}
         </select>
  </mapper>


       Dao配置:
[Java] 纯文本查看 复制代码
  Public interface UserDao {
         public  User getUserById(int id) throws Exception;
         public  void insertUser(User user) throws Exception;
  }
       DaoImpl配置:
[Java] 纯文本查看 复制代码
  Public class UserDaoImpl implements  UserDao {
  
         //注入SqlSessionFactory
         public  UserDaoImpl(SqlSessionFactory sqlSessionFactory){
                this.setSqlSessionFactory(sqlSessionFactory);
         }
  
         private  SqlSessionFactory sqlSessionFactory;
         @Override
         public  User getUserById(int id) throws Exception {
                SqlSession  session = sqlSessionFactory.openSession();
                User  user = null;
                try  {
                       //通过sqlsession调用selectOne方法获取一条结果集
                       //参数1:指定定义的statement的id,参数2:指定向statement中传递的参数
                       user  = session.selectOne("test.findUserById", 1);
                       System.out.println(user);
  
                }  finally{
                       session.close();
                }
                return  user;
         }
  }


缺点

原始Dao开发中存在以下问题:

   Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法

   调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不得于开发维护。

Mapper动态代理方式开发规范

Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper接口开发需要遵循以下规范:

1、  Mapper.xml文件中的namespace与mapper接口的类路径相同。

2、   Mapper接口方法名和Mapper.xml中定义的每个statement的id相同

3、  Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同

4、  Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

5、 mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。

配置使用UserMapper.xml

定义mapper映射文件UserMapper.xml(内容同Users.xml),需要修改namespace的值为 UserMapper接口路径。将UserMapper.xml放在classpath 下mapper目录 下。

[XML] 纯文本查看 复制代码
 <?xml version="1.0"  encoding="UTF-8" ?>[/p]<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
<!-- 根据id获取用户信息 -->
    <select id="getUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">
       select *  from user where id = #{id}
      </select>
  </mapper>

Dao接口接口定义有如下特点:
1、  Mapper接口方法名和Mapper.xml中定义的statement的id相同
2、  Mapper接口方法的输入参数类型和mapper.xml中定义的statement的parameterType的类型相同
3、  Mapper接口方法的输出参数类型和mapper.xml中定义的statement的resultType的类型相同
[Java] 纯文本查看 复制代码
/**
* 用户管理mapper
*/
Public interface UserMapper {
    //根据用户id查询用户信息
    public User findUserById(int id) throws Exception;
  
}

加载UserMapper.xml

修改SqlMapConfig.xml文件:

[XML] 纯文本查看 复制代码
<!-- 加载映射文件 -->[/p]  <mappers>
    <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
SqlMapConfig.xml配置说明配置内容
  SqlMapConfig.xml中配置的内容和顺序如下:
  
  properties(属性)
  settings(全局配置参数)
  typeAliases(类型别名)
  typeHandlers(类型处理器)
  objectFactory(对象工厂)
  plugins(插件)
  environments(环境集合属性对象)
  environment(环境子属性对象)
  transactionManager(事务管理)
  dataSource(数据源)
  mappers(映射器)

Mapper.xml详解
Namespace
[XML] 纯文本查看 复制代码
  <mapper  namespace="cn.itheima.mybatis.mapper.OrderMapper"></mapper>
  <!-- namespace是命名空间,作用sql语句的隔离。namespace用于绑定dao接口的,即面向接口编程。-->
ResultMap      一对一
[XML] 纯文本查看 复制代码
		 <resultMap type="orders"  id="order_user_resultmap">
  <!--type:resultMap对应的pojo类型 假如不配置别名,必须使用全路径名,配置后可使用类名,不区分大小写  -->
  <!--resultMap中的id  为当前Map的id,方便查询语句调用 -->
                <id  property="id" column="id"/>
           <!--property为pojo的属性名称,pojo必须提供get、set方法 。column为属性对应的数据库字段列-->
                <result  property="userId" column="user_id"/>
                <result  property="number" column="number"/>
                <result  property="createtime" column="createtime"/>
                <result  property="note" column="note"/>
                <!--  配置一对一关联映射 -->
                <!--  property:对于orders中user的属性.javaType:代表user属性的数据类型-->
                <association  property="user" javaType="cn.itheima.mybatis.po.User">
                       <id  property="id" column="user_id"/>
                       <result  property="username" column="username"/>
                       <result  property="address" column="address"/>
                </association>
         </resultMap>

一对多
[XML] 纯文本查看 复制代码
<!-- 一对多关联映射 -->
         <resultMap  type="user" id="user_order_resultmap">
                <id  property="id" column="id"/>
                <result  property="username" column="username"/>
                <result  property="birthday" column="birthday"/>
                <result  property="sex" column="sex"/>
                <result  property="address" column="address"/>
                <!--  配置一对多关联映射 -->
                <!--  property:对于user对象中的集合属性  -->
                <!--  ofType:集合中每个元素的数据类型 -->
                <collection  property="orders" ofType="orders">
                       <!--  id对于order的主键属性 -->
                       <id  property="id" column="oid"/>
                       <result  property="number" column="number"/>
                       <result  property="createtime" column="createtime"/>
                       <result  property="note" column="note"/>
                </collection>
         </resultMap>



0 个回复

您需要登录后才可以回帖 登录 | 加入黑马