Mybatis的介绍和基本使用

news2025/3/1 15:26:22

目录

数据库操作框架的历程

JDBC

Hibernate

JDBCTemplate 

什么是Mybatis

快速搭建Mybatis项目

创建普通的maven项目

导入相关的依赖

创建对应的数据表

创建与表对应的实体类对象

创建对应的Mapper接口

编写配置文件

编写测试类

增删改查的基本操作


数据库操作框架的历程

JDBC

JDBC(Java Data Base Connection,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成.JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序

  • 优点:运行期:快捷、高效
  • 缺点:编辑期:代码量大、繁琐异常处理、不支持数据库跨平台,主要还是代码量太大,搞个驱动,在搞连接,写sql,业务和配置写在一起也很乱

jdbc核心api

  1. DriverManager 获取驱动
  2. Connection 连接数据库的抽象
  3. Statment 执行SQL
  4. ResultSet 数据结果集

Hibernate

  • ORM 对象关系映射
  • object java对象
  • relational 关系型数据
  • mapping 映射

Hibernate 是由 Gavin King 于 2001 年创建的开放源代码的对象关系框架。它强大且高效的构建具有关系对象持久性和查询服务的 Java 应用程序。

Hibernate 将 Java 类映射到数据库表中,从 Java 数据类型中映射到 SQL 数据类型中,并把开发人员从 95% 的公共数据持续性编程工作中解放出来。

Hibernate 是传统 Java 对象和数据库服务器之间的桥梁,用来处理基于 O/R 映射机制和模式的那些对象。

Hibernate 优势

  • Hibernate 使用 XML 文件来处理映射 Java 类别到数据库表格中,并且不用编写任何代码。
  • 为在数据库中直接储存和检索 Java 对象提供简单的 APIs。
  • 如果在数据库中或任何其它表格中出现变化,那么仅需要改变 XML 文件属性。
  • 抽象不熟悉的 SQL 类型,并为我们提供工作中所熟悉的 Java 对象。
  • Hibernate 不需要应用程序服务器来操作。
  • 操控你数据库中对象复杂的关联。
  • 最小化与访问数据库的智能提取策略。
  • 提供简单的数据询问。

Hibernate劣势

  • hibernate的完全封装导致无法使用数据的一些功能。
  • Hibernate的缓存问题。
  • Hibernate对于代码的耦合度太高。
  • Hibernate寻找bug困难。
  • Hibernate批量数据操作需要大量的内存空间而且执行过程中需要的对象太多

JDBCTemplate 

JdbcTemplate针对数据查询提供了多个重载的模板方法,你可以根据需要选用不同的模板方法.如果你的查询很简单,仅仅是传入相应SQL或者相关参数,然后取得一个单一的结果,那么你可以选择如下一组便利的模板方法。

  • 优点:运行期:高效、内嵌Spring框架中、支持基于AOP的声明式事务 ​
  • 缺点:必须于Spring框架结合在一起使用、不支持数据库跨平台、默认没有缓存

什么是Mybatis

MyBatis 是一款优秀的持久层框架/半自动的ORM,它支持自定义 SQL(我没用过hibernate,这个应该没办法自定义sql吧,hibernate那边不怕移植,不用重写sql)、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

优点:

  1. 与JDBC相比,减少了50%的代码量
  2. 最简单的持久化框架,简单易学
  3. QL代码从程序代码中彻底分离出来,可以重用
  4. 提供XML标签,支持编写动态SQL
  5. 提供映射标签,支持对象与数据库的ORM字段关系映射
  6. 支持缓存、连接池、数据库移植....

缺点:

  1. 数据库移植性比较差,如果需要切换数据库的话,SQL语句会有很大的差异

快速搭建Mybatis项目

创建普通的maven项目

导入相关的依赖

<dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.4</version>
        </dependency> 
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>  
    </dependencies>

驱动请按照数据库版本进行对应

MySQL :: MySQL Connector/J 8.0 Release Notes

创建对应的数据表

创建与表对应的实体类对象

Emp.java

public class Emp {
    private Integer id;
    private String username;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    @Override
    public String toString() {
        return "Emp{" +
                "id=" + id +
                ", username='" + username + '\'' +
                '}';
    }
}

创建对应的Mapper接口

EmpMapper.java

public interface EmpMapper {
    // 根据id查询Emp实体
    //@Select("select * from emp where id=#{id}")
    Emp selectEmp(Integer id);
    // 插入
    Integer insertEmp(Emp emp);
    // 更新
    Integer updateEmp(Emp emp);
    // 删除
    Integer deleteEmp(Integer id);
}

编写配置文件

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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--<mapper resource="EmpMapper.xml"/>-->
        <mapper class="cn.tulingxueyuan.mapper.EmpMapper"></mapper>
    </mappers>
</configuration>

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">
<mapper namespace="cn.tulingxueyuan.mapper.EmpMapper">

    <!--根据id查询Emp实体-->
    <select id="selectEmp" resultType="cn.tulingxueyuan.pojo.Emp">
        select * from Emp where id = #{id}
    </select>

    <insert id="insertEmp">
        INSERT INTO
        `mybatis`.`emp` ( `username`)
        VALUES (#{username});
    </insert>

    <update id="updateEmp">
        UPDATE EMP
        SET username=#{username}
        WHERE id=#{id}
    </update>

    <delete id="deleteEmp">
        DELETE FROM emp
        WHERE id=#{id}
    </delete>

</mapper>

编写测试类

MyTest.java

/***
 * MyBatis 搭建步骤:
 * 1.添加pom依赖 (mybatis的核心jar包和数据库版本对应版本的驱动jar包)
 * 2.新建数据库和表
 * 3.添加mybatis全局配置文件 (可以从官网中复制)
 * 4.修改mybatis全局配置文件中的 数据源配置信息
 * 5.添加数据库表对应的POJO对象(相当于我们以前的实体类)
 * 6.添加对应的PojoMapper.xml (里面就维护所有的sql)
 *      修改namespace:  如果是StatementId没有特殊的要求
 *                      如果是接口绑定的方式必须等于接口的完整限定名
 *      修改对应的id(唯一)、resultType 对应返回的类型如果是POJO需要制定完整限定名
 * 7.修改mybatis全局配置文件:修改Mapper
 */
public class MybatisTest {

    SqlSessionFactory sqlSessionFactory;
    @Before
    public void before(){
        // 从 XML 中构建 SqlSessionFactory
        String resource = "mybatis.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    /**
     * 基于StatementId的方式去执行SQL
     *      <mapper resource="EmpMapper.xml"/>
     * @throws IOException
     */
    @Test
    public void test01() {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            Emp emp = (Emp) session.selectOne("cn.tulingxueyuan.pojo.EmpMapper.selectEmp", 1);
            System.out.println(emp);
        }
    }

    /**
     * 基于接口绑定的方式
     *  1.新建数据访问层的接口:  POJOMapper
     *  2.添加mapper中对应的操作的方法
     *      1.方法名要和mapper中对应的操作的节点的id要一致
     *      2.返回类型要和mapper中对应的操作的节点的resultType要一致
     *      3.mapper中对应的操作的节点的参数必须要在方法的参数中声明
     *  3.Mapper.xml 中的namespace必须要和接口的完整限定名要一致
     *  4.修改mybatis全局配置文件中的mappers,采用接口绑定的方式:
     *        <mapper class="cn.tulingxueyuan.mapper.EmpMapper"></mapper>
     *  5.一定要将mapper.xml和接口放在同一级目录中,只需要在resources新建和接口同样结构的文件夹就行了,生成就会合并在一起
     *
     * @throws IOException
     */
    @Test
    public void test02(){
        try (SqlSession session = sqlSessionFactory.openSession()) {
            EmpMapper mapper = session.getMapper(EmpMapper.class);
            Emp emp = mapper.selectEmp(1);
            System.out.println(emp);
        }
    }


    /**
     * 基于注解的方式
     * 1.在接口方法上面写上对应的注解
     *@Select("select * from emp where id=#{id}")
     * 注意:
     *      注解可以和xml共用, 但是不能同时存在方法对应的xml的id
     *
     */
    @Test
    public void test03(){
        try (SqlSession session = sqlSessionFactory.openSession()) {
            EmpMapper mapper = session.getMapper(EmpMapper.class);
            Emp emp = mapper.selectEmp(1);
            System.out.println(emp);
        }
    }

}

增删改查的基本操作

EmpDao.java

public interface EmpDao {
    public Emp findEmpByEmpno(Integer empno);
    public int updateEmp(Emp emp);
    public int deleteEmp(Integer empno);
    public int insertEmp(Emp emp);
}

EmpDao.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 namespace="cn.tulingxueyuan.dao.EmpDao">
    <!--
    select:表示这个操作是一个查询操作
    id表示的是要匹配的方法的名称
    resultType:表示返回值的类型,查询操作必须要包含返回值的类型
    #{属性名}:表示要传递的参数的名称
    -->
    <select id="findEmpByEmpno" resultType="cn.tulingxueyuan.bean.Emp">
        select * from emp where empno = #{empno}
    </select>
    <!--增删改查操作不需要返回值,增删改返回的是影响的行数,mybatis会自动做判断-->
    <insert id="insertEmp">
        insert into emp(empno,ename) values(#{empno},#{ename})
    </insert>
    <update id="updateEmp">
        update emp set ename=#{ename} where empno = #{empno}
    </update>
    <delete id="deleteEmp">
        delete from emp where empno = #{empno}
    </delete>
</mapper>

MyTest.java

public class MyTest {
    SqlSessionFactory sqlSessionFactory = null;
    @Before
    public void init(){
        // 根据全局配置文件创建出SqlSessionFactory
        // SqlSessionFactory:负责创建SqlSession对象的工厂
        // SqlSession:表示跟数据库建议的一次会话
        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void test01() {

        // 获取数据库的会话
        SqlSession sqlSession = sqlSessionFactory.openSession();
        Emp empByEmpno = null;
        try {
            // 获取要调用的接口类
            EmpDao mapper = sqlSession.getMapper(EmpDao.class);
            // 调用方法开始执行
            empByEmpno = mapper.findEmpByEmpno(7369);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
        System.out.println(empByEmpno);
    }

    @Test
    public void test02(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpDao mapper = sqlSession.getMapper(EmpDao.class);
        int zhangsan = mapper.insertEmp(new Emp(1111, "zhangsan"));
        System.out.println(zhangsan);
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void test03(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpDao mapper = sqlSession.getMapper(EmpDao.class);
        int zhangsan = mapper.updateEmp(new Emp(1111, "lisi"));
        System.out.println(zhangsan);
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void test04(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpDao mapper = sqlSession.getMapper(EmpDao.class);
        int zhangsan = mapper.deleteEmp(1111);
        System.out.println(zhangsan);
        sqlSession.commit();
        sqlSession.close();
    }
}

EmpDaoAnnotation.java

public interface EmpDaoAnnotation {

    @Select("select * from emp where id= #{id}")
    public Emp findEmpByEmpno(Integer empno);

    @Update("update emp set ename=#{ename} where id= #{id}")
    public int updateEmp(Emp emp);

    @Delete("delete from emp where id= #{id}")
    public int deleteEmp(Integer empno);

    @Insert("insert into emp(id,user_name) values(#{id},#{username})")
    public int insertEmp(Emp emp);

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/360977.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

魔兽世界服务端端新手搭建教程

明杰也是很久以前开始研究魔兽服务器架设&#xff0c;主要原因是亚服经常要排队6-7个小时&#xff0c;去不排除的服和单机没啥区别&#xff0c;以怀旧服玩到10级以后就开始玩335端&#xff0c;一开始也和新入手的人一样云里雾里的&#xff0c;经过长时间的学习总算有点成就,向新…

三次握手四次挥手详细解析面试常问

文章目录1.第2次握手传回了ACK&#xff0c;为什么还要传回SYN&#xff1f;2.断开连接-TCP 四次挥手3.为什么要四次挥手&#xff1f;4.为什么不能把服务器发送的 ACK 和 FIN 合并起来&#xff0c;变成三次挥手&#xff1f;5.如果第二次挥手时服务器的 ACK 没有送达客户端&#x…

从零实现深度学习框架:Seq2Seq从理论到实战【理论篇】

来源&#xff1a;投稿 作者&#xff1a;175 编辑&#xff1a;学姐 往期内容&#xff1a; 从零实现深度学习框架1&#xff1a;RNN从理论到实战&#xff08;理论篇&#xff09; 从零实现深度学习框架2&#xff1a;RNN从理论到实战&#xff08;实战篇&#xff09; 从零实现深度…

RabbitMQ之Work Queues

Work Queues 工作队列(又称任务队列)的主要思想是避免立即执行资源密集型任务,而不得不等待它完成。相反我们安排任务在之后执行。我们把任务封装为消息并将其发送到队列。在后台运行的工作进程将弹出任务并最终执行作业。当有多个工作线程时,这些工作线程将一起处理这些任务…

Spring:五、编程式事务

Spring&#xff1a;五、编程式事务 1 前言 spring支持声明式和编程式事务&#xff0c;因spring事务基于AOP&#xff0c;使用cglib作为代理&#xff0c;为父子类继承的代理模式&#xff0c;故而声明式事务Transactional中&#xff0c;常见事务失效的场景&#xff0c;如方法内自…

基于UIAutomation+Python+Unittest+Beautifulreport的WindowsGUI自动化测试框架common目录解析

文章目录1 框架工具说明2 技术栈说明3 框架截图4 源码解析/common目录4.1 common/baseinfo.py4.2 common/creenShot.py4.3 common/logOut.py4.4 common/reportOut.py4.5 common/sendMail.py注&#xff1a; 1、本文为本站首发&#xff0c;他用请联系作者并注明出处&#xff0c;谢…

从源码中探究React中的虚拟DOM

引文 通过本文你将了解到 什么是虚拟DOM&#xff1f;虚拟DOM有什么优势&#xff1f;React的虚拟Dom是如何实现的&#xff1f;React是如何将虚拟Dom转变为真实Dom&#xff1f; 一、概念 虚拟DOM实际上是一种用来模拟DOM结构的javascript对象。当页面变化的时候通过一种算法来…

美国拟发布纽扣电池或硬币电池安全标准和通知要求ANSI C18. 3M

2023年2月10日&#xff0c;美国向WTO提交G/TBT/N/USA/1964号通报&#xff0c;拟发布纽扣电池或硬币电池以及含有此类电池的消费品的安全标准和通知要求&#xff0c;征求意见截止日期为2023年3月13日&#xff0c;拟通过日期和生效日期待定。联[1]系 拟定规则通知根据H.R.5313瑞…

微服务保护之sentinel熔断器

文章目录 目录 文章目录 前言 一、解决微服务雪崩的问题 二、使用步骤 三、熔断器的使用 3.1 限流规则 3.1.1流控模式 3.1.2流控效果 3.2 隔离和降级 3.2.1 隔离 3.2.2 降级 四、sentinel规则持久化 总结 前言 在基于 SpringCloud 构建的微服务体系中&#xff0c;服务间的调用…

宝塔搭建实战人才求职管理系统mobile手机端vue源码(五)

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 上一期给大家分享骑士cms会员管理member前端vue在本地运行打包、宝塔发布部署的方式&#xff0c;本期给大家分享&#xff0c;mobile移动端vue怎么在本地运行&#xff0c;打包&#xff0c;实现线上功能更新替换的方…

南卡和wiwu电容笔哪款更值得入手?开学季电容笔推荐

在如今科技飞速发展的时代&#xff0c;数码产品层出不穷&#xff0c;尤其是电容笔。最近一段时间&#xff0c;电容笔非常受欢迎&#xff0c;很多人们都会使用电容笔来搭配平板电脑&#xff0c;不管在学习上或者工作上都随处可见。而随着电容笔的种类越来越多&#xff0c;人们对…

墨菲安全参与信息通信软件供应链安全社区成员大会并获自主研发创新成果奖

2023年2月16日&#xff0c;首届ICT软件供应链安全治理论坛暨信息通信软件供应链安全社区第二届成员大会在北京成功举办&#xff0c;多位业界顶级专家与工业和信息化部网络安全管理局相关领导出席&#xff0c;为现场观众分享了关于软件供应链可持续性与安全治理行业的前瞻与思考…

ICLR 2023|VLDet:从图像-文本对中学习区域-词语对齐的开放词汇式目标检测

原文链接&#xff1a;https://www.techbeat.net/article-info?id4614&isPreview1 作者&#xff1a;林闯 目标检测任务在AI工业界具有非常广泛的应用&#xff0c;但由于数据获取和标注的昂贵&#xff0c;检测的目标一直被限制在预先设定好的有限类别上。而在学术界&#xf…

2023最新软件测试面试题(带答案)

1. 请自我介绍一下(需简单清楚的表述自已的基本情况&#xff0c;在这过程中要展现出自信&#xff0c;对工作有激情&#xff0c;上进&#xff0c;好学) 面试官您好&#xff0c;我叫###&#xff0c;今年26岁&#xff0c;来自江西九江&#xff0c;就读专业是电子商务&#xff0c;毕…

OpenGL学习日记之模型绘制

自己编译运行过程中遇到的一些问题 下载Assimp已编译的lib(因为我们公司的电脑有很多权限和限制&#xff0c;也不能自己安装一些没有报备的软件&#xff0c;所以愁方便我就没有用cMake自己编译了)找到一位免费分享的博主的。 https://blog.csdn.net/lady_killer9/article/deta…

聊聊8万8的私董会,很扎心

聊聊8万8的私董会&#xff0c;很扎心 道几句真心话&#xff0c;很扎心&#xff0c;但也很现实。 如果你喜欢刷抖音&#xff0c;这种感觉应该会更加明显。 股市哀鸿遍野&#xff0c;实体一地鸡毛&#xff0c;我们办公室楼下的门面换了一波又一波。 别说那些不起眼的小生意&a…

第48章 抽离Axios拦截守及其全局变量定义

1 准备工作 1.1 重构src\store\index.js import { createStore } from vuex; export default createStore({ state: { //通过该全局变量&#xff0c;获取全局化存储的1个指定用户的令牌字符串。 token: localStorage.getItem(Token) ? localStorage.getItem(Token) : , //通…

CHAPTER 3 Web Server - httpd配置(二)

Web Server - httpd配置二3.1 httpd配置3.1.1 基于用户的访问控制3.1.2 basic认证配置示例&#xff1a;1. 添加用户2. 添加网页文件3. 定义安全域4. 修改父目录权限5. 访问效果6. 在配置文件中定义一个".htaccess"隐藏文件7. 添加组3.1.3 虚拟主机1. 构建方案2. 基于…

Storage

WebStorage主要提供了一种机制&#xff0c;可以让浏览器提供一种比cookie更直观的key、value存储方式&#xff1a; localStorage&#xff1a;本地存储&#xff0c;提供的是一种永久性的存储方法&#xff0c;在关闭掉网页重新打开时&#xff0c;存储的内容依然保留&#xff1b;…

TCP/IP网络协议族分成及其每层作用

1、可以分为应用层、传输层、网络层、链路层 2、各层的作用 应用层(可以想象成是快递打包过程) 决定了向用户提供应用服务时通信的活动&#xff0c;将要进行的操作或者数据进行一个打包。 传输层&#xff08;可以理解为选择顺丰、圆通等快递公司&#xff09; 提供数据传输的方…