系列文章目录
文章目录
前言
本系列为博主近期复习Mybatis相关知识时整合的书籍内容、相关练习例子以及个人的一些理解的分享,作为自己重温Mybatis操作的总结。希望能对在学习Mybatis或者在一些操作上遇到同样bug的同学给到一定的帮助。
一、Mybatis是什么?
简单来说,MyBatis(前身是iBatis)是一个支持普通SQL查询、存储过程以及高级映射的持久层框架 。MyBatis是一个半自动映射的框架,需要手动匹配提供POJO(实体类)、SQL和映射关系MyBatis可以配置动态SQL并优化SQL,可以通过配置决定SQL的映射规则,它还支持存储过程等。 ————《Java EE企业级应用开发教程》
二、Mybatis使用步骤
环境:博主使用的是IDEA2021版本,使用Maven作为项目管理,因此后续的导包使用的是在pom中添加依赖,如果是用jar包的小伙伴可以根据博主提供的链接获取对应jar包并添加到项目依赖中,同时附上文章中的代码。
链接:https://pan.baidu.com/s/13ebpuITEe5xY6_yY0hAeoA?pwd=fuu0 提取码:fuu0
1.引入相应依赖包
-
引入mybatis相应依赖包
本次使用的是mybatis-3.4.6版本,具体的pom代码如下:
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
使用Maven导入依赖有一点好处就是会将mybatis相关的依赖自动导入项目。
如果是使用jar包的同学们呢,就可以在我给大家的文件中看到以下目录:
将核心包以及lib目录中的依赖包都导入项目就完成了Mybatis的依赖引入。
- 引入Mysql连接包
博主使用的数据为mysql,导入mysql-connector-java-8.0.26的依赖包如下:
<!--mysql-connector依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
- lib目录下的需要我们进行配置的便是log4j日志输出
首先让我们看看是否启用log4j日志输出的差异图如下:
从图中我们也可以清楚的看到使用log4j后我们可以看到sql语句以及参数的输入,这样有利于在sql语句报错时找到问题所在,以及更清晰看到sql语句执行的过程。
开启log4j的方法也很简单,首先我们要引入前文所说的lib下log4j相关的依赖包,maven项目则引入log4j的依赖。其次,我们要在项目路径下创建log4j.properties文件(maven项目在resources目录下、普通项目在src目录下) --------此处的配置只是log4j的基础使用
<!--log4j依赖-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
# Global options
log4j.rootLogger=ERROR, stdout
# MyBatis Log options
#com.mashang 是需要使用log4j日志输出的包路径,通过修改com.mashang为自己的包目录即可
#Debug为日志输出的级别
log4j.logger.com.mashang=DEBUG
# Console Log options
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
2.Mybatis的工作原理图
3.Mybatis初体验
在这一节中使用一个基础的mybatis对学生信息增删改查的例子来感受一些Mybatis。
-
准备好学生表,并向其中添加数据
表的结构如下图:
名 | 类型 |
id | int |
name | varchar |
age | int |
sex | varchar |
加入数据如下:
id | name | age | sex |
1 | 郝涛 | 20 | 男 |
2 | 孟勇 | 20 | 男 |
3 | 王娜 | 20 | 女 |
-
创建持久化类(实体类)Student
实体类代码如下:
(这里我使用了一个插件lombok,简单来说就是使用对应的注解自动生成getter、setter、tostring等方法,可以看到我的代码非常简洁,只设置了相应的属性。)
package com.mashang.entity;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@Data
@NoArgsConstructor
@RequiredArgsConstructor
public class Student {
private Integer id;
@NonNull
private String name;
@NonNull
private Integer age;
@NonNull
private String sex;
}
-
创建mapper包并创建映射文件StudentMapper.xml
mybatis中mapper映射文件的写法有很多,可以是xml配置文件形式、接口映射以及注解映射的形式。初体验我们选择的是最容易理解的xml配置文件形式。
mapperXml相关约束配置如下:
<?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="">
</mapper>
具体代码如下:
<?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="com.mashang.mapper.StudentMapper">
<!--根据id查询学生所有信息-->
<!--parameterType表传入参数的类型,小写int对应的是包装类Integer-->
<!--resultType表得到结果的类型,需要传入全类型-->
<!--在mybatis中 #{id}表示该占位符待接收参数的名称为id-->
<select id="getStudentById" parameterType="int"
resultType="com.mashang.entity.Student">
select *
from student
where id = #{id}
</select>
</mapper>
-
在项目目录下创建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">
<!-- 配置文件的根元素 -->
<configuration>
</configuration>
具体代码如下:
<?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>
<!--配置环境,默认环境id为mysql-->
<environments default="mysql">
<!--配置id为mysql的数据库环境-->
<environment id="mysql">
<!--使用jdbc事务管理-->
<transactionManager type="JDBC"></transactionManager>
<!--数据源配置-->
<!--type为POOLED表示以连接池形式-->
<dataSource type="POOLED">
<!--配置驱动-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!--配置路径-->
<!--userSSL=false:不使用SSL协议链接数据库-->
<!--serverTimeZone=Asia/Shanghai:指明时区为亚洲上海-->
<property name="url"
value="jdbc:mysql://localhost:3306/Mybatis
?userSSL=false&serverTimeZone=Asia/Shanghai"/>
<!--配置数据库用户名-->
<property name="username" value="root"/>
<!--配置数据库密码-->
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--配置Mapper映射文件位置-->
<mappers>
<!--配置xml资源形式的映射文件-->
<mapper resource="com/mashang/mapper/StudentMapper.xml"/>
</mappers>
</configuration>
-
创建测试类
测试类包的位置就由大家自己来定了,博主这里是放在maven项目test文件夹下,使用Junit进行单元测试,当然大家也可以使用主函数来测试。
具体代码如下:
package com.mashang.test;
import com.mashang.entity.Student;
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 MybatisTest01 {
/*
* 根据学生ID返回学生数据
* */
@Test
public void getStudentById() throws IOException {
//1.读取配置文件输入流
InputStream resources = Resources
.getResourceAsStream("mybatis-config.xml");
//2.根据配置文件输入流使用SqlSessionFactoryBuilder创建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(resources);
//3.通过SqlSessionFactory创建SqlSession
SqlSession sqlSession = factory.openSession();
//4.利用sqlSession执行Mapper映射中的sql语句
/*因为通过Id主键查询只会返回一条数据,因此使用selectOne方法,
具体的其他方法在后续也会介绍*/
//传入参数为: 映射文件的 "命名空间+对应的方法id"
Student student = sqlSession.selectOne("com.mashang." +
"mapper.StudentMapper.getStudentById", 1);
System.out.println(student);
//关闭sqlSession连接
sqlSession.close();
}
}
执行代码得到结果如下:
注:如果是和我一样使用maven项目的小伙伴执行可能会遇到以下报错:
原因是Maven项目默认不会扫描src目录下的资源文件,只会扫描resource下的xml、properties等资源文件,解决方法有两种:
1.将mapper文件放在resource目录下
2.配置pom文件,使maven项目扫描src下的资源文件,具体代码如下:
<!--在build下加上以下代码-->
<resources>
<resource>
<directory>src/main/Java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
-
一样的操作设置增删改查代码
我不再一一演示,直接将完整的代码贴出如下:
增删改查的StudentMapper.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="com.mashang.mapper.StudentMapper">
<!--根据id查询学生所有信息-->
<!--parameterType表传入参数的类型,小写int对应的是包装类Integer-->
<!--resultType表得到结果的类型,需要传入全类型-->
<!--在mybatis中 #{id}表示该占位符待接收参数的名称为id-->
<select id="getStudentById" parameterType="int"
resultType="com.mashang.entity.Student">
select *
from student
where id = #{id}
</select>
<!--添加学生-->
<!--因为我在数据库中设置了id自增,因此将id赋值设为null-->
<insert id="addStudent"
parameterType="com.mashang.entity.Student">
insert into student
values (null, #{name}, #{age}, #{sex})
</insert>
<!--根据id修改学生信息-->
<!--
这里使用了mybatis中的set和if结合的动态sql,
根据传入参数动态生成sql语句,
具体的动态sql语法在后续会介绍
-->
<update id="updateStudent"
parameterType="com.mashang.entity.Student">
update student
<set>
<if test="name!=null and name!=''">
name=#{name},
</if>
<if test="age!=null and age!=''">
age=#{age},
</if>
<if test="sex!=null and sex!=''">
sex=#{sex},
</if>
</set>
where id=#{id}
</update>
<!--根据id删除学生-->
<delete id="deleteStudent" parameterType="int">
delete
from student
where id = #{id}
</delete>
</mapper>
增删改查测试类代码:
package com.mashang.test;
import com.mashang.entity.Student;
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 MybatisTest01 {
/*
* 根据学生ID返回学生数据
* */
@Test
public void getStudentById() throws IOException {
//1.读取配置文件输入流
InputStream resources = Resources
.getResourceAsStream("mybatis-config.xml");
//2.根据配置文件输入流使用SqlSessionFactoryBuilder创建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(resources);
//3.通过SqlSessionFactory创建SqlSession
SqlSession sqlSession = factory.openSession();
//4.利用sqlSession执行Mapper映射中的sql语句
/*因为通过Id主键查询只会返回一条数据,因此使用selectOne方法,
具体的其他方法在后续也会介绍*/
//传入参数为: 映射文件的 "命名空间+对应的方法id"
Student student = sqlSession.selectOne("com.mashang." +
"mapper.StudentMapper.getStudentById", 1);
System.out.println(student);
sqlSession.close();
}
/*
* 添加学生
* */
@Test
public void addStudent() throws IOException {
//1.读取配置文件输入流
InputStream resources = Resources
.getResourceAsStream("mybatis-config.xml");
//2.根据配置文件输入流使用SqlSessionFactoryBuilder创建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(resources);
//3.通过SqlSessionFactory创建SqlSession
SqlSession sqlSession = factory.openSession();
//4.利用sqlSession执行Mapper映射中的sql语句
/*
注意执行insert语句不能用selectOne等select方法,
应该使用insert方法,返回值为影响的行数。
且insert和update方法需要手动提交事物,
调用commit方法
*/
//传入参数为: 映射文件的 "命名空间+对应的方法id"
int row = sqlSession.insert("com.mashang." +
"mapper.StudentMapper.addStudent",
new Student("邓芳", 20, "男"));
if (row > 0) {
System.out.println("添加学生成功");
} else {
System.out.println("添加学生失败");
}
sqlSession.commit();
sqlSession.close();
}
/*
* 根据id修改学生信
* */
@Test
public void updateStudent() throws IOException {
//1.读取配置文件输入流
InputStream resources = Resources
.getResourceAsStream("mybatis-config.xml");
//2.根据配置文件输入流使用SqlSessionFactoryBuilder创建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(resources);
//3.通过SqlSessionFactory创建SqlSession
SqlSession sqlSession = factory.openSession();
//4.利用sqlSession执行Mapper映射中的sql语句
//传入参数为: 映射文件的 "命名空间+对应的方法id"
//创建学生对象
Student student = new Student();
//用setter设置id和名字
student.setId(1);
student.setName("张三");
int row = sqlSession.update("com.mashang." +
"mapper.StudentMapper.updateStudent", student);
if (row > 0) {
System.out.println("修改学生成功");
} else {
System.out.println("修改学生失败");
}
sqlSession.commit();
sqlSession.close();
}
/*
* 根据id删除学生
* */
@Test
public void deleteStudent() throws IOException {
//1.读取配置文件输入流
InputStream resources = Resources
.getResourceAsStream("mybatis-config.xml");
//2.根据配置文件输入流使用SqlSessionFactoryBuilder创建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(resources);
//3.通过SqlSessionFactory创建SqlSession
SqlSession sqlSession = factory.openSession();
//4.利用sqlSession执行Mapper映射中的sql语句
//传入参数为: 映射文件的 "命名空间+对应的方法id"
int row = sqlSession.delete("com.mashang." +
"mapper.StudentMapper.deleteStudent", 4);
if (row > 0) {
System.out.println("删除学生成功");
} else {
System.out.println("删除学生失败");
}
sqlSession.commit();
sqlSession.close();
}
}
总结
本篇文章简单的介绍了Mybatis,以及如何使用Mybatis,用了学生增删改查的小例子介绍了mybatis的简单使用以及效果。