MyBatis —— 初窥门径

news2024/11/26 10:41:32

前言

        MyBatis作为一款优秀的持久层框架,在Java后端开发中无疑是比较重要一环,在常见的spring整合的SSM框架以及之后的SpringBoot中都可以看到MyBatis大显神威的模样。在这篇文章中,荔枝将会从Maven开启创建一个MyBatis项目并整理MyBatis相应的配置和模板的设定。


文章目录

前言

一、MyBatis概述与环境搭建

1.1 MyBatis与其它持久层技术的对比

1.2 通过Maven开启一个MyBatis项目

1.2.1 构建核心配置文件 

environments标签

typeAliases:设置类型别名

mapper:可以以包为单位来引入映射文件

1.2.2 构建映射文件

1.2.3 mapper层接口

1.2.4 实体类文件

1.3 MyBatis项目测试

1.4 查询功能

1.5 优化:借助properties文件存放数据库连接数据

二、MyBatis核心配置文件模板设置和工具类封装

2.1 设置核心配置文件的模板 

2.2 封装用来获取MyBatis连接数据库时的会话对象的工具类  

三、MyBatis获取参数值

3.1 获取参数值的两种方式

3.2 MyBatis获取五种类型的参数值

3.2.1 单个字面量类型

3.2.2 多个字面量参数

3.2.3 手动将参数存储在一个map集合中

3.2.4 实体类参数

3.2.5 使用@param注解来命名参数

总结


一、MyBatis概述与环境搭建

        我们知道在Java后端项目中通过JDBC的API来执行数据库的操作,JDBC中不仅需要提供访问数据库的API,还需要封装与各种数据库服务器通信的步骤,这个过程无疑会有较多的冗杂的操作,而MyBatis框架的出现无疑很好地解决了这个问题。MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集,它是一个半自动ORM框架。

1.1 MyBatis与其它持久层技术的对比

JDBC

  • SQL夹杂在到ave代码中耦合度高,导致硬编码内伤
  • 维护不易且实际开发需求中SQL有变化,需要频繁修改,代码冗长,开发效率低

Hibernate和JPA

  • 操作简便,开发效率高
  • 内部自动生产的SQL,不容易做特殊优化,程序中的长难复杂SQL需要绕过框架
  • 基于全映射的全自动框架,大量字段的POJO进行部分映射时比较困难。
  • 反射操作太多,导致数据库性能下降

1.2 通过Maven开启一个MyBatis项目

        我们常说的配置文件,其实就是核心配置文件+映射文件,其中核心配置文件主要是有关数据库的整体配置以及响应的映射文件的引入,其中映射文件的名字最好和mapper接口的名称保持一致。

        在之前的Java web中我们通过Dao层来实现后端中有关数据库的操作,其中dao层包含了接口层以及接口所对应的实现类,在springMVC中或者说是mybatis中我们将其分为mapper层和pojo层,mapper层其实就相当于dao接口层。

1.2.1 构建核心配置文件 

<?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="mappers/UserMapper.xml"/>
    </mappers>
</configuration>

environments标签

environments:配置多个连接数据库的环境,在使用的时候只会使用一个,default属性值设置默认使用的数据库环境的id

transactionManager:设置事务管理方式,type:JDBC | MANAGE

  • JDBC:表示在执行sql中采用的是JDBC中原生的事务管理方式,事务提交需要手动
  • MANAGE:被管理,比如Spring

dataSource:配置数据源

属性:type:设置数据源的类型

           type="POOLED | UNPOLLED | JNDI"

  • POOLED:使用数据库连接池缓存数据库连接
  • UNPOOLED:不使用数据库连接池
  • JNDI:表示使用上下文的数据源 

MyBatis核心配置文件的顺序

properties -> settings -> typeAliases -> typeHandlers -> objectFactory -> objectwrapperFactory -> refLectorFactory -> plugins -> environments -> databaseIdProvider -> mappers

typeAliases:设置类型别名

类型别名不区分大小写,如果不使用alias声明别名,默认是实体类的类名作为别名。

<!--设置类型别名-->
<typeAliases>
    <typeAlias type="com.crj.pojo.User" alias="User"/>
</typeAliases>

以包为单位设置类型别名

<typeAliases>
    <package name="com.crj.pojo"/>
</typeAliases>

mapper:可以以包为单位来引入映射文件

以包为单位引入映射文件要求:

  • 1.mapper接口所在的包要与映射文件所在的包一致
  • 2.mapper接口要和映射文件的名字一致

<mappers>
    <package name="com.crj.mybatis.xml"/>
</mappers>

1.2.2 构建映射文件

<?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="com.crj.mapper.UserMapper">
<!--    int insertUser();-->
    <insert id="insertUser">
        insert into t_user values(null,'admin','123456',23,'男','12345@qq.com')
    </insert>
</mapper>

1.2.3 mapper层接口

package com.crj.mapper;

public interface UserMapper {
    /**
     * 添加用户功能
     */
    int insertUser();
}

需要注意的是:这里需要保证MyBatis面向接口编程的两个一致

  1. 映射文件xx.xml中mapper标签下的namespace中的属性值要保证和其对应的mapper接口的全类名一致;
  2. 映射文件中的SQL语句中的id要保证和mapper接口中的方法名一致;

1.2.4 实体类文件

package com.crj.pojo;
//实体类
public class User {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private String sex;
    private String email;
//    有参构造
    public User(Integer id, String username, String password, Integer age, String sex, String email) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.age = age;
        this.sex = sex;
        this.email = email;
    }
//    无参构造
    public User() {

    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", email='" + email + '\'' +
                '}';
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

 根据项目的路径在核心配置文件中引入映射文件:

1.3 MyBatis项目测试

SqlSession:代表Java程序和数据库之间的会话

SqlSessionFactory:是生产SqlSession对象的工厂函数,这是一种工厂模式

package com.crj.mtbatis;

import com.crj.mapper.UserMapper;
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 org.junit.Test;

import java.io.IOException;
import java.io.InputStream;

public class test {
    @Test
    public void testMyBatis() throws IOException {
        //加载核心配置文件:通过核心配置文件的名字以一个字节输入流的方式
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //获取SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //获取SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        //获取Mybatis操作数据库的会话对象SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取mapper接口实现类对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        //测试功能,增删改的返回值是受影响的函数
        int result = mapper.insertUser();
        System.out.println("result:"+result);
        
        //提交事务
        sqlSession.commit();
    }
}

sqlSession.getMapper()方法采用代理模式返回一个接口的实例化对象。

开启自动提交仅需要在openSession方法中配置autoCommit为true即可,这样就无需再手动提交事务了。

SqlSession sqlSession = sqlSessionFactory.openSession(true);

1.4 查询功能

mapper接口

/**
* 查询所有的用户信息
*/
List<User> getAllUser();

映射文件

<!--    List<User> getAllUser();-->
    <select id="getAllUser" resultType="com.crj.pojo.User">
        select * from t_user
    </select>

测试类 

 //查询所有的用户信息
    @Test
    public  void testAll() throws IOException {
        //加载核心配置文件:通过核心配置文件的名字以一个字节输入流的方式
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //获取SqlSessionFactoryBuilder对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //获取Mybatis操作数据库的会话对象SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取mapper接口实现类对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> list = mapper.getAllUser();
        list.forEach(user-> System.out.println(user));
    }

需要注意的是当查询的时候我们通常在映射文件中配置好resultType的属性值并将相应的实体类的全类名作为属性值,同时在声明接口的时候需要注意采用相应的数据结构。

1.5 优化:借助properties文件存放数据库连接数据

创建一个资源绑定文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456

 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>
    <!--声明使用的数据文件properties-->
    <properties resource="jdbc.properties"/>
    <!--配置连接数据库的环境-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--引入映射文件-->
    <mappers>
        <mapper resource="mappers/UserMapper.xml"/>
    </mappers>
</configuration>

二、MyBatis核心配置文件模板设置和工具类封装

2.1 设置核心配置文件的模板 

打开IDEA中的setting,找到Editor下的File and Code Templates并新建一个demo模板mybatis-config.xml

 设置模板名和后缀,并将模板配置文件的内容复制在内容框中即可。

之后右键新建一个mybatis核心配置文件的模板试试:

同样的方法可以用来设置一个mybatis的映射文件

2.2 封装用来获取MyBatis连接数据库时的会话对象的工具类  

package com.crj.utils;

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;

/**
 * 该工具类封装了获取mybatis操作数据库连接时的会话对象的一个方法
 * 之后通过sqlSession这个数据库会话对象SqlSession的getMapper()方法来获取接口并自动获得该接口的实现类
 * 通过调用mapper接口中声明的方法来实现增删改的操作
 */
public class SqlSessionUtils {
    public static SqlSession getSqlSession(){
        SqlSession sqlSession = null;
        try {
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            sqlSession = sqlSessionFactory.openSession(true);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return sqlSession;
    }
}

三、MyBatis获取参数值

3.1 获取参数值的两种方式

和JDBC类似,MyBatis获取参数值的两种方式:${}和#{}

  • ${ }:本质是字符串拼接,缺点是比较复杂并且容易造成SQL注入
  • #{ }:本质是占位符赋值,推荐的使用方式是这种

3.2 MyBatis获取五种类型的参数值

3.2.1 单个字面量类型

两种方式获取单个字面量类型参数值

<select id="getUserByUserName" resultType="User">
    select * from t_user where username = #{username}
    select * from t_user where username = '${username}'
</select>

3.2.2 多个字面量参数

mapper接口方法在获取到多个参数时,Mybatis会将所有的参数放在一个map集合中并采用两种方式的键值对的形式进行存储。 

<!--    User checkLogin(String username,String password);-->
    <select id="checkLogin" resultType="User">
        select * from t_user where username = #{arg0} and password = #{arg1}
        select * from t_user where username = #{param1} and password = #{param2}
    </select>

3.2.3 手动将参数存储在一个map集合中

<!--    User checkLoginByMap(Map<String,Object> map);-->
    <select id="checkLogin" resultType="User">
        select * from t_user where username = #{username} and password = #{passsword}
    </select>
@Test
public void testCheckLoginByMap(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    Map<String,Object> map = new HashMap<>();
    map.put("username","admin");
    map.put("password","admin");
    User user = mapper.checkLoginByMap(map);
}

3.2.4 实体类参数

<!--    int insertUserByMap(User user);-->
    <insert id="insertUserByMap">
        insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
    </insert>

3.2.5 使用@param注解来命名参数

User checkLoginByParam(@Param("username") String username,@Param("password") String password);

总结

        总结一下,在这篇文章中荔枝主要记录了有关MyBatis项目环境的基本配置以及相应的模板设置,以及有关MyBatis获取参数值两种方式以及五种情况,掌握后我们就算是基本入门了。在接下来的文章中,荔枝将会继续将梳理有关MyBatis的相关知识比如动态SQL以及SpringBoot项目如何整合MyBatis框架进行开发,继续加油吧~~~

今朝已然成为过去,明日依然向往未来!我是小荔枝,在技术成长的路上与你相伴,码文不易,可以举起小爪爪点个赞哈哈哈~~~ 比心心♥~~~

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

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

相关文章

服务器放在香港好用吗?

​  相较于国内服务器&#xff0c;将网站托管在香港服务器上最直观的好处是备案层面上的。香港服务器上的网站无需备案&#xff0c;因此更无备案时限&#xff0c;购买之后即可使用。 带宽优势 香港服务器的带宽一般分为香港本地带宽和国际带宽、直连中国骨干网 CN2三种。香港…

函数注解学习

def hanshuzhujie(a:str,b: str m)->str:print(hanshuzhujie.__annotations__)return ab hanshuzhujie(qqq)运营结果 E:\Python\Python38\python.exe D:/pythonprojects/python-auto-test/test/hanshuzhujie.py {a: <class str>, b: <class str>, return: <…

生态项目|Typus如何用Sui特性制作动态NFT为DeFi赋能

对于许多人来说&#xff0c;可能因其涉及的期权、认购和价差在内的DeFi而显得晦涩难懂&#xff0c;但Typus Finance找到了一种通过动态NFT使体验更加丰富的方式。Typus NFT系列的Tails为用户带来一个外观逐渐演变并在平台上提升活动水平时获得新特权的角色。 Typus表示&#x…

AI时代,GPGPU和NPU哪个才是王者?

AI飞速发展&#xff0c;全球算力井喷&#xff0c;我国进入AI计算高速发展阶段&#xff0c;GPU的自主化已经摆上案头。近日&#xff0c;华夏银行首席信息官吴永飞发表研究&#xff0c;指出GPGPU是比NPU更合适的路线&#xff0c;并以海光DCU为基础进行了GPU算力池化的研究。 GPG…

无涯教程-Android - List View函数

Android ListView 是垂直滚动列表中显示的视图&#xff0c;使用 Adapter 从列表(如数组或数据库)中获取内容的列表项会自动插入列表中。 适配器(Adapter)实际上是UI组件和将数据填充到UI组件中的数据源之间的桥梁&#xff0c;适配器保存数据并将数据发送到适配器视图&#xff0…

说说我最近筛简历和面试的感受。。

大家好&#xff0c;我是鱼皮。 都说现在行情不好、找工作难&#xff0c;但招人又谈何容易&#xff1f;&#xff01; 最近我们公司在招开发&#xff0c;实习社招都有。我收到的简历很多&#xff0c;但认真投递的、符合要求的却寥寥无几&#xff0c;而且都是我自己看简历、选人…

【ES6】Proxy的高级用法,实现一个生成各种 DOM 节点的通用函数dom

下面的例子则是利用get拦截&#xff0c;实现一个生成各种 DOM 节点的通用函数dom。 <body> </body><script>const dom new Proxy({}, {get(target, property) {return function(attrs {}, ...children) {const el document.createElement(property);for …

路由转发(详细理解+实例精讲)

系列文章目录 华为数通学习&#xff08;5&#xff09; 目录 华为数通学习&#xff08;5&#xff09; 前言 一&#xff0c;最长匹配原则 实例1&#xff1a; 实例2&#xff1a; 二&#xff0c;路由转发流程&#xff1a; 三&#xff0c;IP路由表小结&#xff1a; 总结 前…

公司新招了一个拿14K的测试员,而我工作3年才8K,凭什么?

最近我的好朋友给我分享了一个他公司发生的事&#xff0c;大概的内容呢就是&#xff1a;公司一位工作3年的测试员的工资还没有一个刚来的新人高&#xff0c;对此怨气不小&#xff0c;她来公司辛辛苦苦三年&#xff0c;三年内迟到次数都不超过5次&#xff0c;每天都是按时上下班…

WebGPT VS WebGPU

推荐&#xff1a;使用 NSDT编辑器 快速搭建3D应用场景 随着WebGPU的引入&#xff0c;Web开发发生了有趣的转变&#xff0c;WebGPU是一种新的API&#xff0c;允许Web应用程序直接访问设备的图形处理单元&#xff08;GPU&#xff09;。这种发展意义重大&#xff0c;因为 GPU 擅长…

如何买期权看多:期权交易技巧指南,一定要看!

首先我们要清楚在50ETF期权中有两个角色&#xff0c;分别是买方和卖方&#xff0c;两者互为对手方&#xff0c;买方也就是散户&#xff0c;卖方可以理解为机构&#xff0c;认购是看多&#xff0c;认沽是做空。下文介绍如何买期权看多&#xff1a;期权交易技巧指南&#xff0c;一…

理解 Databend Cluster key 原理及使用

Databend Cluster Key 是指 Databend 可以按声明的 key 排序存储&#xff0c;主要用于用户对时间响应比较高&#xff0c;同时愿意为这个 cluster key 进行额排序操作的用户。 Databend 只支持一个 Cluster key&#xff0c;Cluster key中可以包含多列及表达式。 基本语法 -- 语…

恒运资本:股票有认购和申购区别?

股票是一个非常复杂的金融概念&#xff0c;涉及到许多术语和概念&#xff0c;其间包含股票认购和股票申购。这两个概念是股票出资中非常重要的一部分&#xff0c;出资者需求了解它们的差异和使用方法&#xff0c;才干更好地进行股票出资。 认购和申购的界说 首要&#xff0c;咱…

嬴图Ultipa | 一文了解关于图数据库的一点儿干货

本篇包括以下内容点&#xff1a; 数据库主要技术分类 图是什么&#xff1f; 图的模式 图数据库 VS.关系型数据库 图数据库VS.其他NOSQL的对比 并非所有的图数据库都一样&#xff01; 根据Gartner预测&#xff0c;“到2025年&#xff0c;使用图技术进行数据和分析创新…

多个开源姿态检测模型项目,上手即用,实测可行!

编辑&#xff1a;OAK中国 项目来源&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ ▌前言 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是助手君。 我发现今年有不少朋友都想做姿态检测&#xff0c;正好我们也有不少客户做过这…

概念解析 | 认知媒介战:重塑信息战争的新纪元

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:认知媒介战。 认知媒介战:重塑信息战争的新纪元 俄乌网络战争观察与思考:混合战争及其背后的信息战- 安全内参| 决策者的网络安全知识库 一、背景介绍 认知媒介战是一个新…

tsmc12nm innovus加endcap失败的原因分析

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 重新create floorplan时加了flip first row就加上了endcap&#xff0c;所以一些情况下设置core2die也可以解决这个问题。 physical only的cell&#xff0c;endcap是要先加的&a…

零知识证明(zk-SNARK)(一)

全称为 Zero-Knowledge Succinct Non-Interactive Argument of Knowledge&#xff0c;简洁非交互式零知识证明&#xff0c;简洁性使得运行该协议时&#xff0c;即便statement非常大&#xff0c;它的proof大小也仅有几百个bytes&#xff0c;并且验证一个proof的时间可以达到毫秒…

Nature:AI新技术助力面部瘫痪患者思维交流

通过使用人工智能&#xff08;AI&#xff09;增强的脑机植入物&#xff0c;已经实现了两名瘫痪患者以前所未有的准确度和速度进行交流。 脑机接口将参与者的大脑信号转换为动画的语音和面部动作。来源&#xff1a;Noah Berger 在分别发表于8月23日的《Nature》&#xff08;IF20…

C语言:指针的运算

一、指针 或 - 整数 指针 或 - 整数表示指针跳过几个字节&#xff08;具体跳过几个字节由指针类型决定&#xff09; 本文不做具体讲解&#xff0c;详解跳转链接&#xff1a; 《C语言&#xff1a;指针类型的意义》 二、指针 - 指针 前提条件&#xff1a;指针类型相同并且指向同…