Mybatis框架

当你看到这里的时候我想我不必再次强调这是一个框架了;

那咱们就来简单的说一下这个Mybatis框架:

首先呢,先提一下前文ORM,为什么要提它,看官您接着往下看:

ORM概述

在使用JDBC 的时候,我们通常将数据直接返回,但现在也会将数据封装到实体类对象中,由对象携带数据。这样操作的时候,可以通过操作对象的方式操作数据。但是手写这类代码通常是繁琐的、重复的,如果有自动完成这些功能的程序就好了。

ORM(Object-Relational-Mapping):是对象关系映射的意思,它是一种思想,是指将数据库中的每一行数据用对象的形式表现出来。可以将 ORM 简单理解为上面我们提出的,可以自动将对象与数据进行映射的技术。

常见ORM框架

Hibernate 完全ORM映射框架

优点

  1. 简化了整个jdbc操作过程

  2. 对于开发者来说不需要关心sql了,只需要去操作对象就可以了,hibernate可以帮我们自动生成所需要的sql

  3. 代码移植性比较好,通过hibernate操作db都是通过操作对象来进行的,而hibernate会根据我们的操作和db的类型生成符合各种db要求的sql,如果我们需要切换db的类型,hibernate会自动适应,对于开发者业务代码来说不需要做任何业务代码上的调整

  4. 开发效率比较高

即使开发人员不知道sql,也能使用Hibernate来完成数据的CRUD的操作

缺点

  1. sql优化比较艰难,各种操作最终发给db的sql是由hibernate自动生成的,对于开发者来说如果想干预最终需要执行的sql,相对来说比较困难

  2. hibernate入门比较容易,但是想成为高手学习成本比较高

  3. 对于复杂的动态sql,代码中也需要写很多判断进行组装,动态sql这块的支持比较欠缺

如果做一些简单的系统,开发周期也比较紧急,对sql的优化要求也不是很高,可以使用hibernate。

JdbcTemplate

jdbctemplate是在spring框架的基础上开发的一个jdbc框架,所以对spring是有依赖的,它对jdbc做了封装,隐藏了各种重复的操作,使用时只需传入:需要执行的sql、参数以及对于结果如何解析的程序就可以了,使用起来还是很方便的,但是面对与动态sql,它也是无能为力了。整体上来说,jdbctemplate相对于纯jdbc隐藏了很多重复性的操作,对于sql的写法和结果的组装上完全交给了开发者自己去控制,在系统中使用也可以帮助我们节约很多时间,而且学习相当简单.

mybatis 是一个半自动的orm框架

MyBatis

MyBatis简介

MyBatis是一个半自动化的orm框架,为什么说是半自动化的呢,因为他需要我们自己去写sql,而他做的更好的地方就是动态sql的支持上面,而上面说的各种技术,面对与动态sql只能自己写很多判断去组装sql,而这些判断和组装在mybatis中实现起来就非常简单了,完全由mybatis去帮我们实现了。mybatis将sql交由开发者去控制,所以在sql的优化方面,开发者可以随心所欲,也就是说mybatis将重复性的工作优化到了极致:操作db的过程、动态sql的拼装、结果和对象的映射,这些mybatis都帮我们实现的很好,而让我们将更多的经历花在sql的写法和优化上面,所以毫无疑问mybatis使用人数和公司也是最多的。

MyBatis 优缺点

  • 优点

    - 简单易学,容易上手(相比于 Hibernate ) : 基于SQL编程
    - 消除了JDBC大量冗余的代码,不需要手动开关连接
    - 很好的与各种数据库兼容(因为 MyBatis 使用JDBC来连接数据库,所以只要JDBC 支持的数据库 MyBatis 都支持,而JDB提 供了可扩展性,所以只要这个数据库有针对Java的jar包就可以就可以与 MyBatis 兼容),开发人员不需要考虑数据库的差异性。
    - 提供了很多第三方插件(分页插件 / 逆向工程)
    - 能够与Spring很好的集成
    - 如果‘使用映射文件’的话,可以让代码和配置文件完全分离。只要方法的定义没有改变,那么只需要修改配置文件就可以达到修改的目的。
  • 缺点

- SQL语句的编写工作量较大,尤其是字段多、关联表多时,更是如此,对开发人员编写SQL语句的功底有一定要求。
- SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库

Mybatis的工作原理

两者相比较:

        通过刚才咱们的介绍,可以简单的看出各自的优劣,那我就简单的说一下两者的主要区别还是在于SQL语句,一个需要写SQL语句一个不需要写SQL语句;

        对于Hibernate 的完全封装而言,不可以对SQL语句进行修改,这从而会导致我们无法对于SQL进行优化,所以Mybatis解决了这一现象,也导致MybatisHibernate 常用。

我们之前在没学矿建,对于数据库的连接都是在使用JDBC,那Mybatis相较于JDBC有那些优化改进或者是优点呢?

Mybatis与传统JDBC的比较(简单说一些让大家看看,有个简单的认识):

减少了60%的代码量

最简单的持久化框架

架构级性能增强

SQL代码从程序代码中彻底分离,可重用

增强了项目中的分工

增强了移植性

Mybatis的工作原理图

首先呢,通过这个图,咱们可以大致的简单了解一下Mybatis的整体工作流程:

它是有一个核心的配置文件(也叫全局配置文件),通过new 一个SqlSessionFactory工厂读取配置文件,获取SqlSession进行增删改查操作,它是通过executor底层执行器,最终是对数据库DB的操作;

光说不练假把式,接下来我就给各位看官快速的写一个流程操作,看清楚了,是快速哦!

首先是配置文件,咱们是最终对数据库的操作,肯定是要连接数据库的,不然还操作干嘛呀,这不就是白干了吗,对吧?

所以咱们得在核心配置文件mybatis.xml中配置连接数据库的操作

<configuration>
    <properties resource="jdbc.properties"></properties>
    <environments default="jsp">
        <environment id="jsp">
            <!-- 使用jdbc的事务,mybatis进行管理 -->
            <transactionManager type="JDBC"/>
            <!-- 使用jdbc的连接池连接数据库 -->
            <!-- 如果配置了<properties resource="db.properties"/> -->
            <!-- value可以使用value="mybatis"的形式进行书写 /> -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 映射文件的配置-->
    <mappers>
        <package name="mapper"/>
    </mappers>
</configuration>
environments这个标签是代表咱们可能在开发中遇到很多数据库,比如:测试、运行等等时要用到的数据库;
default代表是默认连接的数据库,它一定要与你所要使用的id相同,大家可以看到我取的名字是jsp,但不一定非得是这个名字,随便取,但前提是你得记住且不要连错了;

mappers是咱们的映射配置,后面再说

我这里是引用了我自己写的一个jdbc的配置文件jdbc.properties,大家也可以直接把properties这个标签去掉,下面的value写上对应的值。

刚才说到配置核心文件下面就是SqlSessionFactory工厂,这是我自己写的一个类,读取咱们刚刚配置的配置文件,一会我们可以通过调用这个类的方法直接调用这个工厂方法

public class MyBatisUtil {
    private MyBatisUtil() {
    }

    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder()
                    .build(Resources.getResourceAsStream("mybatis.xml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSessionFactory getSqlSessionFactory() {
        return sqlSessionFactory;
    }
}

有人可能会问:为什么要单独写一个类呢,直接写不行吗?

我的回答是:当然可以,但是你有没有想过,咱们每一次都要写吗?这样是不是会造成代码的冗余呢?咱们程序员本身就是要减少一些不必要的操作,所以这次写一个类,到时候想用下次直接调用即可!

前面我也说了,简单快速的写一下,主要是让大家知道mybatis的执行流程,所以后续的我会通过注解和单元测试来快速进行,如果大家还不理解注解和单元测试的话,可以自行了解,过程中我也会简述一下!

因为咱们要将数据库中的数据打印出来,所以我们也要创建相应的实体类

下面就是我创建的一个实体类

import lombok.Data;


@Data
public class User {
    private int uid;
    private String username;
    private String password;
    private String phone;
}

大家看到了,我没有写构造方法,但是我们获取数据是需要有构造方法的,这是因为我引入了注解的功能,可以看到public上方有一个@Data,这就是注解的功能之一,我们不必自行构造方法,像set、get、toString他都帮我们创建了,大家导包一定要看清楚我导的包,引入的是lombok;

然后我们获取,肯定不是我们直接从数据库中粗暴的获取、拿来的吧,我们得通过一些方法,委婉一点,温柔一点,所以我们可以通过接口,接口中我们自己书写的方法来获取

首先我们先来进行查询操作,这是咱们在接口中书写的方法

//查询指定id的数据
    @Select ("select * from user where uid=#{uid}")
    User selectAll(int uid);

这同样也是通过注解的方式,这样我们可以很清晰直白明了的看到SQL语句,而不是去mapper.xml中书写,然后在来回跳转,这样显得十分麻烦和繁琐

在这之前呢,咱们先把工具都准备好,因为已经做好了工厂,下一步就是获取sqlsession,再进行curd操作,那怎样获取呢,请看

 SqlSessionFactory sqlSessionFactory ;
    @Before
    public void start(){
       sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();

    }

创建一个类,不必写main函数,刚才说到单独创建一个类用来获取工厂,所以现在直接可以用MyBatisUtil点方法来获取工厂。@Before表示无论运行那个代码他都会被运行,而且是指其之前运行

    @Test
    public void selectAll(){
        //构建SqlSession对象
        try (SqlSession session = sqlSessionFactory.openSession(true)) {
            //执行sql
            UserMapper mapper = session.getMapper(UserMapper.class);
            User user = mapper.selectAll(1);
            System.out.println(user);
        }
    }

@Test指的就是单元测试,可以单独运行,不必靠main方法

查询的结果如下:

DEBUG [main] - ==>  Preparing: select * from user where uid=? 
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <==      Total: 1
User(uid=1, username=zhangsan, password=123456, phone=138468885889)

这里就可以看到咱们的SQL语句以及传入的参数1,然后进行查询;

咱们看一下数据表:

就是咱们所要查询的uid为1的数据 

一通则百通,接下来就是增加、修改和删除,咱们就一块来看一下吧!

首先是他们接口中书写的方法以及他们的SQL语句:

    //增加数据
    @Insert("insert into user values (#{uid},#{username},#{password},#{phone})")
     void insertStudent(User user);


    //修改数据
    @Update("update user set username=#{username},password=#{password},phone=#{phone} where uid=#{uid}")
    void updateStudent(User user);


    //删除指定id的数据
    @Delete("delete from user where uid=#{uid}")
    void deleteStudent(int uid);

他们的结果分别是:

增加:

DEBUG [main] - ==>  Preparing: insert into user values (?,?,?,?) 
DEBUG [main] - ==> Parameters: 3(Integer), lili(String), 15453(String), 123456(String)
DEBUG [main] - <==    Updates: 1

其中的#{}转变为了占位符,update是影响条数,咱们就增加了一条,所以也就为1;

看一下表是否有变化呢

 

修改:

DEBUG [main] - ==>  Preparing: update user set username=?,password=?,phone=? where uid=? 
DEBUG [main] - ==> Parameters: wing(String), 123456(String), 152003026548(String), 3(Integer)
DEBUG [main] - <==    Updates: 1

修改条数也是为1;

同样看一下表

 

删除:

DEBUG [main] - ==>  Preparing: delete from user where uid=? 
DEBUG [main] - ==> Parameters: 3(Integer)
DEBUG [main] - <==    Updates: 1

 

同样如此,证明咱们并没有报错

写的过于繁多,可能会导致观感,所以就先说这么多,让大家对于mybatis有个简单的认识,后续会继续改进,共勉!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值