SSM框架开发web项目系列(二) MyBatis真正的能力

  前言

  上篇SSM框架环境搭建篇,演示了咱开展web开发必不可少的有些部署和准备工作,假诺登时下面尚发生问号的地点,能够先行参考达一致篇“SSM框架开发web类别体系(一)
环境搭建篇
”。本文重要介绍MyBatis的功底内容,包括基本概念、开发步骤、使用实例等。说于MyBatis,工作遭到开过SSH/SSM相关Web开发的要么在学习MyBatis的总人口如故多或者少都会晤硌到类似“MyBatis和Hibernate有什么区别?”,“MyBatis和Hibernate哪个还好?”,“为何Mybatis用底口更是多?”等等…记得面试题目,区别问的最为多,有不良给面试官问到再也爱用啊一个?明明已经精通这店介绍用之凡SSM了,我报了个Hibernate,并说先用的也是Hibernate,或许初恋的痛感过于深切吧…何人好什么人差这种主观性问题,大家不冲突,但是不容质疑之是五头都为商家级支做出巨大进献。同时,带在问题及求知欲去上学累会为修功效大大提升,因为众多题材在纳闷你的以,也也您带了样子。就刚刚而你得会就此它们,领悟她了,才晓得它于某面怎么会相差。

  MyBatis介绍

  早些时候,Apache有一个开源项目iBatis,后来改名了被Mybatis,所以大家于网上偶然会看有的初期的篇章有时候看到iBatis,其实是与一个物。同时,大家好看下MyBatis源码工程协会,如下图,也会觉察此题材。

 图片 1

  MyBatis是一个半自动-ORM-持久层框架,下边分别介绍就三独概念,假若了然之底可以从来跨越了因为节省时间。

  首先持久层相比好明,就是指向数据库的各个操作持久化层面,大家由此jdbc也可以针对数据库中表举办增删可查;WEB开发分层结构面临,类似的还有业务层、控制层,MyBatis所召开用的重叠,首假若用来和数据库打交道。

  其次ORM(Object Relational Mapping,对象关系映射)是同种技术,也是思考,即便就此了jdbc的原生情势操作数据的当还知,其中各类获取与换代的操作都曾起相关的API了,然而这进程实际上太繁琐,获取连接、构造语句、发送SQL和接收数据、最终是处理数量以及关闭流等等…实际的劳作出中,分明不绝适用。也许是有人想到,最辛劳的地点在获取数据后底处理过程,为了简化这同一过程,以Java中面向对象的想结构了就一个ORM关系模型,即每张数据表对应一个Java类,数据表中列一样漫漫记下分别针对应Java类的一个实体对象,数据表中每个字段对应Java类中之一个属性,那样一来Java中整都对象,数据库里之事物既已针对性应映射到Java概念遭到来,大家更就此面向对象的想去操作数据库,就大大简化了开销流程。

  最后,解释半电动,既然暴发活动,应该就发全自动,例如Hibernate就是一个自行的ORM持久层框架,它在创建数据库和bean对象关联映射模型的又,提供的api还会援救我们自动生成和殡葬SQL语句去操作数据库,而MyBatis略有不同,它呢创立了对象关联映射模型,不过连无相会拉大家生成SQL语句,需要我们协调写SQL语句,不少口或许碰面认为别人都得帮忙你自动生成了即还要自己写,不是没事找事吗?不过恰恰相反,很两人口因这一点好上了MyBatis,灵活且透明,自己出手不解释。

  MyBatis紧要对象

  关于MyBatis的习运用过程遭到,依次要留心的季只目的来SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper实例。

  1.SqlSessionFactoryBuilder

  SqlSessionFactoryBuilder是一个近似,里面定义许多重载的build方法,通过build方法可落SqlSessionFactory对象,即SqlSession工厂实例

  2.SqlSessionFactory

  SqlSessionFactory是一个接口,看名字应该能领会是SqlSession工厂,里面定义了成百上千重载的openSession方法,用于取SqlSession对象

  3.SqlSession

  SqlSession是一个大重要之接口,通过它们我们得以履发送SQL语句、拿到Mapper实例等等。以她的第一独艺术为条例,
<T> T selectOne(String
statement);
方法名很轻了解,获取数据表的同样久记下(在Java中对许返一个实体类对象),后面的泛型对应的就是是实体类的门类,关于String类型的参数statement,用了原生的JDBC操作数据库的应有不碰面生,在运用JDBC过程中,有个Statement对象,通过该对象的接近 ResultSet executeQuery(String sql) throws SQLException;
等措施能够发送SQL语句,方法里的字符串类型参数 sql
就是大家只要发送的sql语句,而前的String
statement
同样也是表示大家的sql语句如上所述,selectOne中之statement代表sql语句,JDBC中的statement是可以发送sql语句之目标实例,不可混淆。

  4.Mapper实例

  Mapper实例就是我们在dao层定义之概念之接口实例,咱们当service层中注入dao对象时涉嫌的凡该接口名,而实在大家得到了拖欠接口实例也便是Mapper实例。而我辈于web开发进程被,持久层的相关措施都定义在Mapper接口中,所以多只目的里大家当后边环境搭建篇正如便于觉察的也就是以此Mapper实例所属接口,即PersonMappr接口。Mapper实例可以透过SqlSession的getMapper方法得到。

  MyBatis配置文件

  图片 2

  以上也MyBatis配置文件下节点的布局分布图,熟悉DTD的遵照org/apache/ibatis/builder/xml下的封锁文件mybatis-*-config.dtd为可以赢得XML规范。

  environment(环境)

  以出中,大家只要连接受数据库,往往还亟需配置一个数据源,其中囊括数据库url参数,用户名和密码等等,另外还有事事务管理器配置。MyBatis中也未例外,在此处针对一个数据库的接连,有一个environment(环境)与之对应,假使生多独数据库,我们可以当environments下定义六个environment。environment下边通过dataSource和transactionManager的property属性举行数据源和事务管理器部署。

  typeAliases(类型命名)

  这么些是开发被酷实用的部署,前边配置篇中mybatis-config.xml中之<typeAlias alias=”person” type=”com.mmm.pojo.Person” />,给类绑定别名,然后在另外地点引用时好不用写类的真名(类似com.xxx.Xxx格局),直接写别名即可,例如前边personMapper.xml映射文件被<resultMap
type=”person” id=”personResultMap”
>,这里的person别叫就象征此类了,假如无前的别名绑定,我们以颇具需要种type指定com.mmm.pojo.Person的时刻,都急需写全名。另外MyBatis中自既绑定了成千上万接近的别名,在Configuration类的协会中曾经先期登记绑定了系别名,这也是大家在用Spring集成开发之布局文件中那一个特殊别名能博取解析的关键所在,如下所示

public Configuration() {
   
    typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
    typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
  
    typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
    typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
    typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);
   
    typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);
    typeAliasRegistry.registerAlias("FIFO", FifoCache.class);
    typeAliasRegistry.registerAlias("LRU", LruCache.class);
    typeAliasRegistry.registerAlias("SOFT", SoftCache.class);
    typeAliasRegistry.registerAlias("WEAK", WeakCache.class);
  
    typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class);

    typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class);
    typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class);

    typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);
    typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class);
    typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);
    typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);
    typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);
    typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);
    typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);

    typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);
    typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class);

    languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class);
    languageRegistry.register(RawLanguageDriver.class);
  }

  mappers(映射器)

<mappers>
        <mapper resource="com/xxx/xxx/mapper/xxxMapper.xml" />
</mappers>

  以上就是为一个映射器配置体制,通过该配置,Mybatis会找到呼应的SQL映射文件(前边环境搭建篇中呢personMapper.xml),下面详细介绍SQL映射文件。

  MyBatis真正的力量

  The true power of MyBatis is in the Mapped
Statements(MyBatis真正的力便在SQL映射语句里)。这是MyBatis对SQL映射文件作介绍的第一词话,足以展现这一个紧要,前边说到之自发性的MyBatis需要协调写SQL语句,这么些写SQL语句之地点即当这里。

图片 3

  清节点mapper有一个属性namespace(命名空间),对应之是Mapper接口的姓名,通过那一个属于性值的装,MyBatis才会找到该SQL映射文件对象Mapper接口,从而构造相应的Mapper实例对象。  

  以上为MyBatis的SQL映射xml文件之素结构,子节点中还有一个parameterMap,不过都为吐弃了,就没有画上。前面四只,看单词意思,应该不难明白,分别用于定义增删改查SQL语句。下边坐询问<select>为条例

<!-- 根据主键id查找记录 -->
<select id="selectById" resultType="person">
        select * from `TBL_PERSON` where id = #{id}
</select>    

  下边select节点中id为该节点的唯一标识,与其它节点区分,另一方面,id名对应我们的Mapper接口中之艺术名,在这里对应PersonMapper的如下方法:

//根据主键id查找Person对象
Person selectById(String id);

  由于是询问,会发返数据内容,基于ORM思想,这里的T_PERSON表重回记录有一个实体类和的相应,那么具体指向承诺哪个实体类怎么指定?这里的resultType即指定再次来到数据对应品种,并且用到了号,所以那里其实就是点名了com.mmm.pojo.Person类作为对应实体类。此外还有一样种resultMap定义形式,也堪指定再次回到路,两者不可知而且利用,上边会实际说到。倘若艺术无回来值,也足以免点名项目。

  节点受到之言语即为该办法对应之SQL语句,那里的#{id}表示参数,对许PersonMapper接口中针对诺方法的参数String
id。

   其它两种植<delete><updata><insert>类似,不过假若小心,<insert>作为插入节点,有几乎只奇特性能,useGeneratedKeys、keyProperty、keyColumn,这三独属性都是<insert>特有的,也唯有对这行,keyProperty属性指定数量表主键值对应之实业类属性,这里呢Person类中的id;keyColumn属性指定数据表主键字段名,这里为id;useGeneratedKeys指定是否动数据表主键策略生成的主键值,例如当Mysql中主键可以装自增,然后我们当插入记录(或者说是写SQL语句)时,即使不指定主键值,插入也会晤马到成功,并且主键会自行赋值。为了因显示区别,文中构建示例我会面采取MySQL的自增主键,而不是在此之前的妄动字符串作为主键。

  <sql>被用来定义可选拔的SQL代码段,可以蕴涵在另外语句中。

  再来拘禁<resultMap>,从前的Person实例中,数据表的字段名和实业类属性名都是一模一样的,id,name,gender。假设无平等的话,大家重新采用前的写法就会合爆发题目了,resultMap给我们提供了解决办法,下边我们由此总体构建一个Mybatis环境来演示全体内容。

  MyBatis实践

  这里我们单独讲Mybatis,并未采纳Spring集成环境,也远非就此到web层的Spring
MVC,所以不欲构建web项目。所以率先通过maven新建一个java项目,pom.xml看重可以参见前的SSM环境搭建,最终项目结构大体上如下图所示

图片 4

  数据库被准备同摆员工表TBL_EMP,七只字段:主键id自增,姓名emp_name,性别emp_gender,插入若干数额,如下图

图片 5

  实体类(Emp.java)

package com.mmm.pojo;
//员工实体类
public class Emp {
    private Integer id;            //主鍵
    private String name;        //员工姓名
    private String gender;        //员工性别

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
}

  配置文件(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>
    <!-- 这里可以定义类的别名,在mapper.xml文件中应用会方便很多 -->
    <typeAliases>
        <typeAlias alias="emp" type="com.mmm.pojo.Emp" />
    </typeAliases>
    <!-- 环境配置 -->
    <environments default="envir">
        <environment id="envir">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/ssm?characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/mmm/mapper/empMapper.xml"/>
    </mappers>
</configuration>

  Mapper接口(EmpMapper.java)

package com.mmm.mapper;

import java.util.List;

import com.mmm.pojo.Emp;

public interface EmpMapper {

    //新增一个Emp对象
    void insert(Emp p);

    //根据主键id删除Emp对象
    void deleteById(Integer id);

    //修改一个Emp对象
    void update(Emp p);

    //根据主键id查找Emp对象
    Emp selectById(Integer id);

    //查找所有Emp对象,返回集合类型
    List<Emp> selectAll();
}

  SQL映射文件(EmpMapper.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">

<!-- namespace命名空间绑定Mapper接口 -->
<mapper namespace="com.mmm.mapper.EmpMapper">

    <!-- resultMap定义,property对应实体类中属性,column对应数据表字段名 -->
    <resultMap type="emp" id="empResultMap" >
        <id property="id" column="id"></id>
        <result property="name" column="emp_name"></result>
        <result property="gender" column="emp_gender"></result>
    </resultMap>

    <!-- 新增一条记录,这里并未在SQL语句中设置主键id值 -->
    <insert id="insert" parameterType="emp" useGeneratedKeys="true" keyProperty="id" keyColumn="id"  >
        insert into `TBL_EMP`(emp_name,emp_gender) values (#{name},#{gender})
    </insert>

    <!-- 删除一条记录 -->
    <delete id="deleteById">
        delete from `TBL_EMP` where id = #{id}
    </delete>

    <!-- 更新一条记录 -->
    <update id="update" parameterType="EMP">
        update `TBL_EMP` set emp_name = #{name}, emp_gender = #{gender}
    </update>

    <!-- 查找所有记录 -->
    <select id="selectAll" resultMap="empResultMap">
        select * from `TBL_EMP`
    </select>

    <!-- 根据主键id查找记录 -->
    <select id="selectById" resultMap="empResultMap">
        select * from `TBL_EMP` where id = #{id}
    </select>
</mapper>

  测试(TestMyBatis.java)

package com.mmm.test;

import java.io.IOException;
import java.io.Reader;
import java.util.List;

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 org.junit.Test;

import com.mmm.mapper.EmpMapper;
import com.mmm.pojo.Emp;

public class TestMyBatis {



    @Test
    public void testCore() throws IOException {
        //直接实例SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //MyBatis配置文件路径
        String path = "mybatis-config.xml";
        //通过路径获取输入流
        Reader reader = Resources.getResourceAsReader(path);
        //通过reader构建sessionFactory
        SqlSessionFactory sessionFactory = builder.build(reader);
        //获取SqlSession对象
        SqlSession sqlSession = sessionFactory.openSession();
        //获取Mapper实例
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);

        //获取所有记录并遍历展示
        List<Emp> list = mapper.selectAll();
        for(Emp emp:list) {
            System.out.println("姓名:"+emp.getName()+",性别:"+emp.getGender());
        }

    }
}

  运行程序成,结果如下

图片 6

  小结

  本文首要介绍了单身为MyBatis构建数据库访问程序的主意步骤,涉及的且是MyBatis基础和主导之始末,数据库也是对的单表操作。MyBatis的涉查询、动态SQL、事务管理和Spring集成MyBatis等情节准备梳理一番了以后写出来。

网站地图xml地图