mybatis基础应用,看这一篇就够了!(代码片段)

程序员yqy 程序员yqy     2022-12-04     626

关键词:

文字分享

希望现在的你无论有明确具体的目标还是没有,都能重视自己的需求和目标,并且常常回顾,或许可以找一个你习惯的方式写出来,挂在哪里,电脑或日记本都好。当你疲惫或迷茫的时候拿出来看一下,这在情怀领域大概可以叫“不忘初心”。

相关概念

还是先上文字介绍吧!不敢兴趣的同学可直接跳过

Mybatis

MyBatis是一款优秀的基于ORM的半自动轻量级持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生类型、接口和Java的POJO (Plain Old Java Objects,普通老式Java对 象)为数据库中的记录。

对象/关系数据库映射(ORM)

ORM全称Object/Relation Mapping,表示对象-关系映射的缩写ORM完成面向对象的编程语言到关系数据库的映射。

当ORM框架完成映射后,程序员既可以利用面向对象程序设计语言的简单易用性,又可以利用关系数据库的技术优势。

ORM把关系数据库包装成面向对象的模型。ORM框架是面向对象设计语言与关系数据库发展不同步时的中间解决方案。

采用ORM框架后,应用程序不再直接访问底层数据库,而是以面向对象的放松来操作持久化对象,而ORM框架则将这些面向对象的操作转换成底层SQL操作。ORM框架实现的效果:把对持久化对象的保存、修改、删除 等操作,转换为对数据库的操作。

上面一堆话总结下来,可以理解为直接操作对象,不用关心数据库细节

Mybatis历史

原是apache的一个开源项目iBatis, 2010年6月这个项目由apache software foundation 迁移到了google code,随着开发团队转投Google Code旗下,ibatis3.x正式更名为Mybatis ,代码于2013年11月迁移到Github。

iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)

Mybatis优势

半自动化,对开发人员开说,核心sql还是需要自己进行优化。

sql和java编码进行分离,功能边界清晰,一个专注业务,一个专注数据。

基本使用

我们通过写一个用户表的增删查改进行入门

快速入门

开发步骤如下:

  1. 添加MyBatis的坐标
  2. 创建user数据表
  3. 编写User实体类
  4. 编写映射文件UserMapper.xml
  5. 编写核心文件SqlMapConfig.xml
  6. 编写测试类

新建maven项目并导入依赖

	<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties> <!--mybatis坐标-->
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency> <!--mysql驱动坐标-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
            <scope>runtime</scope>
        </dependency> <!--单元测试坐标-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency> <!--日志坐标-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
    </dependencies>

创建user数据表录入数据,并编写实体

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

public class User 

    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 "User" +
                "id=" + id +
                ", username='" + username + '\\'' +
                '';
    

编写UserMapper映射文件UserMapper.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="user">
    <select id="findAll" resultType="com.yqy.pojo.User">
        select  * from user
    </select>
</mapper>

编写MyBatis核心文件sqlMapConfig.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">
            <!--            当前事务交由jdbc管理-->
            <transactionManager type="JDBC"></transactionManager>
            <!--            当前使用mybatis提供的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///zyd_mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!--    引入映射配置文件-->
    <mappers>
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>

测试代码

	@Test
    public void test1() throws IOException 
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        //获得sqlSession工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        //获得sqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
		//执行sql语句,这里的user.findAll其实是通过xml中namespace和id的组合,
		//mybatis是通过namespace和id的组合来定位到具体的sql语句的
        List<User> userList = sqlSession.selectList("user.findAll");
        for (User user : userList) 
            System.out.println(user);
        
        sqlSession.close();
    

结果输入

增删改查操作

以上我们做了一个简单查询,接下来来个把增删改也来一套!

插入数据

基于之前编写UserMapper映射文件,追加insert

<mapper namespace="user">
    <insert id="insert" parameterType="com.yqy.pojo.User">
        insert into user values(#id,#username,#password) 
    </insert>
</mapper>

编写测试代码

    @Test
    public void testInsert() throws IOException 
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = new User();
        user.setId(3);
        user.setUsername("打工人");
        int insert = sqlSession.insert("user.insert", user);
        System.out.println(insert);
        //提交事务
        sqlSession.commit();
        sqlSession.close();
    

总结

  • 插入语句使用insert标签
  • 在映射文件中使用parameterType属性指定要插入的数据类型
  • Sql语句中使用#实体属性名方式引用实体中的属性值
  • 插入操作使用的API是sqlSession.insert(“命名空间.id”,实体对象);
  • 插入操作涉及数据库数据变化,所以要使用sqlSession对象显示的提交事务,即sqlSession.commit()

修改数据

基于之前编写UserMapper映射文件,追加insert

<mapper namespace="user">
    <update id="update" parameterType="com.yqy.pojo.User">
        update user set username=#username where id=#id
    </update>
</mapper>

编写测试代码

    @Test
    public void testUpdate() throws IOException 
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = new User();
        user.setId(3);
        user.setUsername("打工人yqy");
        sqlSession.update("user.update", user);
        //提交事务
        sqlSession.commit();
        sqlSession.close();
    

总结

• 修改语句使用update标签
• 修改操作使用的API是sqlSession.update(“命名空间.id”,实体对象);

删除数据

基于之前编写UserMapper映射文件,追加delete

<mapper namespace="user">
    <delete id="delete" parameterType="java.lang.Integer">
        delete from user where id=#id
    </delete>
</mapper>

编写测试代码

    @Test
    public void testDelete() throws IOException 
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.delete("user.delete",3);
        //提交事务
        sqlSession.commit();
        sqlSession.close();
    

总结

除语句使用delete标签
•Sql语句中使用#任意字符串方式引用传递的单个参数
•删除操作使用的API是sqlSession.delete(“命名空间.id”,Object);

常用配置解析

environments标签

数据库环境的配置,支持多环境配置

事务管理器transactionManager)类型有两种:

JDBC:这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。

MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。

数据源dataSource)类型有三种:

•UNPOOLED:每次被请求时打开和关闭连接。

•POOLED:利用“池”的概念将 JDBC 连接对象组织起来。

•JNDI:为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。

mapper标签

该标签的作用是加载映射的,加载方式有如下几种:

    •使用相对于类路径的资源引用,例如:
    <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
    •使用完全限定资源定位符(URL),例如:
    <mapper url="file:///var/mappers/AuthorMapper.xml"/>
    •使用映射器接口实现类的完全限定类名,例如:
    <mapper class="org.mybatis.builder.AuthorMapper"/>
    •将包内的映射器接口实现全部注册为映射器,例如:
    <package name="org.mybatis.builder"/>

相应API介绍

SqlSession工厂构建器SqlSessionFactoryBuilder

常用API:SqlSessionFactory build(InputStream inputStream)

通过加载mybatis的核心文件的输入流的形式构建一个SqlSessionFactory对象

String resource = "org/mybatis/builder/mybatis-config.xml"; 
InputStream inputStream = Resources.getResourceAsStream(resource); 
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); 
SqlSessionFactory factory = builder.build(inputStream);

其中, Resources 工具类,这个类在 org.apache.ibatis.io 包中。Resources 类帮助你从类路径下、文件系统或一个 web URL 中加载资源文件。

SqlSession工厂对象SqlSessionFactory

SqlSessionFactory 有多个个方法创建SqlSession 实例。常用的有如下两个:

SqlSession会话对象

SqlSession中提供了所有执行语句、提交或回滚事务和获取映射器实例的方法。

执行语句主要有:

<T> T selectOne(String statement, Object parameter) 
<E> List<E> selectList(String statement, Object parameter) 
int insert(String statement, Object parameter) 
int update(String statement, Object parameter) 
int delete(String statement, Object parameter)

操作失事务方法有:

void commit() 
void rollback()

Mybatis的Dao层实现

实现dao层方式有两种,传统开发和代理开发方式,代理开发的有点是不用编写具体实现类

传统开发方式

传统方式即自己编写Dao层接口的实现类

先定义接口

public interface UserDao  
	List<User> findAll() throws IOException; 

编写UserDaoImpl实现

public class UserDaoImpl implements UserDao  
	public List<User> findAll() throws IOException  
		InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml"); 
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); 
		SqlSession sqlSession = sqlSessionFactory.openSession(); 
		List<User> userList = sqlSession.selectList("userMapper.findAll"); 
		sqlSession.close(); 
		return userList; 
	 

测试

@Test 
public void testTraditionDao() throws IOException  
	UserDao userDao = new UserDaoImpl(); 
	List<User> all = userDao.findAll(); 
	System.out.println(all); 

代理开发方式

采用 Mybatis 的代理开发方式实现 DAO 层的开发,这是主流的方式。
Mapper 接口开发方法只需要编写Mapper 接口(相当于Dao 接口),由Mybatis 框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper 接口开发需要遵循以下规范:

  1. Mapper.xml文件中的namespace与mapper接口的全限定名相同
  2. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
  3. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
  4. Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

编写UserMapper接口

import com.yqy.pojo.User;

public interface UserDao 
    User findById(int id);

<mapper namespace="com.yqy.mapper.UserDao">
	<select id="findById" resultType="com.yqy.pojo.User" parameterType="int">
	      select  * from user where id = #id
	</select>
</mapper>

测试

    @Test
    public void testMapper() throws IOException 
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获得MyBatis框架生成的UserMapper接口的实现类
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        User user = userDao.findById(1);
        System.out.println(user);
    

配置文件深入

核心配置文件层次关系如下

常用配置

Properties标签

实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件

typeAliases标签

类型别名是为Java 类型设置一个短的名字。原来的类型名称配置如下

配置typeAliases,为com.lagou.domain.User定义别名为user

上面我们是自定义的别名,mybatis框架已经为我们设置好的一些常用的类型的别名

映射配置文件mapper.xml

动态sql语句

根据实体类的不同取值,使用不同的 SQL语句来进行查询。比如在 id如果不为空时可以根据id查询,如果username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。

<select id="findByCondition" parameterType☀️javanio?看这一篇就够了!!☀️(代码片段)

...向缓冲区1.2.3阻塞与非阻塞1.2.4.同步与异步二、Buffer基本应用2.1Buffer概述2.2Buffer基本应用三、Channel基本应用3.1Channel概述3.2FileChannel基本应用3.3SocketChanel基本应用四、Selector基本应用4.1Sele 查看详情

elasticsearch入门,看这一篇就够了(代码片段)

Elasticsearch入门,看这一篇就够了前言可视化工具kibanakibana的安装kibana配置kibana的启动Elasticsearch入门操作操作index创建index索引别名有什么用删除索引查询索引exist索引操作document插入document查询document删除document更新document使用... 查看详情

mybatis增删改查(步骤详细,由浅入深,适合初学者,只看这一篇就够了)(代码片段)

MyBatis目录java(后端框架)MyBatis的使用1.mybatis基本使用2.mybatis工具类的封装和实现增删改查3.mybatis中主要类的介绍4.nybatis实现动态代理:(使用的是反射机制,重点掌握)5.mybatis参数传递:6.$和#的区别(重点掌握)7.ResultType的使用... 查看详情

handler看这一篇就够了(代码片段)

Handler使用首先来熟悉一下Handler的四种使用方式,如果比较熟悉可以直接跳过:通过sendMessage消息机制来发送sendEmptyMessage(int);//发送一个空的消息sendMessage(Message);//发送消息,消息中可以携带参数sendMessageAtTime(Message,long... 查看详情

系统性的学会pandas看这一篇就够了(代码片段)

...cKinney开发出的库专门用于数据挖掘的开源python库以Numpy为基础,借力Numpy模块在计算方面性能高的优势基于matplotlib,能够简便的画图独特的 查看详情

redux从入门到进阶,看这一篇就够了!(代码片段)

Redux,带你从入门到进阶🌂序言☂️一、基础知识1、Redux概念简述2、Redux的工作流程🎃二、使用Antd实现TodoList页面布局1、在项目中使用Antd2、使用Antd实现TodoList的基本布局3、创建redux中的store(1)创建storeÿ... 查看详情

redux从入门到进阶,看这一篇就够了!(代码片段)

Redux,带你从入门到进阶🌂序言☂️一、基础知识1、Redux概念简述2、Redux的工作流程🎃二、使用Antd实现TodoList页面布局1、在项目中使用Antd2、使用Antd实现TodoList的基本布局3、创建redux中的store(1)创建storeÿ... 查看详情

typescript与javascript的区别(typescript万字基础入门,了解ts,看这一篇就够了)(代码片段)

TypeScript是JavaScript的一个超集,支持ECMAScript6标准(ES6教程)。TypeScript由微软开发的自由和开源的编程语言。TypeScript设计目标是开发大型应用,它可以编译成纯JavaScript,编译出来的JavaScript可以运行在任何浏览... 查看详情

最全排序算法及优化,看这一篇就够了(代码片段)

最全排序算法总结看这一篇就够了没有经过总结的知识是沉重的,无用的瞧一瞧~博健的LeetCode题解:Gitbook版本传送门博健的LeetCode题解:CSDN传送门有趣的CSS:Gitbook传送门前端进阶笔记:Gitbook传送门目录... 查看详情

关于el-upload看这一篇就够了(代码片段)

...9版本前提在解析源码之前,先阐述其重点使用的两个基础内容:<inputtype="file">使用type=“file”的元素使得用户可以选择一个或多个元素以提交表单的方式上传到服务器上,或者通过Javascript的FileAPI对... 查看详情

关于el-upload看这一篇就够了(代码片段)

...9版本前提在解析源码之前,先阐述其重点使用的两个基础内容:<inputtype="file">使用type=“file”的元素使得用户可以选择一个或多个元素以提交表单的方式上传到服务器上,或者通过Javascript的FileAPI对... 查看详情

什么是谓词下推,看这一篇就够了(代码片段)

...1.什么是谓词2.什么是下推3.什么是谓词下推4.一些常见的应用4.1传统数据库应用4.2Hive中的谓词下推4.3列式存储中的谓词下推今天有个小伙伴问我,什么是谓词下推,然后我就开启巴拉巴拉模式,说了好长一段时间࿰... 查看详情

java基础算法看这一篇就够了,简单全面一发入魂(代码片段)

目录1、简单的概述一下你眼中的算法?2、什么是Java的字节码?3、如何才能将一个double变量初始化为无穷大?4、能够将double类型的值和int类型的值相互比较吗?5、如果使用一个变量前没有将它初始化,会发... 查看详情

css渐变背景看这一篇就够了(代码片段)

CSS渐变背景看这一篇就够了在我们自己设计网页的时候,为了好看美观,颜色可谓是最让人头疼的一部分。尤其是在配色上又找不到一些好看的网站。今天我就来记录一些好看的渐变式背景,和一些常用的颜色网站。... 查看详情

想要弄懂groupby看这一篇就够了(代码片段)

一、前言groupby关键字,不管是工作中还是面试都会经常被用到,所以弄懂它是非常有必要的。要弄懂groupby那我们就得联合着:聚合函数、groupby、having一块讲解。讲之前我们先准备一张表:二、聚合函数为了讲好groupby我们必须... 查看详情

逆转单向链表看这一篇就够了java(代码片段)

逆转单向链表逆转前:1->2->3->4->5->null逆转后:5->4->3->2->1->null个人博客地址:逆转单向链表方法一、循环迭代publicNodereverse(Nodehead)if(head==null||head.next==null)returnhead;//取前面节点Nodepre=head;//取后面 查看详情

docker从入门到精通,看这一篇就够了(代码片段)

...缺点部署慢成本高虚拟机都不开,直接上物理机部署应用,那成本能不高嘛资源浪费硬件资源没有合理利用不易迁移和增加机器每次迁移都要重新安装一模一样的运行环境等受限于硬件虚拟机时代 查看详情

k8sservice服务详解,看这一篇就够了!!(代码片段)

...务可以相互通讯,反之进行隔离。1.1ServiceKubernetes中一个应用服务会有一个或多个实例(Pod,Pod可以通过rs进行多复本的建立),每个实例(Pod)的IP地址由网络插件动态随机分配(Pod重启后IP地址会改变)。为屏蔽这些后端实例的... 查看详情