😀前言
在现代软件开发中,与数据库交互是一个不可避免的任务。为了更高效、更简洁地操作数据库,持久层框架的应用变得越来越重要。在这个教程中,我们将探索MyBatis,这个强大的持久层框架,它能够极大地简化数据库操作,提高开发效率,同时还能帮助我们实现代码的解耦。
🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉
😊解锁数据库操作新境界:轻松上手的MyBatis快速入门指南
官方文档
MyBatis 中文手册 https://mybatis.org/mybatis-3/zh/index.html
Maven 仓库
提示:需要什么 jar 包,搜索得到对应的 maven dependency
😉传统的 Java 程序操作 DB 分析
工作示意图
传统方式问题分析(如上)
引出 MyBatis
基本介绍
1. MyBatis 是一个持久层框架
2. 前身是 ibatis, 在 ibatis3.x 时,更名为 MyBatis
3. MyBatis 在 java 和 sql 之间提供更灵活的映射方案
4. mybatis 可以将对数据表的操作(sql,方法)等等直接剥离,写到 xml 配置文件,实现和 java代码的解耦
5. mybatis 通过 SQL 操作 DB, 建库建表的工作需要程序员完成
MyBatis 工作原理示意图
🥰MyBatis 快速入门
快速入门需求说明
要求: 开发一个 MyBatis 项目,通过 MyBatis 的方式可以完成对 monster 表的 crud 操作
快速入门-代码实现
创建 mybatis 数据库 - monster 表
CREATE DATABASE `mybatis` CREATE TABLE `monster` ( `id` INT NOT NULL AUTO_INCREMENT, `age` INT NOT NULL, `birthday` DATE DEFAULT NULL, `email` VARCHAR(255) NOT NULL , `gender` TINYINT NOT NULL, `name` VARCHAR(255) NOT NULL, `salary` DOUBLE NOT NULL, PRIMARY KEY (`id`) ) CHARSET=utf8
MyBatis 快速入门
快速入门需求说明
要求: 开发一个 MyBatis 项目,通过 MyBatis 的方式可以完成对 monster 表的 crud 操作
快速入门-代码实现
1. 创建 mybatis 数据库 - monster 表
2. 创建 maven 项目, 方便项目jar包管理
说明
将 D:\idea_java_projects\WYX_MyBatis\pom.xml 作为父项目 pom.xml 引入相关依赖
1. 将mybatis作为父项目管理多个子模块/子项目
2. 父项目的完整的坐标 groupId[组织名]+artifactId[项目名]
3. 后面该父项目会管理多个子模块/子项目 , 将来父项目中的引入的依赖可以直接给子项目用, 这样开发简单,提高复用性,也便于管理
4. pom 表示父项目以多个子模块/子项目管理工程
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!--解读 1. 将mybatis作为父项目管理多个子模块/子项目 2. 父项目的完整的坐标 groupId[组织名]+artifactId[项目名] 3. 后面该父项目会管理多个子模块/子项目 , 将来父项目中的引入的依赖可以直接给子项目用 , 这样开发简单,提高复用性,也便于管理 4. <packaging>pom</packaging> 表示父项目以多个子模块/子项目管理工程 --> <groupId>com.wyxedu</groupId> <artifactId>mybatis</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <!-- modules指定管理的哪些子模块 --> <modules> <module>mybatis_quickstart</module> </modules> <!--加入依赖--> <dependencies> <!--mysql依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency> <!--mybatis依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!--junit依赖--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <!--如果这里有一个scope-test 表示该jar的作用范围在test目录, 后面老韩还有有专门讲解maven --> <!--<scope>test</scope>--> </dependency> </dependencies>
这个自动生成就说明成功了
创建 mybatis-config.xml
1. jdbc:mysql 协议
2. 127.0.0.1:3306 : 指定连接mysql的ip+port
3. mybatis: 连接的DB
4. useSSL=true 表示使用安全连接
5. & 表示 & 防止解析错误
6. useUnicode=true : 使用unicode 作用是防止编码错误
7. characterEncoding=UTF-8 指定使用utf-8, 防止中文乱码
8. 温馨提示:不要背,直接使用即可
<environments default="development"> <environment id="development"> <!--配置事务管理器--> <transactionManager type="JDBC"/> <!--配置数据源--> <dataSource type="POOLED"> <!--配置驱动--> <property name="driver" value="com.mysql.jdbc.Driver"/> <!--配置连接mysql-url 解读: 1. jdbc:mysql 协议 2. 127.0.0.1:3306 : 指定连接mysql的ip+port 3. mybatis: 连接的DB 4. useSSL=true 表示使用安全连接 5. & 表示 & 防止解析错误 6. useUnicode=true : 使用unicode 作用是防止编码错误 7. characterEncoding=UTF-8 指定使用utf-8, 防止中文乱码 8. 温馨提示:不要背,直接使用即可 --> <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments>
创建Monster类
解读
1. 一个普通的Pojo类
2. 使用原生态的sql语句查询结果还是要封装成对象
3. 要求大家这里的实体类属性名和表名字段保持一致。
package com.wyxdu.entity; import java.util.Date; /** * Monster 和 monster表有对应关系 * 体现OOP */ //解读 //1. 一个普通的Pojo类 //2. 使用原生态的sql语句查询结果还是要封装成对象 //3. 要求大家这里的实体类属性名和表名字段保持一致。 public class Monster { //属性-和表字段有对应关系 private Integer id; private Integer age; private String name; private String email; private Date birthday; private double salary; private Integer gender; public Monster() { } public Monster(Integer id, Integer age, String name, String email, Date birthday, double salary, Integer gender) { this.id = id; this.age = age; this.name = name; this.email = email; this.birthday = birthday; this.salary = salary; this.gender = gender; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public Integer getGender() { return gender; } public void setGender(Integer gender) { this.gender = gender; } @Override public String toString() { return "Monster{" + "id=" + id + ", age=" + age + ", name='" + name + '\'' + ", email='" + email + '\'' + ", birthday=" + birthday + ", salary=" + salary + ", gender=" + gender + '}'; } }
创建MonsterMapper类
public interface MonsterMapper { //添加monster public void addMonster(Monster monster); }
创建MonsterMapper.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"> <!--解读 1. 这是一个mapper xml 文件 2. 该文件可以去实现对应的接口的方法 3. namespace 指定该xml文件和哪个接口对应!!! --> <mapper namespace="com.wyxdu.mapper.MonsterMapper"> <!--配置addMonster 1. id="addMonster" 就是接口的方法名 2. parameterType="com.wyxdu.entity.Monster" 放入的形参的类型 3. 注意"com.wyxdu.entity.Monster" 可以简写 4. 写入sql语句=> 建议,现在sqlyog 写完成-测试通过,再拿过来 5. (`age`, `birthday`, `email`, `gender`, `name`, `salary`) 表的字段 6. (#{age}, #{birthday}, #{email}, #{gender}, #{name}, #{salary}) 是从传入的monster对象属性值 7. 这里 #{age} age 对应monster对象的属性名,其它一样 --> <insert id="addMonster" parameterType="com.wyxdu.entity.Monster" useGeneratedKeys="true" keyProperty="id"> INSERT INTO `monster` (`age`, `birthday`, `email`, `gender`, `name`, `salary`) VALUES (#{age}, #{birthday}, #{email}, #{gender}, #{name}, #{salary}) </insert> </mapper>
配置addMonster 注意事项
1. id="addMonster" 就是接口的方法名
2. parameterType="com.wyxdu.entity.Monster" 放入的形参的类型
3. 注意"com.wyxdu.entity.Monster" 可以简写
4. 写入sql语句=> 建议,现在sqlyog 写完成-测试通过,再拿过来
5. (`age`, `birthday`, `email`, `gender`, `name`, `salary`) 表的字段
6. (#{age}, #{birthday}, #{email}, #{gender}, #{name}, #{salary}) 是从传入的monster对象属性值
7. 这里 #{age} age 对应monster对象的属性名,其它一样
修改mybatis-config.xml
说明
1. 这里我们配置需要关联的Mapper.xml
2. 这里我们可以通过菜单 Path from source root
<mappers> <mapper resource="com/wyxdu/mapper/MonsterMapper.xml"/> </mappers>
创建工具类MyBatisUtils可以得到SqlSession
package com.wyxdu.util; 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; /** * MyBatisUtils 工具类,可以得到SqlSession */ public class MyBatisUtils { //属性 private static SqlSessionFactory sqlSessionFactory; //编写静态代码块-初始化sqlSessionFactory static { try { //指定资源文件, 配置文件mybatis-config.xml String resource = "mybatis-config.xml"; //获取到配置文件mybatis-config.xml 对应的inputStream //这里说明:加载文件时,默认到resources目录=>运行后的工作目录target-classes InputStream resourceAsStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); System.out.println("sqlSessionFactory=" + sqlSessionFactory.getClass()); } catch (IOException e) { e.printStackTrace(); } } //编写方法,返回SqlSession对象-会话 public static SqlSession getSqlSession() { return sqlSessionFactory.openSession(); } }
创建MonsterMapperTest
注意
如果是增删改, 需要提交事务
public class MonsterMapperTest { //属性 private SqlSession sqlSession; private MonsterMapper monsterMapper; /** * 解读 * 1. 当方法标注 @Before, 表示在执行你的目标测试方法前,会先执行该方法 * */ //编写方法完成初始化 @Before public void init() { //获取到sqlSession sqlSession = MyBatisUtils.getSqlSession(); //获取到到MonsterMapper对象 class com.sun.proxy.$Proxy7 代理对象 //, 底层是使用了动态代理机制 monsterMapper = sqlSession.getMapper(MonsterMapper.class); System.out.println("monsterMapper=" + monsterMapper.getClass()); } @Test public void addMonster() { for (int i = 0; i < 2; i++) { Monster monster = new Monster(); monster.setAge(10 + i); monster.setBirthday(new Date()); monster.setEmail("kate@qq.com"); monster.setGender(1); monster.setName("大象精-" + i); monster.setSalary(1000 + i * 10); monsterMapper.addMonster(monster); System.out.println("添加对象--" + monster); System.out.println("添加到表中后, 自增长的id=" + monster.getId()); } //如果是增删改, 需要提交事务 if(sqlSession != null) { sqlSession.commit(); sqlSession.close(); } System.out.println("保存成功..."); } }
测试
看看是否可以添加成功, 这时会出现找不到 Xxxxmapper.xml 错误, 分析了原因
解决找不到 Mapper.xml 配置文件问题,
提示:如果顺利,你会很快解决,不顺利, 你 会 干 到 怀 疑 人 生
在父工程的 pom.xml 加入 build 配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!--在build中配置resources,来防止我们资源导出失败的问题 解读: 1. 不同的idea/maven 可能提示的错误不一样 2. 不变应万变,少什么文件,就增加相应配置即可 3. 含义是将 src/main/java目录和子目录 和 src/main/resources目录和子目录 的资源文件 xml 和 properties在build项目时,导出到对应的target目录下 --> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </resource> </resources> </build> </project>
修改 MonsterMapper.java, 增加方法接口
//根据id删除一个Monster public void delMonster(Integer id);
修改 MonsterMapper.xml, 实现方法接口
<!--配置/实现delM onster方法 1. 这里 java.lang.Integer 这是Java类型, 可以简写成 Integer 2. 这里写入delete --> <delete id="delMonster" parameterType="Integer"> DELETE FROM `monster` WHERE id = #{id} </delete>
完成测试
修改 MonsterMapperTest增加测试方法
@Test public void delMonster() { monsterMapper.delMonster(2); if(sqlSession != null) { sqlSession.commit(); sqlSession.close(); } System.out.println("删除成功..."); }
修改 MonsterMapper.java, 增加方法接口
//修改Monster public void updateMonster(Monster monster); //查询-根据id public Monster getMonsterById(Integer id); //查询所有的Monster public List<Monster> findAllMonster();
为了配置方便
在 mybatis-config.xml 配置 Monster 的别名
<!--配置别名--> <typeAliases> <typeAlias type="com.wyxdu.entity.Monster" alias="Monster"/> </typeAliases>
修改 MonsterMapper.xml, 实现方法接口
这里就可以简化操作了
<update id="updateMonster" parameterType="Monster"> UPDATE `monster` SET `age`=#{age} , `birthday`= #{birthday}, `email` = #{email}, `gender` = #{gender} , `name`= #{name}, `salary` = #{salary} WHERE id = #{id} </update> <!--配置/实现getMonsterById--> <select id="getMonsterById" resultType="Monster"> SELECT * FROM `monster` WHERE id = #{id} </select> <!--配置/实现findAllMonster--> <select id="findAllMonster" resultType="Monster"> SELECT * FROM `monster` </select>
完成测试
修改 MonsterMapperTest增加测试方法
@Test public void updateMonster() { Monster monster = new Monster(); monster.setAge(50); monster.setBirthday(new Date()); monster.setEmail("king3@qq.com"); monster.setGender(0); monster.setName("老鼠精-01"); monster.setSalary(2000); monster.setId(3); monsterMapper.updateMonster(monster); if(sqlSession != null) { sqlSession.commit(); sqlSession.close(); } System.out.println("修改成功..."); } @Test public void getMonsterById() { Monster monster = monsterMapper.getMonsterById(3); System.out.println("monster=" + monster); if(sqlSession != null) { sqlSession.close(); } System.out.println("查询成功~"); } @Test public void findAllMonster() { List<Monster> monsters = monsterMapper.findAllMonster(); for (Monster monster : monsters) { System.out.println("monster-" + monster); } if(sqlSession != null) { sqlSession.close(); } System.out.println("查询成功~"); }
😄总结
通过本教程,我们深入了解了MyBatis的基本原理和使用方法。从创建数据库表、配置MyBatis环境,到定义实体类、编写Mapper接口和XML映射文件,再到完成CRUD操作的全流程,我们详细讲解了每个步骤。MyBatis通过灵活的配置和强大的SQL操作,让数据库操作变得轻松而又高效。希望你通过这个教程能够掌握MyBatis的基本用法,为你的持久层开发工作带来便捷和舒适。继续探索和应用MyBatis,将有助于你构建更出色的软件项目
文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞