对Mybatis框架的理解

来源:互联网 发布:怎样备份电脑软件 编辑:程序博客网 时间:2024/05/08 02:31

说起对象关系映射框架,大家首先想到的肯定是Hibernate。Hibernate作为一个著名的框架,功能十分强大。我们只需要配置好实体类和数据表之间的关系,Hibernate就会自动帮我们完成生成并执行SQL语句,映射结果集这样的工作。但正是由于Hibernate如此强大的功能,导致了它的缺点:

1、Hibernate非常笨重,启动Hibernate的SessionFactory非常耗时,开销巨大;

2、Hibernate配置复杂,学习成本较高,系统调优也不容易;

3、Hibernate自定义查询功能较弱,查询结果如果不是映射的实体类,查询起来就比较麻烦。

因此另一个ORM框架MyBatis,越来越流行。

一、MyBatis原理
        MyBatis应用程序根据XML配置文件创建SqlSessionFactory,SqlSessionFactory再根据配置,配置来源于两个地方,一处是配置文件,一处是Java代码的注解,获取一个SqlSession。SqlSession包含了执行sql所需要的所有方法,可以通过SqlSession实例直接运行映射的sql语句,完成对数据的增删改查和事务提交等,用完之后关闭SqlSession。

二、MyBatis的优缺点
优点:

1、简单易学
       MyBatis本身就很小且简单。没有任何第三方依赖,安装只要两个jar文件+配置几个sql映射文件就行了,易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。 
2、灵活
       MyBatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
3、解除sql与程序代码的耦合
       通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
4、提供映射标签,支持对象与数据库的orm字段关系映射 
5、提供对象关系映射标签,支持对象关系组建维护
6、提供xml标签,支持编写动态sql。
缺点:
1、编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。
2、SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。
3、框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。 
4、二级缓存机制不佳

总结:

MyBatis的优点同样是MyBatis的缺点,正因为MyBatis使用简单,数据的可靠性、完整性的瓶颈便更多依赖于程序员对sql的使用水平上了。sql写在xml里,虽然方便了修改、优化和统一浏览,但可读性很低,调试也非常困难,也非常受限。

三、MyBatis的使用

1、jar包引入(使用Maven项目管理工具构建)


<!-- mybatis核心包 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency><!-- mybatis/spring包 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>${mybatis-spring.version}</version></dependency>
2、配置mybatis-config.xml

<configuration>      <settings>                  <!-- 全局映射器启用缓存 -->          <setting name="cacheEnabled" value="true" />                  <!-- 查询时,关闭关联对象即时加载以提高性能 -->          <setting name="lazyLoadingEnabled" value="true" />                  <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指定),不会加载关联表的所有字段,以提高性能 -->          <setting name="aggressiveLazyLoading" value="false" />                  <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->          <setting name="multipleResultSetsEnabled" value="true" />                  <!-- 允许使用列标签代替列名 -->          <setting name="useColumnLabel" value="true" />                  <!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->          <setting name="useGeneratedKeys" value="true" />                  <!-- 给予被嵌套的resultMap以字段-属性的映射支持 -->          <setting name="autoMappingBehavior" value="FULL" />                  <!-- 对于批量更新操作缓存SQL以提高性能  -->          <setting name="defaultExecutorType" value="BATCH" />                  <!-- 数据库超过25000秒仍未响应则超时 -->          <setting name="defaultStatementTimeout" value="25000" />      </settings>  </configuration>
3、创建SqlSessionFactory

有了mybatis-config.xml配置文件,我们就可以开始使用MyBatis了。首先要做的事情是创建MyBatis的SqlSessionFactory,它和Hibernate的SessionFactory类似,是主要的工厂类,一个应用程序中只需要创建一个即可。

public abstract class MyBatisUtils {    private static volatile SqlSessionFactory sqlSessionFactory;     public static final String MyBatisConfigLocation = "mybatis-config.xml";     public static SqlSessionFactory getSqlSessionFactory() throws IOException {        if (sqlSessionFactory == null) {            synchronized (MyBatisUtils.class) {                if (sqlSessionFactory == null) {                    InputStream input = Resources.getResourceAsStream(MyBatisConfigLocation);                    sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);                    input.close();                }            }        }        return sqlSessionFactory;    }}
4、映射文件

具体的业务代码忽略,这里主要讲一下Mybatis的映射文件:

映射文件主要包含SQL语句,可以执行各种各样的sql。每一条语句都需要一个标识符,将会在后面的代码中用到。如果是查询语句还需要resultType,指定返回类型。MyBatis会将数据表列明和这里指定的类型属性按名称自动映射起来。如果需要在语句中传入参数,可以使用 parameterType属性,指定Java实体类的全名或简写,然后就可以在SQL语句中使用#{}来访问参数的属性了。如果是简单的映射,那么parameterType属性还可以省略,MyBatis会自动从传入的Java对象中获取相应的属性。对于某些数据库(例如MySQL),还可以在插入的时候指定useGeneratedKeys="true",让数据库自动生成主键。

<!-- namespace和定义的Mapper接口对应,并实现其中的方法 --><mapper namespace="com.audTest.mapper.admin.menu.MenuMapper">    <resultMap type="com.audTest.admin.menu.entity.Menu" id="menuResultMap">        <id column="id" property="id"/>        <result column="name" property="name"/>        <result column="code" property="code"/>            </resultMap>        <select id="findMenuByUserid" resultType="List" resultMap="menuResultMap">    SELECTmenu.*from web_r_user uinner JOIN web_r_user_role ur on u.id = ur.useridINNER JOIN web_r_role role on ur.roleid = role.idinner join web_r_role_menu rm on role.id=rm.roleidinner join web_r_menu menu on rm.menuid = menu.id where userid=#{userid}    </select></mapper>
5、还可以使用映射类XXMapper来构建sql语句

public interface TestMapper {@Select("select a.*,concat(b.province,b.city,b.county) location from test a inner join info.areainfo b on a.code=b.code 
limit ${page.startIndex},${page.pageSize}")public ArrayList<Test> findAll(@Param("page")PageResponse page) throws Exception;}

1 0
原创粉丝点击