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

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


Mybatis是什么?

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。


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。


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包都导入项目后,才可以正式开始。

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文件,代码如下:

<?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类,代码如下:

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接口编程。

转载于:https://my.oschina.net/u/4000133/blog/3013841

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值