MyBatis 是 GitHub 中一个开源项目,要下载 MyBatis 文件,首先百度搜索 GitHub 官网并点击打开
打开之后界面如下,用左上角的搜索框,输入 MyBatis 进行搜索
点击箭头所指的链接
打开之后,拉到最下方,有一个 download latest ,点击打开。
下载最新版本的压缩(zip)文件
下载完之后,解压 mybatis.zip 文件到常用目录下,以备使用
打开 Navicat,在鼠标右键点击连接,点击新建数据库,创建如下图所示数据库
创建完数据库,鼠标右键单击表这个目录,点击设计表,为表设计如下4个字段,并令id为主键
设计完表后,点击保存,令其名称为student,并为此表添加两个数据
点击New —> Project —> Maven 由于我们第一个Maven项目不是web项目,直接用qucikstart这个模板创建就行
点击 next 更改项目名和项目坐标,如下图所示
更改完之后点击 next ,为此项目配置本地 Maven 和 重新设定本地仓库的地址
配置好之后,点击 Finish。开始项目的构建,构建过程可能时间较长,可以为Maven 配置阿里云镜像减少构建时间
项目结构如下,IDEA默认创建了App与AppTest类文件,在此我们用不到,把他们删掉即可。
在pom.xml文件中,添加所要用到的mybatis和mysql-connector依赖,如果报红,点击右边的reload按钮刷新即可
添加的依赖代码如下
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.1version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.25version>
dependency>
添加如下图所示代码,此段代码的作用是在编译时能够扫描到main目录下的所有配置文件
扫描插件代码如下
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.xmlinclude>
<include>**/*.propertiesinclude>
includes>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.xmlinclude>
<include>**/*.propertiesinclude>
includes>
resource>
resources>
在domain包下创建Student实体类,作为student表结构的映射,成员变量与表中字段保持一致,生成构造方法及setter和getter方法。
代码如下
package com.fancy.domain;
public class Student {
private Integer id;
private String name;
private String email;
private Integer age;
public Student() {
}
public Student(Integer id, String name, String email, Integer age) {
this.id = id;
this.name = name;
this.email = email;
this.age = age;
}
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 String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
在dao包下创建StudentDao接口,用以完成对于对表的增删改查操作,在此我们先写一个实现查询功能的抽象方法,返回值为List
代码如下
package com.fancy.dao;
import com.fancy.domain.Student;
import java.util.List;
public interface StudentDao {
List<Student> selectStudents();
}
Mapper 映射文件又叫 sql映射文件,是用来写 sql 语句的,mybatis会执行其中的sql
模板:
<?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>
1.指定约束文件
<?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">
2.约束文件作用
3.mapper当前文件的根标签,是必须存在的
:表示执行查询,放的是select语句
:表示更新数据库的操作,标签里面放update语句insert>
:表示插入操作,里面放入insert语句
:表示删除,执行的是delete语句由于IDEA中无法直接创建普通的xml文件,我们可以通过new —> file 然后加上.xml后缀名的形式
也可以在settings —> Editor —> File and Code Templates 中配置mapper文件模板,然后进行新建就有mapper文件
新建完模板后直接使用就行,只需在模板中再填代码就行
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fancy.dao.StudentDao">
<select id="selectStudents" resultType="com.fancy.domain.Student">
select id, name, email, age from student;
select>
mapper>
标签中 id 与 resultType
模板
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydatabase?useUnicode=true&characterEncoding=utf-8&serverTimeZone=UTC"/>
<property name="username" value="root"/>
<property name="password" value=""/>
dataSource>
environment>
environments>
<mappers>
<mapper resource=""/>
mappers>
configuration>
1.指定约束文件
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
mybatis-3-config.dtd : 约束文件名称
2.根标签 :
3.环境配置 : `
配置数据库的连接信息4.数据库信息配置 :
一个数据库信息的配置、环境5.事务类型 :
表示 mybatis 事务类型6.数据源 :
表示数据源,标签之中放连接数据库的所需要的属性名称7.
中的resource属性用来告诉mybatis要执行的sql语句的位置,用类路径来写
我们同样可以像写mapper映射文件那样,在setting里创建mybatis-config.xml的模板
然后在之前创建的模板中填写相关代码就行,比如password,StudentDao.xml路径等
代码如下
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf-8&serverTimeZone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="aszhuo123"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/fancy/dao/StudentDao.xml"/>
mappers>
configuration>
在src ----> test ----> java 目录下创建MyBatisTest测试类用于对于我们上述代码进行检测,以及学习如何使用mybatis来执行对于数据库的操作
代码如下,以下的代码展示了使用MyBatis的主要流程,稍后我们会对流程作具体的介绍
package com.fancy;
import com.fancy.domain.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;
import java.util.List;
public class MyBatisTest {
@Test
public void testStart() throws IOException {
//1. mybatis主配置文件
String config = "mybatis-config.xml";
//2. 读取配置文件
InputStream in = Resources.getResourceAsStream(config);
//3. 创建SqlSessionFactory 对象, 目的是获取SqlSession
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//4. 创建SqlSession, SqlSession能够执行sql语句
SqlSession session = factory.openSession();
//5. 执行SqlSession的 selectList()
List<Student> studentList = session.selectList("com.fancy.dao.StudentDao.selectStudents");
//6. 循环输出查询结果 lamda表达式
studentList.forEach(student -> System.out.println(student));
//7. 关闭SqlSession,释放资源
session.close();
}
}
mybatis.xml 文件加入日志配置,可以在控制台输出执行的 sql 语句和参数
日志配置代码如下
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
settings>
然后我们在mybatis-config.xml中加入代码,发现放在后面代码报红,然后鼠标悬停在
标签上,发现放置标签的先后顺序如下图所示。按照提示,将
放在合法位置即可。
点击右侧 Maven ----> test 按钮,测试结果如下
int insertStudent(Student student);
<insert id="insertStudent">
insert into student(id, name, email, age)
values (#{id}, #{name}, #{email}, #{age})
insert>
在 mybatis 的配置映射文件中,动态传递参数有两种方式:
(1) #{},参数占位符,即 sql 预编译
(2) ${},字符串替换,即 sql 拼接
这两者就类似于JDBC中的 PreparedStatement 与 Statement
@Test
public void testInsert() throws IOException {
//1. mybatis 主配置文件
String config = "mybatis-config.xml";
//2. 读取配置文件
InputStream in = Resources.getResourceAsStream(config);
//3. 创建 SqlSessionFactory 对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//4. 获取 SqlSession
SqlSession session = factory.openSession();
//5. 创建保存对象的数据
Student student = new Student(5, "Hell", "[email protected]", 20);
//6. 执行插入insert
int rows = session.insert("com.fancy.StudentDao.insertStudent", student);
//7. 提交事务
session.commit();
//8. 关闭SqlSession
System.out.println("增加的记录" + rows);
session.close();
}
int updateStudent(Student student);
<update id="updateStudent">
update student set age = #{age} where id = #{id}
update>
@Test
public void testUpdate() throws IOException {
//1. mybatis 主配置文件
String config = "mybatis-config.xml";
//2. 创建 SqlSessionFactory 对象
InputStream in = Resources.getResourceAsStream(config);
//3. 创建 SqlSessionFactory 对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//4. 获取SqlSession
SqlSession session = factory.openSession();
//5. 创建保存数据的对象
Student student = new Student();
student.setId(5);
student.setAge(30);
//6. 执行更新update
int rows = session.update("com.fancy.dao.StudentDao.updateStudent", student);
//7. 提交事务
session.commit();
System.out.println("修改记录的行数:" + rows);
//8. 关闭SqlSession
session.close();
}
int deleteStudent(int id);
<delete id="deleteStudent">
delete from student where id = #{studentId}
delete>
@Test
public void testDelete() throws IOException {
//1. mybatis主配置文件
String config = "mybatis-config.xml";
//2. 读取配置文件
InputStream in = Resources.getResourceAsStream(config);
//3. 创建SqlSessionFactory 对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//4. 获取SqlSession
SqlSession session = factory.openSession();
//5. 删除的id
int id = 5;
//6. 执行删除delete
int rows = session.delete("com.fancy.dao.StudentDao.deleteStudent", id);
//7. 提交事物
session.commit();
System.out.println("修改记录的条数:" + rows);
//8. 关闭SqlSession
session.close();
}
(1) Resources 类
Resources 类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返回不同类型的 IO 流对象。注意 Resources 是在 org.apache.ibatis.io 包下的
(2) SqlSessionFactoryBuilder 接口
SqlSessionFactory 的 创 建 , 需 要 使 用 SqlSessionFactoryBuilder 对 象 的 build() 方 法 。 由 于SqlSessionFactoryBuilder 对象在创建完工厂对象后,就完成了其历史使命,即可被销毁。所以,一般会将该 SqlSessionFactoryBuilder 对象创建为一个方法内的局部对象,方法结束,对象销毁。
(3) SqlSessionFactory 接口
SqlSessionFactory 接口对象是一个重量级对象(系统开销大的对象),是线程安全的,所以一个应用只需要一个该对象即可。创建 SqlSession 需要使用 SqlSessionFactory 接口的openSession()方法。
➢ openSession(true):创建一个有自动提交功能的 SqlSession
➢ openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交
➢ openSession():同 openSession(false)
(4) SqlSession 接口
SqlSession 接口对象用于执行持久化操作。一个 SqlSession 对应着一次数据库会话,一次会话以SqlSession 对象的创建开始,以 SqlSession 对象的关闭结束。
SqlSession 接口对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其 close()方法,将其关闭。再次需要会话,再次创建。 SqlSession 在方法内部创建,使用完毕后关闭。
package com.fancy.utility;
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.InputStream;
public class MyBatisUtil {
private static SqlSessionFactory factory = null;
static {
try {
String config = "MyBatis-config.xml";
InputStream in = Resources.getResourceAsStream(config);
factory = new SqlSessionFactoryBuilder().build(in);
} catch (Exception e) {
factory = null;
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
SqlSession session = null;
if (factory != null) {
session = factory.openSession();
}
return session;
}
}
@Test
public void testUtils() throws IOException {
SqlSession session = MyBatisUtil.getSqlSession();
List<Student> studentList = session.selectList("com.fancy.dao.StudentDao.selectStudents");
studentList.forEach(student -> System.out.println(student));
session.close();
}
例如,使用传统 Dao 开发方式来实现查询操作
package com.fancy.dao;
import com.fancy.domain.Student;
import com.fancy.utility.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class StudentDaoImpl implements StudentDao{
@Override
public List<Student> selectStudents() {
SqlSession session = MyBatisUtil.getSqlSession();
List<Student> studentList = session.selectList("com.fancy.dao.StudentDao.selectStudents");
session.close();
return studentList;
}
}
public class MyBatisTest {
StudentDao studentDao = new StudentDaoImpl();
@Test
public void testSelect() throws IOException {
final List<Student> studentList = studentDao.selectStudents();
studentList.forEach( stu -> System.out.println(stu));
}
}
在前面例子中自定义 Dao 接口实现类时发现一个问题:Dao 的实现类其实并没有干什么实质性的工作,它仅仅就是通过 SqlSession 的相关 API 定位到映射文件 mapper 中相应 id 的 SQL 语句,真正对 DB 进行操作的工作其实是由框架通过 mapper 中的 SQL 完成的。所以,MyBatis 框架就抛开了 Dao 的实现类,直接定位到映射文件 mapper 中的相应 SQL 语句,对DB 进行操作。这种对 Dao 的实现方式称为 Mapper 的动态代理方式。Mapper 动态代理方式无需程序员实现 Dao 接口。接口是由 MyBatis 结合映射文件自动生成的动态代理实现的。
详情见下一篇文章。