java框架学习日志-13(Mybatis基本概念和简单的例子)

在mybatis初次学习Mybatis的时候,遇到了不少问题,虽然阿里云的视频有教学,可是视频教学所使用的软件和我本身使用的软件不用,我本身用的数据库是oracle数据库,开发环境是idea。并且视频中只是将mybatis这一部分抽出来说,实际上还须要一些知识储备,我自己是了解了oralce基本的操做后,再开始学习Mybatis的,过程可能会走不少弯路,和遇到不少不理解或者理解错误的地方,如今暂时只能囫囵吞枣,等有必定了解后,再回头看看,总结和更改个人一些认知。java


Mybatis是什么?mysql

mybatis是基于java持久层的框架,持久层就是把业务数据存储到硬盘,在断电或者重启系统后,仍然能够读取这些数据。就好像玩游戏须要保存进度同样,否则每次都须要重头开始玩。java互联网能够经过mybatis框架访问数据库。程序员


没有Mybatis以前怎么访问数据库?
在早期,若是须要访问oracle数据库,须要专门写一个程序,若是访问mysql,又须要专门写一个程序,后来就有了jdbc(Java DataBase Connectivity,java数据库链接),jdbc是一种用来执行sql语句的java api,能够为多种数据库提供统一的访问。简单来讲,它能够与数据库创建链接,发生操做数据库的语句,处理结果。可是jdbc的工做量也是很大的,并且很很差用,因此出现了ORM(Object relational Mapping,对象关系映射 ),咱们把POJO对象和数据库表相互映射的框架称为ORM,mybatis和hibernate都是ORM框架,并且由于mybatis对jdbc的封装很好,并且很灵活,因此几乎能够彻底取代jdbc。sql


Mybatis的优势
mybatis有三个优势:数据库

  1. 不屏蔽SQL,这样能够更加精肯定位SQL语句,能够对其进行优化和改造。
  2. 提供更强大灵活的映射机制。知足了常常变换的互联网应用的要求。
  3. 提供了使用Mapper的接口编程,简化了工做。

除了mybatis,还有其余框架,好比Hibernate,hibernate与mybatis一样是java持久层的框架,均可以经过注解或者xml提供映射规则。可是hibernate不须要编写SQL就能够经过映射关系去操做数据库,这样程序员不须要精通SQL,只须要操做POJO(Plain Ordinary Java Object,简单的java对象)就能够操做对应的数据库的表了,可是这也是缺点,当多表关联超过3个,hibernate的性能就会丢失,而mybatis能够自定义SQL,映射关系,因此,他比hibernate更加灵活。可是mybatis也有缺点,由于须要编写SQL和映射规则,因此工做量比hibernate多。因此若是系统对性能要求不高时,能够实用hibernate,若是对性能要求高可使用mybatis。apache


Mybatis的核心组件
首先先了解mybatis的核心组件有哪些,而后再去了解这些组件的做用和实现原理。mybatis的核心组件分为4个部分:编程

  • SqlSessionFactoryBuilder(构造器)——它会根据配置或者代码生成SqlSessionFactory。
  • SqlSessionFactory(工厂接口)——用来生成SqlSession。
  • SqlSession(会话)——既能够发送SQl并执行返回结果,也能够获取Mapper的接口。
  • SQL Mapper(映射器)——MyBatis新设计存在的组件,由一个java接口和XML文件(或者注解)构成。须要给出对应的SQL和映射规则。负责发送SQL,并返回结果。

Mybatis的配置
开始配置以前,须要准备Mybatis环境,我使用的mybatis版本是3.5.0.而后导入相关jar包。
既然用的mybatis,固然须要mybatis的核心jar包,和lib文件下的jar包,以下图:


由于链接的是oracle数据库,因此还须要oracle的jar包,个人地址是:H:\app\zheng\product\12.2.0\dbhome_1\jdbc\lib
jar包都导入项目后,才能够正式开始。c#

1. 建立SqlSessionFactory

首先获取一个SqlSessionFactory,,Mybatis提供了SqlSessionFactoryBuilder来生成SqlSessionfactory,能够经过XML配置文件或者java代码去生成SqlSessionFactory。这里建议用XML来生成SqlSessionFactory,由于代码的方式会在须要修改的时候比较麻烦。
在mybaits中,由于这是基础配置文件(XML有两类,一类是基础配置文件,主要是配置上下文参数和运行环境,下面的XML就是基础配置文件,另外一类就是映射文件,后面会用到),因此取名mybaits.cfg.xml。mybatis说明文档中XML代码以下:

大部分地方复制过来就能够了,只须要改一下数据源的配置,driver填OracleDriver这个驱动器类的全限定名。url的写法有多种,username,password就是链接数据库用的用户,和密码,这里就不详细说明了。 <mappers>元素表明引入哪些映射器,咱们后面会用新建一个叫product.mapper.xml的映射文件。因此这里写上这个映射文件。稍微改一下XML文件,代码以下:api

<?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>
    <environments default="development"><!--配置环境-->
        <!--数据库环境-->
        <environment id="development"><!--环境变量-->
            <transactionManager type="JDBC"/><!--事物管理器-->
            <dataSource type="POOLED"><!--数据源-->
                <property name="driver" value="oracle.jdbc.OracleDriver"/>
                <property name="url" value="jdbc:oracle:thin:@//DESKTOP-997L86A:1521/orcl"/>
                <property name="username" value="c##scott"/>
                <property name="password" value="tiger"/>
            </dataSource>
        </environment>
    </environments>
    <!--映射文件-->
    <mappers>
        <mapper resource="product.mapper.xml"/>
    </mappers>
</configuration>

而后是去生成SqlSessionFactory了。说明文档中写了能够用下面的代码去生成SqlSessionFactory:

固然这里也须要改一下,把resource换成本身刚才写的XML文件就好了。而后我是把这个方法写在一个getSqlSessionFactory静态方法里面的,这样能够方法生成SqlSessionFactory。新建MyBatisUtil类,代码以下:session

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 MyBatisUtil {
    public static SqlSessionFactory getSqlSessionFactory() throws IOException {

        String resource = "mybatis.cfg.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        return sqlSessionFactory;

    }
}
1. 建立SqlSession

而后是建立SqlSession,有了SqlSessionFactory后,建立SqlSession就很简单了,一行代码就能够,咱们一样把它写在一个静态方法里面,和上面的getSqlSessionFactory()方法放在一块儿。代码以下:

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 MyBatisUtil {
    public static SqlSessionFactory getSqlSessionFactory() throws IOException {

        String resource = "mybatis.cfg.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        return sqlSessionFactory;

    }
    public static SqlSession getSqlSession() throws IOException {
        SqlSessionFactory sqlSessionFactory=getSqlSessionFactory();
        return sqlSessionFactory.openSession();
    }
}
1. 建立映射器

以前说过,mybatis中XML有两类,一个是以前写的基础配置文件,还有一个就是接下来的映射器文件。映射文件能够用XML或者注解实现,这里咱们一样推荐使用XML实现,由于若是同时使用XML和注解定义的话,XML会覆盖掉注解方式。并且当Sql语句比较复杂时,使用注解方式也会下降可读性,灵活性也不如XML。
映射器的主要就是将SQL查询到的结果映射为一个POJO,或者将POJO的数据插入数据库,因此须要先定义一个POJO。
这是用来测试的Testtable表格,只有一个id和名字。

对应的POJO:

public class Testtable {
    private Integer id;
    private String name;

    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;
    }
}

用XML定义映射器分为两个部分:接口和XML。我在看视频的时候,老师一开始是没有讲接口的,因此这里就先不使用接口来建立映射器。那么在有了POJO后,只须要配置一下XML文件就能够实现映射器了。product.mapper.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="ProductMapper">
    <select id="selectTesttable_id" parameterType="int" resultType="Testtable">
        select * from Testtable where id = #{id}
    </select>
    <select id="selectTesttable_name" parameterType="String" resultType="Testtable">
        select * from Testtable where name = #{id}
    </select>
</mapper>

<mapper namespace="ProductMapper">所使用的是接口的全限定名,由于没有接口,因此这里随便写。
<select>元素就是代表查询语句了,id标识哪一条SQL。
parameterType是传递进去的参数类型,好像不写也能够。
resultType是返回类型。
#{id}表示传递进去的参数。
我这里写了两条SQL语句,分别是查询条件为id的selectTesttable_id,和查询条件为name的selectTesttable_name。Mybatis提供自动映射,能够把SQl返回的列名和POJO对应起来,


使用SqlSession发送sql
有了映射器后,就能够经过SqlSession发送SQL了。代码以下:

import org.apache.ibatis.session.SqlSession;

import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {

        SqlSession sqlSession=MyBatisUtil.getSqlSession();//获取SqlSession
        Testtable testtable1=sqlSession.selectOne("ProductMapper.selectTesttable_id",003);//使用ProductMapper配置文件下的selectTesttable_id语句,查询条件为where id = 003
        Testtable testtable2=sqlSession.selectOne("ProductMapper.selectTesttable_name","菜刀");//使用ProductMapper配置文件下的selectTesttable_name,查询条件为where name = ‘菜刀’
        System.out.println("id="+testtable1.getId()+"名字="+testtable1.getName());
        System.out.println("id="+testtable2.getId()+"名字="+testtable2.getName());
        sqlSession.close();//关闭资源。

    }
}

查询结果以下

selectOne方法有两个参数,一个String对象,和一个Object对象,String是由命名空间加SQL id组成的。由此来肯定惟一一条SQL语句,Object由以前的<select>元素中的parameterType肯定的。 selectOne方法会返回一个Testtable类型的对象,书中用了转换:

Testtable testtable1=(Testtable)sqlSession.selectOne("ProductMapper.selectTesttable_id",003);

可是实际上不用转换,能够直接使用。
注意必定要sqlSession.close();关闭资源,若是不关闭,数据库的链接资源很快就会耗费逛,整个系统就会陷入瘫痪。这就是直接用SqlSession发送SQL语句,接下来使用SqlSession去获取Mapper接口,经过Mapper接口发送语句。


使用Mapper接口发送sql
既然使用Mapper接口发送语句,那么就须要先定义一个映射器接口。代码以下

public interface TesttableMapper {
    public Testtable selectTesttable_id(int id);
}

这个方法的名字就是SELECT语句id的名字,参数就是#{id}。
修改product.mapper.xml文件里的<mapper namespace="ProductMapper">,改为新建的接口名。<mapper namespace="TesttableMapper">
测试代码以下:

TesttableMapper testtableMapper=sqlSession.getMapper(TesttableMapper.class);
        Testtable testtable3=testtableMapper.selectTesttable_id(002);
        System.out.println("id="+testtable3.getId()+"  名字="+testtable3.getName());
        sqlSession.close();


注意TesttableMapper这个接口是没有实现类的,可是mybatis运用了动态代理技术,为这个接口生成了一个代理对象。使得接口也能运行起来。


两种发送sql的方式的区别 使用Mapper发送SQl能够提升可读性,更能体现业务逻辑testtableMapper.selectTesttable_id(002)的写法也更符合面向对象的语言。并且使用Mapper,IDE会提示报错。Sqlsession去发生SQL语言只会在运行期间报错。如今基本上都是使用Mapper接口编程。

相关文章
相关标签/搜索