百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

mybatis概述、初体验、配置文件详解、dao层mapper动态代理

ztj100 2024-12-04 17:13 14 浏览 0 评论

1、概述

MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

1.1MyBatis的jar包

要使用 MyBatis, 只需将 mybatis-x.x.x.jar 文件置于 classpath 中即可。

如果使用 Maven 来构建项目,则需将下面的 dependency 代码置于 pom.xml 文件中:

<!-- 添加mybatis依赖 -->
<dependency> 
  <groupId>org.mybatis</groupId> 
<artifactId>mybatis</artifactId> 
<version>3.2.8</version>
</dependency>

1.2.MyBatis的功能架构:

我们把Mybatis的功能架构分为三层:

· API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。

· 数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。

· 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

1.3.MyBatis的优缺点

优点:

· 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件(一个mybatis的jar,一个连接数据库的jar)+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。

· 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。

· 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。

· 提供映射标签,支持对象与数据库的orm字段关系映射

· 提供对象关系映射标签,支持对象关系组建维护

· 提供xml标签,支持编写动态sql。

缺点:

· 当你使用mybatis编写SQL语句时工作量很大,尤其是字段多、关联表多时,sql语句超级复杂,更是如此。

· SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。

· 框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。

· 二级缓存机制不佳

2、初体验mybatis程序

2.1 创建一个Maven项目

1、导入Mybaits依赖

<!--lombok插件(可选,这里为了方便使用了)-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.20</version>
    <scope>provided</scope>
</dependency>
<!--junit 测试 (必选,测试程序使用)-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>
<!--mysql驱动包 (必选,连接MySQL数据库使用)-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.35</version>
</dependency>
<!-- 添加mybatis依赖 (必选,mybatis框架jar包)-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.2.8</version>
</dependency>
<!--日志 (可选,日志jar,这是为了方便查看日志,选择了)-->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
    <scope>test</scope>
</dependency>

2、创建实体类

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
@Data//get set
@Accessors(chain = true)//链式写法
public class MpUser {
    private Integer uid;
    private String uname;
    private String usex;
    private String uphone;
}

3、数据库表

DROP TABLE IF EXISTS `mp_user`;
CREATE TABLE `mp_user` (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `uname` varchar(256) DEFAULT NULL,
  `usex` varchar(20) DEFAULT NULL,
  `uphone` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

INSERT INTO `mp_user` VALUES ('1', 'A', 'M', '1111111');

4、接口和实现类

import com.bean.MpUser;
public interface MpUserDao {
    //根据id查询信息
    MpUser lookUserById(Integer uid);
}
import com.bean.MpUser;
import com.dao.MpUserDao;
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;

public class MpUserDaoImpl implements MpUserDao {
    @Override
    public MpUser lookUserById(Integer uid) {
        MpUser mpUser=null;
        try {
            //1.读取mybatis主配置文件
            InputStream inputStream = Resources.getResourceAsStream("Mybatis-config.xml");
            //2.创建SqlSessionFactory对象
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //3.创建SqlSession对象
            sqlSession = sessionFactory.openSession();
            //4、执行查询
            mpUser=sqlSession.selectOne("lookUserById",1);
            //5、事务提交
            sqlSession.commit();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        return mpUser;
    }
}

5、Mybatis主配置文件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">
<!--注意下面的配置顺序environments、mappers-->
<configuration>
<!--这里default设置当前使用的配置-->
    <environments default="prod">
        <environment id="prod">
            <!--使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域-->
            <transactionManager type="JDBC"/>
            <!--使用数据池,复用实例-->
            <dataSource type="POOLED">
                <!--<property name="driver" value="com.mysql.jdbc.Driver"/>-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/javaweb?allowMultiQueries=true&characterEncoding=utf-8&useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
        <environment id="dev">
            <!--使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域-->
            <transactionManager type="JDBC"/>
            <!--使用数据池,复用实例-->
            <dataSource type="POOLED">
                <!--<property name="driver" value="com.mysql.jdbc.Driver"/>-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/javaweb?allowMultiQueries=true&characterEncoding=utf-8&useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mybatis/MpUserMapper.xml"></mapper>
    </mappers>
</configuration>

6、创建mapper映射文件MpUserMapper.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="com.dao.MpUserDao">
<!--namespace要保证唯一,一般可以使用dao接口的路径,当然不是必须,只要保证唯一即可 -->
    <select id="lookUserById" resultType="com.bean.MpUser" parameterType="java.lang.Integer">
        select * from mp_user where uid=#{uid}
    </select>
</mapper>

7、测试类

import com.bean.MpUser;
import com.impl.MpUserDaoImpl;
import org.junit.Test;

public class TestM {
    @Test
    public void testA(){
        MpUserDaoImpl mpUserDao=new MpUserDaoImpl();
        MpUser mpUser = mpUserDao.lookUserById(1);
        System.out.println(mpUser);
    }
}

8、目录结构

9、结果

2.2.mybatis工具类

仔细看impl类,你会发现mybatis这样使用很复杂,每次查询都要

//1.加载主配置文件
InputStream inputStream = Resources.getResourceAsStream("Mybatis-config.xml");
//2.创建SqlSessionFactory对象
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//3.创建SqlSession对象
sqlSession = sessionFactory.openSession();

现在创建一个工具类:

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.InputStream;

public class MybatisUtils {
	//初始化创建SqlSessionFactory
	private static SqlSessionFactory sqlSessionFactory = null;
	static{
		try{
			//读取mybaits-config.xml文件
			InputStream inputStream = Resources.getResourceAsStream("Mybatis-config.xml");
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	//获取SqlSession
	public static SqlSession getSqlSession(){
		return sqlSessionFactory.openSession();
	}
	//获取SqlSessionFactory
	public static SqlSessionFactory getSessionFactory(){
		return sqlSessionFactory;
	}
}

接着可以修改impl类

import com.bean.MpUser;
import com.dao.MpUserDao;
import com.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
public class MpUserDaoImpl implements MpUserDao {
    private SqlSession sqlSession;
    @Override
    public MpUser lookUserById(Integer uid) {
        sqlSession= MybatisUtils.getSqlSession();
        MpUser mpUser=sqlSession.selectOne("lookUserById",1);
        sqlSession.commit();
        sqlSession.close();
        return mpUser;
    }
}

2.3.namespace作用

在mybatis文件夹创建MpArticleMapper.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="mparticlemapper">
    <select id="lookUserById" resultType="com.bean.MpUser" parameterType="java.lang.Integer">
        select uname,usex,uphone from mp_user where uid=#{uid}
    </select>
</mapper>

注意这个mapper中的查询方法的id,在MpUserMapper.xml中已经存在。然后在Mybatis-config.xml注册上

<mappers>
    <mapper resource="mybatis/MpUserMapper.xml"></mapper>
    <mapper resource="mybatis/MpArticleMapper.xml"></mapper>
</mappers>

接着继续执行刚刚的TestM,中的测试程序发现报错如下:

java.lang.IllegalArgumentException: lookUserById is ambiguous in Mapped Statements collection (try using the full name including the namespace, or rename one of the entries)

主要是因为两个XXmapper.xml中都存在lookUserById方法,故程序分不清去哪个中查询,此时应该修改Impl类。修改如下:

原:sqlSession.selectOne("lookUserById",1);
现:sqlSession.selectOne("com.dao.MpUserDao.lookUserById",1);

其中com.dao.MpUserDao就是mapper的namespace名字,到这我想就不用多说了,你应该懂namespace的作用了,如果说你不想加namespace,解决方案:xml中的插入方法的id不能一样。

3、主配置文件详解

主配置文件名可以随意命名,其主要完成以下几个功能:

· (1)注册存放DB连接四要素的属性文件

· (2)注册实体类的全限定性类名的别名

· (3)配置MyBatis运行环境,即数据源与事务管理器

· (4)注册映射文件

3.1 从属性文件中读取DB连接四要素

1、mybatis文件夹下创建jdbc.poroperties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/javaweb?allowMultiQueries=true&characterEncoding=utf-8&useSSL=false
jdbc.username=root
jdbc.password=123456

2、修改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">
<!--注意下面的配置顺序environments、mappers-->
<configuration>
    <properties resource="mybatis/jdbc.poroperties"></properties>
    <environments default="prod">
        <environment id="prod">
            <!--使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域-->
            <transactionManager type="JDBC"/>
            <!--使用数据池,复用实例-->
            <dataSource type="POOLED">
                <!--<property name="driver" value="com.mysql.jdbc.Driver"/>-->
                <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="mybatis/MpUserMapper.xml"></mapper>
        <mapper resource="mybatis/MpArticleMapper.xml"></mapper>
    </mappers>
</configuration>

3.2 指定实体类全限定性类名的别名

对于实体类的全限定性类名的别名指定方式,一般使用方式。这样做的好处是会将该包中所有实体类的简单类名指定为别名,写法简单方便。在Mybatis-config.xml添加如下内容

<typeAliases> <package name="com.bean"/></typeAliases>

注意此内容需要放置在<environments default="prod"></environments>内容上面

这样设置后,MpUserMapper.xml中的resultType="com.bean.MpUser"就可以就改成resultType="MpUser"了,这样简单多了。不过,还有另外的指定方式:通过指定。type:全限定性类名alias:别名该方式的好处是,可以指定别名为简单类名以外的其它名称。当然,弊端是,必须逐个指定,比较繁琐。

<typeAliases> <typeAlias type="com.bean.MpUser" alias="mpuser"/></typeAliases>

除了自定义的类型的别名外,MyBatis还提供了内置的类型别名:基本类型:

3.3 配置MyBatis的运行环境

配置MyBatis的运行环境,主要是配置数据源与事务管理器。

· 在environments标签在中可以包含多个运行环境,但其default属性指定了当前MyBatis运行时所选择使用的环境。environment的id属性为当前定义的运行环境的名称,可以任意命名。该名称会作为的default属性的值出现。

· transactionManager标签,该标签用于指定MyBatis所使用的事务管理器。MyBatis支持两种事务管理器类型:JDBC与MANAGED。

· (1)JDBC:使用JDBC的事务管理机制。即,通过Connection的commit()方法提交,通过rollback()方法回滚。但默认情况下,MyBatis将自动提交功能关闭了,改为了手动提交。即程序中需要显式的对事务进行提交或回滚。从日志的输出信息中可以看到。

· (2)MANAGED:由容器来管理事务的整个生命周期(如Spring容器)

· dataSource标签该标签用于配置MyBatis使用的数据源类型与数据库连接基本属性。常见有类型有:UNPOOLED、POOLED、JDNI等。

· (1)UNPOOLED :不使用连接池。即每次请求,都会为其创建一个DB连接,使用完毕后,会马上将此连接关闭。

· (2)POOLED:使用数据库连接池来维护连接。

· (3)JNDI:数据源可以定义到应用的外部,通过JNDI容器获取数据库连接。

3.4 指定映射文件

指定映射文件的方式有多种。但所有的方式,都是指定在mappers标签中的。指定映射文件若映射文件只有一个,则可直接使用如下形式:

<mappers>
    <mapper resource="mybatis/MpUserMapper.xml"></mapper>
    <mapper resource="mybatis/MpArticleMapper.xml"></mapper>
</mappers>

class属性值为Dao接口的全类名该方式的使用,需要满足以下几个要求:

· (1)映射文件名要与Dao接口名称相同

· (2)映射文件要与接口在同一包中

· (3)映射文件中的namespace属性值为Dao接口的全类名

<mappers> <mapper class="com.dao.MpUserDao"/></mappers>

当映射文件较多时,也可以使用如下形式。其中package的name属性指定映射文件所存放的包。但,这种方式的使用需要满足以下几个条件:

· (1)dao使用mapper动态代理实现(后面讲)

· (2)映射文件名要与Dao接口名称相同

· (3)映射文件要与接口在同一包中

· (4)映射文件中的namespace属性值为Dao接口的全类名

<mappers> <package name="com.dao"/></mappers>

dao使用mapper动态代理实现目录结构:

MpUserDaoImpl 修改成如下内容

import com.bean.MpUser;
import com.dao.MpUser.MpUserMapper;
import com.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;

public class MpUserDaoImpl implements MpUserMapper {
    private static MpUserMapper mpUserMapper;

    static {
        SqlSession sqlSession=MybatisUtils.getSqlSession();
        mpUserMapper = sqlSession.getMapper(MpUserMapper.class);
    }

    @Override
    public MpUser LookUserById(Integer uid) {
        return mpUserMapper.LookUserById(1);
    }
}

其他相关文章:

·Jdbc vs Mybatis、以及mybatis的API、源码分析:https://blog.csdn.net/qq_41941875/article/details/104881826

·细说mybatis一级缓存二级缓存:https://blog.csdn.net/qq_41941875/article/details/104864384

相关推荐

电脑装系统用GHOST好,还是原装版本好?老司机都是这么装的

Hello大家好,我是兼容机之家的咖啡。安装Windows系统是原版ISO好还是ghost好呢?针对这个的问题,我们先来科普一下什么是ghost系统,和原版ISO镜像两者之间有哪些优缺点。如果是很了解...

苹果 iOS 14.5.1/iPadOS 14.5.1 正式版发布

IT之家5月4日消息今日凌晨,苹果发布了iOS14.5.1与iPadOS14.5.1正式版更新。这一更新距iOS14.5正式版发布过去了一周时间。IT之家了解到,苹果表示,...

iOS 13.1.3 正式版发布 包含错误修复和改进

苹果今天发布了iOS13.1.3和iPadOS13.1.3,这是iOS13发布之后第四个升级补丁。iOS13.1.2两周前发布。iOS13.1.3主要包括针对iPad和...

还不理解 Error 和 Exception 吗,看这篇就够了

在Java中的基本理念是结构不佳的代码不能运行,发现错误的理想时期是在编译期间,因为你不用运行程序,只是凭借着对Java基本理念的理解就能发现问题。但是编译期并不能找出所有的问题,有一些N...

Linux 开发人员发现了导致 MacBook“无法启动”的 macOS 错误

“多个严重”错误影响配备ProMotion显示屏的MacBookPro。...

启动系统时无法正常启动提示\windows\system32\winload.efi

启动系统时无法正常启动提示\windows\system32\winload.efi。该怎么解决?  最近有用户遇到了开机遇到的问题,是Windows未能启动。原因可能是最近更改了硬件或软件。虽然提...

离线部署之两种构建Ragflow镜像的方式,dify同理

在实际项目交付过程中,经常遇到要离线部署的问题,生产服务器无法连接外网,这时就需要先构建好ragflow镜像,然后再拷到U盘或刻盘,下面介绍两种构建ragflow镜像的方式。性能测试(网络情况好的情况...

Go语言 error 类型详解(go语言 异常)

Go语言的error类型是用于处理程序运行中错误情况的核心机制。它通过显式的返回值(而非异常抛出)来管理错误,强调代码的可控性和清晰性。以下是详细说明及示例:一、error类型的基本概念内置接口...

Mac上“闪烁的问号”错误提示如何修复?

现在Mac电脑的用户越来越多,Mac电脑在使用过程中也会出现系统故障。当苹果电脑无法找到系统软件时,Mac会给出一个“闪烁的问号”的标志。很多用户受到过闪烁问号这一常见的错误提示的影响,如何解决这个问...

python散装笔记——177 sys 模块(python sys模块详解)

sys模块提供了访问程序运行时环境的函数和值,例如命令行参数...

30天自制操作系统:第一天(30天自制操作系统电子书)

因为咱们的目的是为了研究操作系统的组成,所以直接从系统启动的第二阶段的主引导记录开始。前提是将编译工具放在该文件目录的同级目录下,该工具为日本人川合秀实自制的编译程序,优化过的nasm编译工具。...

五大原因建议您现在不要升级iOS 13或iPadOS

今天苹果放出了iPadOS和iOS13的公测版本,任何对新版功能感兴趣的用户都可以下载安装参与测试。除非你想要率先体验Dark模式,以及使用AppleID来登陆Facebook等服务,那么外媒CN...

Python安装包总报错?这篇解决指南让你告别pip烦恼!

在Python开发中,...

苹果提供了在M1 Mac上修复macOS重装错误的方案

#AppleM1芯片#在苹果新的M1Mac推出后不久,我们看到有报道称,在这些机器上恢复和重新安装macOS,可能会导致安装错误,使你的Mac无法使用。具体来说,错误信息如下:"An...

黑苹果卡代码篇三:常见卡代码问题,满满的干货

前言...

取消回复欢迎 发表评论: