mybatis
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
mybatis官方文档
mybatis快速入门
运行环境
idea 2023.3.5
mybatis 3.5.6
Maven 3.6.1
JDK 8
mysql 8
准备数据库 mysql 8
创建数据库mybatis
create table mybatis
创建dept表
CREATE TABLE dept (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
address VARCHAR(255) NOT NULL,
age INT NOT NULL,
sex VARCHAR(255) NOT NULL
);
插入语句
INSERT INTO dept VALUES (1, '张三', 25, '男', '北京');
INSERT INTO dept VALUES (2, '李四', 26, '男', '上海');
INSERT INTO dept VALUES (3, '王五', 30, '女', '天津');
创建项目
导入依赖
<?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>
<groupId>com.pxxy</groupId>
<artifactId>mybatis-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- lombok可以通过注解的方式自动化生成代码,主要用于减少模板化的代码,
例如getters/setters、equals、hashCode 和 toString 等方法 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
</dependency>
<!-- 用于连接mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
</dependencies>
</project>
记得刷新maven
编写 pojo 对象
创建pojo包,并在其下创建Dept类
Dept
package com.pxxy.pojo;
import lombok.Data;
// 这里使用了lombok的注解
// 能够自动生成所有属性对应的getters/setters、equals、hashCode和toString方法
@Data
public class Dept {
private int id;
private String name;
private int age;
private String sex;
private String address;
}
目录结构
编写 MyBatis 核心配置文件
在resources文件夹下,创建mybatis的核心配置文件mybatis-config.xml
官网有给出示例
直接复制官网的代码,再如下方修改
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--DTD约束-->
<!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"/>
<!--dataSource数据源 连接池:POOLED-->
<dataSource type="POOLED">
<!--连接驱动 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!--数据库连接路径 -->
<!--useSSL=false 如果mysql的版本是5.7之后的版本必须要加上useSSL=false
useSSL=true是进行安全验证,一般通过证书或者令牌什么的,useSSL=false就是通过账号密码进行连接,通常使用useSSL=false!!!-->
<!-- mysql:///后可以直接加数据库名 -->
<property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
<!-- 下方修改成自己数据库的用户名和对应的数据库密码 -->
<property name="username" value="root"/>
<property name="password" value="JiuNian"/>
</dataSource>
</environment>
</environments>
<!--sql文件配置标签-->
<!-- 此处删除了原来部分的sql映射文件 -->
<mappers>
</mappers>
</configuration>
编写 SQL映射文件
在resources文件夹下编写sql映射文件
这里也可以参照官网来写
DeptMapper.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="dept">
<!-- select 表示查询,除此之外还有update,delete,insert等标签 -->
<!-- id 是 select语句的唯一标识 resultType读取数据的封装类型 -->
<select id="findAll" resultType="com.pxxy.pojo.Dept">
<!-- 内部是查询语句 -->
select * from Dept
</select>
</mapper>
同时将这个文件加入到mybatis-config.xml中的mappers部分
<mappers>
<mapper resource="DeptMapper.xml"></mapper>
</mappers>
目录结构
常用标签
- <select> 标签 用于定义查询操作
- 属性:
- id:唯一标识 SQL 语句的方法名
- resultType:指定查询结果的返回类型,可以是类的全限定名或简单类型
- parameterType:指定传入参数的类型(可选)
- 示例:
- 属性:
<select id="findAll" resultType="com.example.pojo.User">
SELECT * FROM users;
</select>
- <insert> 标签 用于定义插入操作
- 属性:
- id:唯一标识 SQL 语句的方法名
- parameterType:指定传入参数的类型(可选)
示例:
- 属性:
<insert id="addUser" parameterType="com.example.pojo.User">
INSERT INTO users (name, age, address) VALUES (#{name}, #{age}, #{address});
</insert>
- <update> 标签 用于定义更新操作
- 属性:
- id:唯一标识 SQL 语句的方法名
- parameterType:指定传入参数的类型(可选)
- 示例:
- 属性:
<update id="updateUser" parameterType="com.example.pojo.User">
UPDATE users SET name = #{name}, age = #{age} WHERE id = #{id};
</update>
- <delete> 标签 用于定义删除操作
- 属性:
- id:唯一标识 SQL 语句的方法名
- parameterType:指定传入参数的类型(可选)
- 示例:
- 属性:
<delete id="deleteUser" parameterType="int">
DELETE FROM users WHERE id = #{id};
</delete>
- <resultMap> 标签 用于自定义结果集的映射,解决字段名和实体类属性名不一致的问题
- 属性:
- id:唯一标识该映射关系
- type:指定映射结果的实体类
- 子标签:
- :映射主键字段
- :映射非主键字段
- 示例:
- 属性:
<resultMap id="userResultMap" type="com.example.pojo.User">
<id column="user_id" property="id"/>
<result column="user_name" property="name"/>
<result column="user_age" property="age"/>
</resultMap>
<select id="findUserById" resultMap="userResultMap">
SELECT user_id, user_name, user_age FROM users WHERE user_id = #{id};
</select>
编写运行类
在com.pxxy下创建App类,来测试方法是否可行
import com.pxxy.pojo.Dept;
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;
import java.util.List;
public class App {
public static void main(String[] args) throws IOException, SQLException {
// 读取配置文件 返回流
InputStream is
= Resources.getResourceAsStream("mybatis-config.xml");
//解析并加载返回的配置文件,使用SqlSessionFactoryBuilder()的build方法 可以自动加载流
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);
//通过工厂获取连接
SqlSession session = build.openSession();
// 找到标签对应方法,并选择要使用的id
// 这里是命名空间 + 标签id
List<Dept> depts = session.selectList("dept.findAll");
for (Dept dept : depts) {
System.out.println(dept);
}
// 释放连接
session.close();
}
执行一下,看看运行结果
使用代理开发来优化调用
在mybatis中可以通过代理开发来接口类约束,动态生成实现类,例如
在修改前先安装一个插件MyBatisX
,可以帮助接口类和sql映射文件之间快速切换
点击小鸟即可快速切换到另一个对应文件
创建sql接口类
在com.pxxy下创建mapper文件夹,并在其下创建DeptMapper接口类
DeptMapper
package com.pxxy.mapper;
import com.pxxy.pojo.Dept;
import java.util.List;
public interface DeptMapper {
// 返回类型 对应 resultType
// 方法名 对应sql 标签上的id
public List<Dept> findAll();
}
目录结构
更改命名空间
修改原来的DeptMapper.xml文件并移动到在resources中对应DeptMapper接口的文件夹中
<?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.pxxy.mapper.DeptMapper">
<select id="findAll" resultType="com.pxxy.pojo.Dept">
select * from Dept
</select>
</mapper>
目录结构
修改核心配置类的Mappers
修改mybatis-config.xml中的Mappers
<mappers>
<!-- 用于加载sql映射文件 -->
<!-- 如果Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载 -->
<package name="com.pxxy.mapper"/>
</mappers>
修改运行类
import com.pxxy.mapper.DeptMapper;
import com.pxxy.pojo.Dept;
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;
import java.util.List;
public class App {
public static void main(String[] args) throws IOException {
InputStream rs = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(rs);
SqlSession sqlSession = build.openSession();
// 使用getMapper选择对应的接口
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
List<Dept> depts = deptMapper.findAll();
for (Dept dept : depts) {
System.out.println(dept);
}
sqlSession.close();
}
}
运行结果与之前一致
注解开发
使用代理开发需要同时维护两个文件,这样仍旧有点麻烦,所以mybatis还推出了注解开发,在接口类上添加注解,即可完成sql映射,且使用和代理开发相同的调用方法
常用注解
- @Insert 用于执行 插入 操作
- 示例:
@Insert("INSERT INTO users (name, email) VALUES (#{name}, #{email})")
void insertUser(User user);
// #{}:MyBatis 会自动将 User 对象中的 name 和 email 的值替换到 SQL 中的 #{name} 和 #{email} 变量
- @Select 用于执行 查询 操作,通常用于 SELECT 语句
- 示例:
@Select("SELECT * FROM users WHERE id = #{id}")
User getUserById(@Param("id") Integer id);
// @Param("id"):用于指定方法参数名称,确保 #{id} 能正确映射到方法参数
// 返回值:直接返回对应的实体对象
- @Update 用于执行 更新 操作
- 示例:
@Update("UPDATE users SET name = #{name}, email = #{email} WHERE id = #{id}")
void updateUser(User user);
// #{}:直接将 User 对象的 name、email 和 id 替换到 SQL 中
- @Delete 用于执行 删除 操作
- 示例:
@Delete("DELETE FROM users WHERE id = #{id}")
void deleteUser(@Param("id") Integer id);
// @Param:同样确保 #{id} 正确映射方法参数
- @Param 用于传递多个参数,解决参数名称不一致问题。尤其是在方法有多个参数时,必须使用 @Param 标注参数名称
- 示例:
@Select("SELECT * FROM users WHERE name = #{name} AND email = #{email}")
User getUserByNameAndEmail(@Param("name") String name, @Param("email") String email);
// #{name} 和 #{email}:对应 @Param 中指定的参数名称。
- 结果映射:@Results 和 @Result 用于自定义结果集的映射,解决数据库字段名与 Java 对象属性名不一致的问题。
- 示例:
@Select("SELECT user_id, user_name FROM users WHERE user_id = #{id}")
@Results({
@Result(property = "id", column = "user_id"),
@Result(property = "name", column = "user_name")
})
User getUserWithMapping(@Param("id") Integer id);
// @Result:指定 property(实体类属性) 和 column(数据库字段)。
// @Results:包含多个 @Result 注解。
添加注解
在接口类的方法上添加注解,如下
public interface DeptMapper {
// 格式是注解 + sql语句
@Select("select * from dept")
public List<Dept> findAll();
// 此处添加一个了delete标签
@Delete("delete from dept where id=#{id}")
public void deleteDeptById(@Param("id") int id);
}
修改运行类
import com.pxxy.mapper.DeptMapper;
import com.pxxy.pojo.Dept;
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;
import java.util.List;
public class App {
public static void main(String[] args) throws IOException {
InputStream rs = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(rs);
SqlSession sqlSession = build.openSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
List<Dept> depts = deptMapper.findAll();
for (Dept dept : depts) {
System.out.println(dept);
}
System.out.println("=====================================");
deptMapper.deleteDeptById(2);
List<Dept> newDepts = deptMapper.findAll();
for (Dept newDept : newDepts) {
System.out.println(newDept);
}
// 如果有会修改数据库的操作,则一定要使用commit,否侧数据被修改后不会提交到真实的数据库里
sqlSession.commit();
sqlSession.close();
}
}
运行
使用注解开发后可以将先前的sql映射文件DeptMapper.xml删除,但是不要删除mybatis-config.xml中的mapper扫包
优化
下方的代码块每次运行前都要写一遍,如果很多地方会用到则会有很多的重复代码
InputStream rs = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(rs);
SqlSession sqlSession = build.openSession();
因此我们可以将它写到一个单独的工具类中去,如下创建utils包中,并创建MyUtils工具类
MyUtils
package com.pxxy.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;
public class MyUtils {
public static SqlSession getSqlSession() {
SqlSession sqlSession = null;
try {
InputStream rs = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(rs);
sqlSession = build.openSession();
} catch (IOException e) {
e.printStackTrace();
}
return sqlSession;
}
}
修改运行类
import com.pxxy.mapper.DeptMapper;
import com.pxxy.pojo.Dept;
import com.pxxy.utils.MyUtils;
import org.apache.ibatis.session.SqlSession;
import java.io.IOException;
import java.util.List;
public class App {
public static void main(String[] args) throws IOException {
SqlSession sqlSession = MyUtils.getSqlSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
List<Dept> depts = deptMapper.findAll();
for (Dept dept : depts) {
System.out.println(dept);
}
System.out.println("=====================================");
deptMapper.deleteDeptById(2);
List<Dept> newDepts = deptMapper.findAll();
for (Dept newDept : newDepts) {
System.out.println(newDept);
}
sqlSession.commit();
// 记住每次getSqlSession之后都需要close
sqlSession.close();
}
}
运行结果
总结
本文简单介绍了MyBatis的快速入门流程,包括环境配置、数据库准备、项目结构、核心配置文件和SQL映射文件的编写。通过创建Dept表和POJO类,利用MyBatis的配置文件和SQL映射以及代理开发和注解开发两种模式实现了数据查询功能。同时,提供了mybatis调用的优化方案,利用接口映射简化代码调用