Java框架!聊聊MyBatis的历史

Posted 程序员超时空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java框架!聊聊MyBatis的历史相关的知识,希望对你有一定的参考价值。

原生的mybatis(使用xml)

关于别名

关于namespace

原生的mybatis(使用注解)

Mybatis与spring

MapperFactoryBean

SqlSessionDaoSupport

Mybatis与springBoot

Mybatis与mybatis-plus


序言

==

最近项目中,需要在mysql里面新增一个表,然后套用mybatis做增删改查,然后再mapper.java的方法上写注解。写着写着就感觉很烦,为什么呢?看下面:


@Insert({

        "INSERT INTO " + TABLE_NAME + INSERT_COLUMNS +

            " VALUES" +

            "(#{id},now(),now(),#{idxConfigId},#{userId},#{ownerId},#{status}," +

            " #{ukIdempotent},#{startTime},#{endTime},#{extraInfo}," +

            "  #{awardResult},#{boxConfig},#{currentCount},#{treeId},#{target},#{scope}   )"

    })

int insertFinanceInfo(FarmFinanceInfoDO financeInfoDO);







@Update({ "update "+TABLE_NAME+" set " +

        " idx_config_id = #{idxConfigId}, " +

        " owner_id = #{ownerId},status = #{status}, " +

        " uk_idempotent = #{ukIdempotent}, " +

        " start_time = #{startTime,jdbcType=TIMESTAMP}, " +

        " end_time = #{endTime,jdbcType=TIMESTAMP}, " +

        " current_count = #{currentCount}, " +

        " tree_id = #{treeId},target = #{target}, scope = #{scope}, " +

        " box_config = #{boxConfig},award_result = #{awardResult},  " +

        " extra_info = #{extraInfo} " +

        "  where id = #{id} and user_id= #{userId}" })

int updateFinanceInfo(FarmFinanceInfoDO financeInfoDO);

其实我是特别不喜欢在java文件里写这种很长的注解的,感觉特别乱,我甚至愿意把它放到xml里面。后来在网上搜了一下原来还有一个叫mybatis-plus的组件,看着还不错,然后在应用过程中也发生了一下问题,问题的根源就是自己还是急于求成,直接在网上搜一下现成的不成体系的代码就用,后面自然一堆问题。然后这两天就稍微挤出一点时间,把mybatis的使用,从最开始的原生xml,到注解,到spring,到spring-boot到mybatis-plus的使用都梳理了一遍。

原生的mybatis(使用xml)

=================

POM如下:


 <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->

        <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

            <version>8.0.18</version>

        </dependency>



        <dependency>

            <groupId>org.mybatis</groupId>

            <artifactId>mybatis</artifactId>

            <version>3.5.7</version>

        </dependency>

下面mybatis的配置文件


<?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>



    <!-- 别名 -->

    <typeAliases>

        <package name="entity"/>

    </typeAliases>

    <!-- 数据库环境 -->

    <environments default="development">

        <environment id="development">

            <transactionManager type="JDBC"/>

            <dataSource type="POOLED">

                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>

                <property name="url" value="jdbc:mysql://localhost:3306/test_db?characterEncoding=UTF-8"/>

                <property name="username" value="root"/>

                <property name="password" value="123456"/>

            </dataSource>

        </environment>

    </environments>

    <!-- 映射文件 -->

    <mappers>

        <mapper resource="mapper/user.xml"/>

    </mappers>



</configuration>

下面是某个mapper的配置


<?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="xml">

    <select id="listUser" resultType="user">

        select * from  user;

    </select>

</mapper>

这个mapper里面有个namespace,我一直不知道它是什么意思。没关系这个namespace先随便写,一会就知道它是什么意思了。

增加entity


package entity;



/**

 * @program: parent_pro

 * @description:

 * @author: 渭水

 * @create: 2021/07/21

 */

public class User {

    private int id;

    private String username;

    private String  password;

    private String nickname;

    // 省略getset

}

最后的启动类


package xml;



import entity.User;

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 java.io.IOException;

import java.io.InputStream;

import java.util.List;



/**

 * @program: parent_pro

 * @description:

 * @author: 渭水

 * @create: 2021/07/21

 */

public class MyBatisWithXML {

    public static void main(String[] args) {

        String resource = "mybatis-config.xml";

        InputStream inputStream = null;

        try {

            inputStream = Resources.getResourceAsStream(resource);

        } catch (IOException e) {

            e.printStackTrace();

        }

        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession session = sqlSessionFactory.openSession();

        // 最后通过 session 的 selectList() 方法调用 sql 语句 listStudent

        List<User> userList = session.selectList("listUser");

        for (User student : userList) {

            System.out.println("ID:" + student.getId() + ",NAME:" + student.getUsername());

        }

    }

}

我们看看整个项目个结构图:

数据库那边,我已经建立好了,大家看看:

运行项目就能看到:

OK,至此项目已经可以运行了。

然后我们分析一下代码:

关于别名


一段一段看


<select id="listUser" resultType="user">

        select * from  user limit 5;

</select>

这个里面的resultType,我们不用看框架,大概就懂它指的是把下面的sql语句执行的结果,包装成什么类型。

那么光写个user,mybatis知道这个user是个什么东西么?


<!-- 别名 -->

<typeAliases>

        <package name="entity"/>

</typeAliases>

上面一段代码的语义就是,把entity下面的实体都加一个别名,而别名就是类名。所以mybatis就知道上面的user其实对应的就是entity.User这个类。

关于namespace


上面已经有了一个mapper,我现在再加一个mapper如下:

和之前那个的区别就是一个limit 5,一个limit 10

然后让mybatis的主配置文件感知到这个user2.xml


<!-- 映射文件 -->

<mappers>

        <mapper  resource="mapper/user.xml"/>

        <mapper  resource="mapper/user2.xml"/>

</mappers>

然后运行代码会发现:

说的很清楚listUser这个id重复了。

在线上工程里,要保证所有的sql的id都不重复有点困难,所以引入了namespace的概念。如果一旦有重复的id,那么session调用的时候得指定namespace。


List<User> userList = session.selectList("xml.listUser");

原生的mybatis(使用注解)

================


@Mapper

public interface PersonMapper {



    @Select("select id,name ,age from person where id = #{id}")

    Person getPersonById(int id);



    @Select("<script>"

            +"select * from person where 1=1"

            +"<if test='name2 != null'> and name = #{name2}"   +"</if>"

            +"<if test='age != null'> and age = #{age}"   +"</if>"

            +"</script>")

    List<Person> getList(@Param("name2") String name,@Param("age") String age);



    @SelectProvider(type = UserDaoProvider.class, method = "getPersonByPara")

    Person getPersonByPara(@Param("name")  String name, @Param("age") String age);

} 

如上面所示

调用的时候就直接写


 PersonMapper personMapper = session.getMapper(PersonMapper.class);

        Person result = personMapper.getPersonByPara("渭水","");

        List<Person> list = personMapper.getList(null,"25");

其实,这就回到我在序言里说的了,在java代码里写脚本语言很丑,代码很难读。

我们可以用一个单独的java方法来产生sql语句,如下;


@Mapper

public interface PersonMapper {



    @SelectProvider(type = UserDaoProvider.class, method = "getPersonByPara")

    Person getPersonByPara(@Param("name")  String name, @Param("age") String age);

}





public class UserDaoProvider {



    public String getPersonByPara(Map<String, Object> para) {

        String sql = new SQL() {

            {

                SELECT("id, name, age");

                FROM("person");

                if (StringUtils.isNotBlank("" + para.get("name"))) {

                    WHERE("name='" + para.get("name")+"'");

                }

                if (StringUtils.isNotBlank("" + para.get("age"))) {

                    WHERE("age=" + para.get("age"));

                }

            }

        }.toString();

        System.out.println("----" + sql);

        return sql;

    }

} 

Mybatis与spring

==============

通过上面我们可以看到,不管是用xml配置,还是直接在java文件里写注解,最终都是通过SqlSession 来指向下一步的操作的。

所以,就算我们把mybatis与spring整合,其实核心原理还是依赖SqlSession 的。

第一步,我们先去掉之前的mybatis依赖,改成


<dependency>

  <groupId>org.mybatis</groupId>

  <artifactId>mybatis-spring</artifactId>

  <version>2.0.6</version>

</dependency>

然后在spring的xml里面加上


<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

  <property name="dataSource" ref="dataSource" />

</bean>

dataSource的相关代码我这边就赘述。

然后,具体来说,整合的思路有两种:

MapperFactoryBean


把我们的mapper放到MapperFactoryBean里面

学习分享,共勉

这里是小编拿到的学习资源,其中包括“中高级Java开发面试高频考点题笔记300道.pdf”和“Java核心知识体系笔记.pdf”文件分享,内容丰富,囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。同时还有Java进阶学习的知识笔记脑图(内含大量学习笔记)!

资料都是免费提供的,整理不易,有需要的朋友可以转发分享下,同时可以关注我,定期分享学习资源还会更新一些技术分享!

资料免费领取:点击这里即可免费获取!

整理不易,有需要的朋友转发支持下,感谢感谢!

Java核心知识体系笔记.pdf

中高级Java开发面试高频考点题笔记300道.pdf

架构进阶面试专题及架构学习笔记脑图

Java架构进阶学习视频分享

来说,整合的思路有两种:

MapperFactoryBean


把我们的mapper放到MapperFactoryBean里面

学习分享,共勉

这里是小编拿到的学习资源,其中包括“中高级Java开发面试高频考点题笔记300道.pdf”和“Java核心知识体系笔记.pdf”文件分享,内容丰富,囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。同时还有Java进阶学习的知识笔记脑图(内含大量学习笔记)!

资料都是免费提供的,整理不易,有需要的朋友可以转发分享下,同时可以关注我,定期分享学习资源还会更新一些技术分享!

资料免费领取:点击这里即可免费获取!

整理不易,有需要的朋友转发支持下,感谢感谢!

Java核心知识体系笔记.pdf

[外链图片转存中…(img-T816NIQy-1628135718754)]

中高级Java开发面试高频考点题笔记300道.pdf

[外链图片转存中…(img-d2Wg57yO-1628135718756)]

架构进阶面试专题及架构学习笔记脑图

[外链图片转存中…(img-SIlNOWdA-1628135718758)]

Java架构进阶学习视频分享

[外链图片转存中…(img-7WTUBrSd-1628135718760)]

以上是关于Java框架!聊聊MyBatis的历史的主要内容,如果未能解决你的问题,请参考以下文章

聊聊MyBatis缓存机制

面试必问 | 聊聊MyBatis执行流程?

聊聊Mybatis的日志模块的适配器模式

MyBatis 学习

Mybatis的前世今生

ORM框架的发展历史与MyBatis的高级应用