mybatis(sql映射框架)
是MyBatis SQL Mapper Framework for java
sql mapper : sql 映射
- 可以把数据库表中的一行数据 映射为一个java对象
- 一行数据可以看做是一个java对象
- 操作这个对象就相当于操作表中的数据
Data Access Objects (Daos) ; 数据访问
- 对数据库中执行增删改查
mybatis提供那些功能
- 提供了创建 Connection , Statement , ResultSet 的能力 , 不用开发人员创建这些对象了
- 提供了执行SQL语句的能力 , 不用你再执行sql
- 提供了循环sql , 把sql的结果转为list集合的能力
- 提供了关闭资源的能力,不用你再去关闭资源了
开发人员只需要提供sql语句即可
最后是 : 开发人员提供sql语句 — mybatis处理sql — 开发人员得到List集合或java对象 (表中的数据)
总结 :
MyBatis是一个sql映射框架 , 提供的数据库操作能力 , 可以看成是一个增强的JDBC
使用Mybatis 让我们的开发人员集中精神写sql即可 , 不必关心Connection , Statement , ResultSet 创建的创建 , 销毁 ,使用
使用步骤:
- 新建一个表 Student
- 加入maven的MyBatis坐标 , mysql驱动的坐标
- 创建实体类 Student – 保存表中的一行数据
- 创建持久层的Dao接口 , 定义操作数据库的方法
- 创建一个MyBatis使用的配置文件
- 叫做sql映射问文件 : 写SQL语句的 ,一般一个表一个SQL映射文件
- 这个文件是 .xml 文件
- 文件写在接口所在的目录中 , 文件的名称和接口保持一致
- 创建MyBatis的主配置文件
- 一个项目中就一个主配置文件
- 主配置文件提供了数据库的链接信息和SQL映射文件的位置信息
- 创建使用MyBatis的类
- 通过MyBatis访问数据库
SQL映射文件的编写
<!--
sql映射文件 : 写sql语句的 , mybatis会执行这些sql
1.指定约束文件
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
mybatis-3-mapper.dtd 是约束文件的名称 , 扩展名是dtd的
2.约束文件的作用 : 限制,检查在当前文件中出现的标签,属性必须符合mybatis的要求
4.在当前文件中可以使用特定的标签 , 表示数据的特定操作
<select> : 表示执行查询 , 只能执行select语句
<update> : 表示更新数据库的操作,在标签中只能写update语句
<insert> : 表示插入 , 放的是insert语句
<delete> : 表示删除 , 执行的是delete语句
-->
<?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">
<!--
3.mapper是当前文件的根标签,必须的
namespace : 叫做命名空间,唯一值的,可以是自定义的字符串
要求你使用dao接口的全限定名称(绝对路径 , 包名加类名)
-->
<mapper namespace="org.sichen.dao.StudentDao">
<!--
select : 表示查询操作
id : 表示你要执行sql的语句的唯一标识
mybatis会使用这个id的值来找到要执行的SQL的语句
可以自定义 , 但是要求你是用接口中的方法名
resultType : 表示结果类型的 ,
是SQL语句执行后得到的ResultSet , 遍历这个ResultSet得到java对象的类型
规定查询出来的数据的类型
值就是类型的全限定名称
-->
<select id="findAll" resultType="org.sichen.domain.Student">
select id,name,email,age from student order by id;
</select>
<insert id="insertStudent">
<!--这里使用 #{} 一种占位符 里边写插入数据类型对应bean中的属性名-->
insert into student values(#{id},#{name},#{email},#{age});
</insert>
</mapper>
主配置文件的编写:
<?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 : 加s说明可以有多个数据库的配置信息
环境配置 : 就是数据库的配置信息
default : 必须和某个environment的id值一样
告诉mybatis使用那个数据库的连接信息,也就是访问那个数据库-->
<environments default="development">
<!-- environment : 一个数据库信息的配置 , 环境
id : 是一个唯一值 , 是一个自定义的 , 是用来表示环境的名称的-->
<environment id="development">
<!-- transactionManager : mybatis的事务类型
type : 值有两个
JDBC (表示使用jdbc中的connection对象的commit,rollback做事务处理) -->
<transactionManager type="JDBC"/>
<!--dataSource 代表数据源,连接数据库的
type : 表示数据库的类型
POOLED : 表示使用连接池-->
<dataSource type="POOLED">
<!--配置数据库的具体信息的
这些值是固定的,不能自定义,-->
<!--driver : 数据库的驱动类名-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!--连接数据库的url字符串-->
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC"/>
<!--访问数据库的用户名称-->
<property name="username" value="root"/>
<!--访问数据库的用户密码-->
<property name="password" value="acpl159357"/>
</dataSource>
</environment>
</environments>
<!--mapper: 指定sql映射文件的位置
从类路径开始的路径信息
也就是从编译后的classes目录下的路径开始的(如下图所示),
默认情况下,编译后不会保留配置文件 , 需要在pom.xml文件中加一个编译的插件
-->
<mappers>
<mapper resource="org/sichen/dao/StudentDao.xml"/>
</mappers>
</configuration>
编译时保留配置文件的插件:
<build>
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties , .xml文件都会被扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
使用:
//访问mybatis读取student数据
//1.定义mybatis的主配置文件的名称 ,
//从类路径的根开始(target/classes , 不用写这个路径,是默认从这个路径开始找的)
String config = "mybatis.xml";
//2.读取这个config表示的文件
InputStream in = Resources.getResourceAsStream(config);
//(要使用org.apache.ibatis.io这个包下的文件)
//3.创建了SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//4.创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
//5.[重要的]获取SqlSession对象 , 从SqlSessionFactory中获取SqlSession
SqlSession sqlSession = factory.openSession();
//6.[重要的]指定要执行的sql语句的标识 , sql映射文件中的namespace + "." + 标签的id值
String sqlId = "org.sichen.dao.StudentDao" + "." + "findAll";
//7.执行SQL语句,通过sqlId来找到语句
List<Student> studentList = sqlSession. selectList(sqlId);
//8.输出结果(这个是jdk8才有的新功能)
studentList.forEach(stu -> System.out.println(stu));
//9.关闭SqlSession对象
sqlSession.close();
注意:
MyBatis默认不是自动提交事务的
所以在执行增删改之后,要手工提交事务
sqlSession.commit();
主要的类的介绍:
String config = "mybatis.xml";
InputStream in = Resources.getResourceAsStream(config);
/*
Resources : mybatis中的一个类 , 负责读取主配置文件
*/
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
/*
SqlSessionFactoryBuilder : 提供一个方法 build
通过读取配置文件,去创建一个SqlSessionFactory
SqlSessionFactory : 重量级对象 , 程序创建一个对象耗时比较长,使用资源比较多
在整个项目中创建一个就够了
它本身是一个接口
接口的实现类 : DefaultSqlSessionFactory
DefaultSqlSessionFactory作用 : 获取SqlSession对象
*/
SqlSession sqlSession = factory.openSession();
/*
openSession()方法说明 :
openSession(): 无参的 , 获取的是非自动提交事务的SqlSession对象
openSession(boolean): 值为true: 获取的是自动提交事务的SqlSession对象
SqlSession 接口说明 :
定义了操作数据库的方法
例如 : selectOne() , selectList() , insert() , update() , delete() , commit() ,
rollback()
SqlSession 的实现类 : DefaultSqlSession
使用要求 :
SqlSession对象不是线程安全的,需要在方法内部使用 ,
在执行sql语句之前 , 使用openSession()获取SqlSession对象 ,
在执行sql语句之后 , 需要关闭它 , 执行SqlSession.close();
*/
String sqlId = "org.sichen.dao.StudentDao" + "." + "findAll";
List<Student> studentList = sqlSession. selectList(sqlId);
studentList.forEach(stu -> System.out.println(stu));
sqlSession.close();
使用工具类封装重复操作 :
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 MyBatisUtils {
private static SqlSessionFactory factory = null;
static {
String config = "mybatis.xml";
try {
InputStream in = Resources.getResourceAsStream(config);
//一步到位直接获取SqlSessionFactory , 省略了创建SqlSessionFactoryBuilder过程
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
//外界获取SqlSession的方法
public static SqlSession getSqlSession() {
SqlSession sqlSession = null;
if (factory != null) {
sqlSession = factory.openSession();
}
return sqlSession;
}
}
使用动态代理来执行SQL语句:(非常重要)
也就是不用再创建实现类了 , mybatis根据你的dao调用的方法 , 这一条语句 , 获取你的全限定名称 , 还有调用的方法 , 以及 确定调用的是哪一个SqlSession的方法
StudentDao studentdao = new StudentDaoImpl();
/**
* StudentDao studentdao = new StudentDaoImpl();调用
* 1.dao对象 , 类型是StudentDao , 全限定名称是 : com.sichen.dao.StudentDao
* 全限定名称和 namespace 是 一样的
*
* 2.方法名称 : findAll , 这个方法就是mapper文件中的 id值 findAll
*
* 3.通过dao中方法的返回值也可以确定MyBatis要调用的SqlSession方法
* 如果返回值是list , 调用的是SqlSession.selectList()方法
* 如果返回值是 int , 或是非list的 , 看mapper文件中的标签是<insert> <update> 就会调用
* SqlSession的insert , update等方法
*
* MyBatis的动态代理
* mybatis框架根据dao的方法调用 , 获取执行sql语句的信息
* mybatis根据你的Dao接口 , 创建出一个Dao接口的实现类 , 并创建这个类的对象 ,
* 来完成SqlSession 调用方法 , 访问数据库
*/
List<Student> StudentList = studentdao.findAll();
以前写的时候 ,还需要创建实现类 , 将接口实例化 , 然后调用实现类中的方法 , 完成操作 ,
现在只需要写一个dao接口
/**
* 使用mybatis的动态代理的机制 , 使用SqlSession.getMapper(dao接口.class)
* getMapper 能够获取dao接口对于实现类的对象
* 这个是Mybatis使用动态代理的方式 , 自己实现的 , 我们只需要传递这个接口的class类型 , 就可以创建出一个实现类对象 , 调用其中的方法
*/
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//调用dao的方法 , 执行数据库的操作
List<Student> all = dao.findAll();
for (Student student : all) {
System.out.println(student);
}
实现类的对象
- 这个是Mybatis使用动态代理的方式 , 自己实现的 , 我们只需要传递这个接口的class类型 , 就可以创建出一个实现类对象 , 调用其中的方法
*/
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//调用dao的方法 , 执行数据库的操作
List all = dao.findAll();
for (Student student : all) {
System.out.println(student);
}
---