什么是 MyBatis?
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
优点
- 与JDBC相比,减少了50%的代码量;
- 最简单的持久化框架,简单易学;
- SQL代码从程序代码中彻底分离出来,可以重用;
- 提供XML标签,支持编写动态SQL;
- 提供映射标签,支持对象与数据库的ORM字段关系映射。
缺点
- SQL语句编写工作量大,熟练度要高;
- 数据库移植性比较差,如果需要切换数据库的话,SQL语句会有很大的差异。
如何在项目中使用 MyBatis?
1.创建一个 Maven 项目,并导入依赖
<?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>org.example</groupId>
<artifactId>mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2.创建数据库和表
CREATE TABLE `person` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'id,主键,自增长',
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '姓名',
`age` tinyint DEFAULT NULL COMMENT '年龄',
`sex` char(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '性别',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='码森林-MyBatis-Person';
3.创建与表对应的实体类
public class Person {
private Integer id;
private String name;
private Integer age;
private String sex;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
4.创建配置文件 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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--配置数据库连接-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/masenlin_mybatis?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--引入每一个接口对应点xml文件-->
<mappers>
<mapper resource="mapper/PersonMapper.xml"/>
</mappers>
</configuration>
5.创建对应的 Mapper 类,编写接口
package com.masenlin.mybatis.demo01.mapper;
import com.masenlin.mybatis.demo01.entity.Person;
/**
* @author wangc
* @date 2022年11月15日 17:14
*/
public interface PersonMapper {
/**
* 新增人员信息
*
* @param person
*/
void insertPerson(Person person);
/**
* 更新人员信息
*
* @param person
*/
void updatePersonById(Person person);
/**
* 根据id获取人员信息
*
* @param id
* @return
*/
Person getPersonById(Integer id);
/**
* 根据id删除人员信息
*
* @param id
*/
void deletePersonById(Integer id);
}
6.创建对应的 Mapper.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.masenlin.mybatis.demo01.mapper.PersonMapper">
<!--
select:表示这个操作是一个查询操作
id表示的是要匹配的方法的名称
resultType:表示返回值的类型,查询操作必须要包含返回值的类型
#{属性名}:表示要传递的参数的名称
-->
<!-- 根据id获取人员信息 -->
<select id="getPersonById" resultType="com.masenlin.mybatis.demo01.entity.Person">
SELECT * FROM person WHERE id = #{id}
</select>
<!--
增删改查操作不需要返回值,增删改返回的是影响的行数,mybatis会自动做判断。
keyProperty="id" useGeneratedKeys="true" 表示返回新增的主键ID,可以通过person.getId()获取
-->
<!-- 新增人员信息 -->
<insert id="insertPerson" keyProperty="id" useGeneratedKeys="true">
INSERT INTO person (name, age, sex) VALUES (#{name}, #{age}, #{sex})
</insert>
<!-- 修改人员信息 -->
<update id="updatePersonById">
UPDATE person SET name = #{name}, age = #{age}, sex = #{sex} WHERE id = #{id}
</update>
<!-- 根据id删除人员信息 -->
<delete id="deletePersonById">
DELETE FROM person WHERE id = #{id}
</delete>
</mapper>
7.测试用例
package com.masenlin.mybatis.demo01;
import com.masenlin.mybatis.demo01.entity.Person;
import com.masenlin.mybatis.demo01.mapper.PersonMapper;
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.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
/**
* @author wangc
* @date 2022年11月15日 17:27
*/
public class MyBatisDemo01Test {
SqlSessionFactory sqlSessionFactory = null;
@Before
public void init() {
String resource = "mybatis-config.xml";
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream(resource);
// 根据全局配置文件创建出 SqlSessionFactory,SqlSessionFactory 是负责创建 SqlSession 对象的工厂
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void insertPerson() {
// 获取数据库的会话
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person person = new Person();
person.setName("张三");
person.setAge(24);
person.setSex("男");
mapper.insertPerson(person);
// 提交本次会话要执行的内容
sqlSession.commit();
System.out.println(person.getId());
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭会话
sqlSession.close();
}
}
@Test
public void updatePersonById() {
// 获取数据库的会话
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person person = new Person();
person.setId(5);
person.setName("张三明");
person.setAge(20);
person.setSex("男");
mapper.updatePersonById(person);
// 提交本次会话要执行的内容
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭会话
sqlSession.close();
}
}
@Test
public void getPersonById() {
// 获取数据库的会话
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person person = mapper.getPersonById(5);
System.out.println(person);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭会话
sqlSession.close();
}
}
@Test
public void deletePersonById() {
// 获取数据库的会话
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
mapper.deletePersonById(5);
// 提交本次会话要执行的内容
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭会话
sqlSession.close();
}
}
}
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>
<!--引入外部配置文件,类似于Spring中的property-placeholder
resource:从类路径引入
url:从磁盘路径或者网络路径引入
-->
<properties resource="db.properties"></properties>
<!--用来控制mybatis运行时的行为,是mybatis中的重要配置-->
<settings>
<!--设置列名映射的时候是否是驼峰标识-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--typeAliases表示为我们引用的实体类起别名,默认情况下我们需要写类的完全限定名
如果在此处做了配置,那么可以直接写类的名称,在type中配置上类的完全限定名,在使用的时候可以忽略大小写
还可以通过alias属性来表示类的别名
-->
<typeAliases>
<!-- <typeAlias type="com.masenlin.entity.Person" alias="Person"></typeAlias>-->
<!--如果需要引用多个类,那么给每一个类起别名肯定会很麻烦,因此可以指定对应的包名,那么默认用的是类名-->
<package name="com.masenlin.entity"/>
</typeAliases>
<!--
在实际的开发过程中,我们可能分为开发环境,生产环境,测试环境等等,每个环境的配置可以是不一样的
environment就用来表示不同环境的细节配置,每一个环境中都需要一个事务管理器以及数据源的配置
我们在后续的项目开发中几乎都是使用spring中配置的数据源和事务管理器来配置,此处不需要研究
-->
<!--default:用来选择需要的环境-->
<environments default="development">
<!--id:表示不同环境的名称-->
<environment id="development">
<transactionManager type="JDBC"/>
<!--配置数据库连接-->
<dataSource type="POOLED">
<!--使用${}来引入外部变量-->
<property name="driver" value="${driverClassname}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--
在不同的数据库中,可能sql语句的写法是不一样的,为了增强移植性,可以提供不同数据库的操作实现
在编写不同的sql语句的时候,可以指定databaseId属性来标识当前sql语句可以运行在哪个数据库中
-->
<databaseIdProvider type="DB_VENDOR">
<property name="MySQL" value="mysql"/>
<property name="SQL Server" value="sqlserver"/>
<property name="Oracle" value="orcl"/>
</databaseIdProvider>
<!--将sql的映射文件适用mappers进行映射-->
<mappers>
<!--
指定具体的不同的配置文件
class:直接引入接口的全类名,可以将xml文件放在mapper的同级目录下,并且设置相同的文件名称,同时可以使用注解的方式来进行相关的配置
url:可以从磁盘或者网络路径查找sql映射文件
resource:在类路径下寻找sql映射文件
-->
<!--
<mapper resource="PersonDao.xml"/>
<mapper resource="FileDao.xml"/>
<mapper class="com.masenlin.mapper.CustomMapperAnnotation"></mapper>-->
<!--
当包含多个配置文件或者配置类的时候,可以使用批量注册的功能,也就是引入对应的包,而不是具体的配置文件或者类
但是需要注意的是,
1、如果使用的配置文件的形式,必须要将配置文件跟mapper类放在一起,这样才能找到对应的配置文件.
如果是maven的项目的话,还需要添加以下配置,原因是maven在编译的文件的时候只会编译java文件
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
2、将配置文件在resources资源路径下创建跟mapper相同的包名
-->
<package name="com.masenlin.mapper"/>
</mappers>
</configuration>
总结
本文介绍了 MyBatis 是什么及其优缺点,并且如何在项目中使用,对常用的配置做了简单的介绍。
评论区