文章目录
一、MyBatis介绍
- 官网中给出的解释是:
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。 - MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
- MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
二、MyBatis原理
- 如果使用 Maven 来构建项目,则需将下面的依赖代码置于 pom.xml 文件中:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
- 从XML文件中构建SqlSessionFactory。每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
- 从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。 但也可以使用任意的输入流(InputStream)实例,比如用文件路径字符串或 file:// URL 构造的输入流。MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,使得从类路径或其它位置加载资源文件更加容易。
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- 从 SqlSessionFactory 中获取 SqlSession;
try (SqlSession session = sqlSessionFactory.openSession()) {
Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
}
使用和指定语句的参数和返回值相匹配的接口(比如 BlogMapper.class),现在你的代码不仅更清晰,更加类型安全,还不用担心可能出错的字符串字面值以及强制类型转换。
例如:
try (SqlSession session = sqlSessionFactory.openSession()) {
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
}
三、MyBatis的配置
- 除了给定MyBatis依赖之外,还要连接数据库,那就需要再导入数据库驱动:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
1、配置全局配置文件
- 首先在创建的项目中找到resource;
如果没有那就创建一个新建一个包,包名设置为resource;然后鼠标右键点击依次点击如下图,将这个包设置为Resource Root;
- 在这个resource下新建一个xml类型的文件,
打开文件在MyBatis官网中找到配置信息,然后再根据需要做出一点修改;
<?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.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
</configuration>
- 在main目录的java下创建POJO类,即创建一个包,命名为POJO,然后新建一个类为:Student.java,与数据库中的Student表数据映射为student对象,给定数据库中的属性名,注意属性名要与数据库中的属性要一一对应;
public class Student {
private Integer SID;//学生ID
private String Sname;//学生姓名
private String Ssex;//学生性别
private Integer Sage;//学生年龄
//省略getter和setter方法
}
- 然后再POJO包同一位置上新建一个mapper包,这个包用来存放我们创建的Mapper接口的文件;
public interface StudentMapper {
Student selectStudentById(Integer id);//通过学生的ID来进行检索
}
- 配置Mapper的xml文件,即在resource资源的目录下创建一个mapper包,在这个包下来存放我们创建的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.example.springBootDemo.TestMabits.mapper.StudentMapper">
<!--
当ResultType无法完成某些字段映射时,需要resultMap进行显性映射
resultMap标签主要用来显性指定返回映射关系
id:必填,表示去名称,可以随便取
type:必填,指定显性映射的java类的全限定名
id标签:指定主键映射关系,ID标签一般使用一次指定主键即可
result:指定非主属性映射关系,可以多次使用
property:指定java类中属性名(必填
column:指定数据库中的属性名称(必填
jdbcType:指定数据库中当前属性类型(选填
typeHandler:如果是有自定义类型处理器需要在这里指定自定义类型处理器的
-->
<resultMap id="studentMap" type="student">
<id property="SID" column="SID"/>
<result property="Sname" column="Sname"/>
<result property="Ssex" column="Ssex"/>
<result property="Sage" column="Sage"/>
</resultMap>
<!--
select标签是查询操作标签
id属性:(必填的)Statement的id,必填的,和接口文件中的方法名保持一致
parameterType:表述输入参数的类型(String,pojo,Integer)
resultType:(必填)表示输出参数的类型(String,pojo,Integer)还可以返回resultMap类型(返回的是hashmap)两种类型二选一
#{
XXX}:表示占位符 XXX:接口方法中的参数名称
-->
<select id="selectStudentById" parameterType="int" resultType="com.example.springBootDemo.TestMabits.pojo.StudentA">
select * from Student where SID =#{
sid}
</select>
<!-- id:在空间命名具有唯一性,和方法名保持一致
parameterType:指定入参的类型,可以是类的全限定名或者
-->
<insert id="insertStudent" flushCache="true" parameterType="student"/>
<select id="selectAllStudents" resultType="com.example.springBootDemo.TestMabits.pojo.Student">
select * from Student;
</select>
</mapper>
- 将mapper.xml文件的映射路径配置到全局配置文件中;
<!--映射文件-->
<mappers>
<!--resource属性,指定mapper.xml文件的路径-->
<mapper resource="mapper/StudentMapper.xml"/>
</mappers>
- 然后再新建一个测试类,用来通过java代码执行查询操作;
package com.example.springBootDemo.TestMabits;
import com.example.springBootDemo.TestMabits.mapper.StudentMapper;
import com.example.springBootDemo.TestMabits.pojo.Student;
import org.apache.ibatis.annotations.Delete;
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;
import java.util.Properties;
public class MybatisDemo {
public static void main(String[] args) throws IOException {
//1、创建SQLSessionFactory对象
//1.读取全局配置文件
String path="mybatis_config.xml";
//通过Resource获取文件流
InputStream resourceAsStream = Resources.getResourceAsStream(path);
//创建会话工厂,通过SQLSessionFactoryBUilder来创建
Properties properties = new Properties();
properties.setProperty("username","root");
properties.setProperty("password","123456");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream,properties);
// 创建会话,会话工厂是用来读取全局配置文件,通过builder类来创建
// 通过读取配置文件来创建实例,一般配置文件读取依次即可
// 对数据库CRUD操作
// SQLSession是线程不安全的,将其设置为方法的局部变量
// 以及缓存是基于SQLSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过代理模式创建代理类
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
// Student student = studentMapper.selectStudentById(4);
// System.out.println(student);
List<Student> students=studentMapper.selectAllStudents();
for (Student s:students) {
System.out.println(s);
}
}
}
运行结果:
- MyBatis的操作流程
- 配置MyBatis的全局配置文件(数据源,mapper映射)
- 创建SQLSessionFactory对象;
- 通过SQLSessionFactory创建SQLSession对象;
- 通过SQLSession来操作数据库CRUD操作;
- 关闭SQLSession资源;
2、XML配置
- MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:
1、Properties
- 这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。例如:
<properties resource="db.properties">
<property name="username" value="root"/>
<property name="password" value="123456"/>
</properties>
- 在其中对应的属性可以用来提花为需要的动态配置的属性值,比如:
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
- 这个例子中的 username 和 password 将会由 properties 元素中设置的相应值来替换
如果一个属性在不只一个地方进行了配置,那么,MyBatis 将按照下面的顺序来加载:
- 首先读取在 properties 元素体内指定的属性。
- 然后根据 properties 元素中的 resource 属性读取类路径下属性文件,或根据 url 属性指定的路径读取属性文件,并覆盖之前读取过的同名属性。
- 最后读取作为方法参数传递的属性,并覆盖之前读取过的同名属性。
因此,通过方法参数传递的属性具有最高优先级,resource/url 属性中指定的配置文件次之,最低优先级的则是 properties 元素中指定的属性。
2、setting
- 这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。
3、typeAliases(类型别名)
- 类型别名是Java类型的短名称,和XML配置有关,存在是在于用来减少类全限定名的冗余,在mapper.xml中,会有很多的Statement,Statement需要的parameterType指定入参类型,需要resultType执行输出参数类型,如果是指定类型需要书写全限定名,不方便开发,可以通过类型别名,较少代码冗余
<!--类型别名-->
<typeAliases>
<!--单个类型定义别名: type:pojo全路径 alias:别名的名称-->