今天我们来学习一下Mybatis,我们先简单介绍一下MyBatis。MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
按我来说,他就是可以帮助我们不用jdbc那么多繁琐的代码,比较简洁的去映射出数据库的记录。
那我们就开始这个程序吧!
需求
我想查询我数据库test中dept表中deptno为10的记录
准备工具
在开始之前我们需要准备两个工具包,一个是MyBatis工具包,一个是数据库驱动包。
mybatis-3.2.2.jar //MyBatis工具包
mysql-connector-java-5.1.30-bin.jar //数据库驱动包
这里我准备的是这两个版本的,你可以根据你的软件版本和window版本下载自己对应的工具包。
MyBatis下载https://github.com/mybatis/mybatis-3/releases
建立java工程
把我们刚刚准备好的两个工具包导入到项目中去。
导入之后还不够,你要检查一下,他是否加入到项目中了,如果没有,你就需要手动添加到项目中。如果导入成功,在Referenced Libraries文件夹中就会有你导入的两个工具包。
建立工程包pojo
我们建一个pojo包,并在pojo包中创建一个Dept类,用来装数据库表中的字段,成为一个对象。创建他的属性,构造方法,get,set方法,toString方法。属性名要与表中的字段名一样,属性类型要和表中的字段类型一样。
路径:src/pojo/Dept.java
public class Dept {
private int deptno;
private String dname;
private String loc;
//无参构造函数
public Dept() {
super();
}
//有参构造函数
public Dept(int deptno, String dname, String loc) {
super();
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
}
//toString方法
@Override
public String toString() {
return "Dept [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + "]";
}
//get和set方法
public int getDeptno() {
return deptno;
}
public void setDeptno(int deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
}
创建工程包Mapper,并创建sql映射文件DeptMapper.xml
路径:src/mapper/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">
<mapper namespace="mapper.DeptMapper">
<select id="selectDeptByDeptno" parameterType="int" resultType="pojo.Dept">
select * from dept where deptno = #{id}
</select>
</mapper>
注释:
namespace:包路径+pojo名 +Mapper,它的值必须唯一的。
1、<select></select>查询语句 <update> <insert> <delete>
2、id:唯一标识,见名知意
3、parameterType:参数类型
a.如果是基本数据类型,直接写对应的类型即可
b、如果是对象,就必须写完全限定名(类路径)
4、resultType:语句的返回类型
a.如果是基本数据类型,直接写对应的类型即可
b、如果是对象,就必须写完全限定名(类路径)
5、sql语句,如果有参数,写在#{}
a .如果参数是基本数据类型,#{ }里面可以随便写
b.如果是对象,#{ }必须是对象的属性名称
我这里的id给他取了一个名字叫selectDeptByDeptno,因为我要查询的deptno是int类型,所以我写的是int。我要返回的类型是一个dept对象,所以我这里写的是类路径(dept类的路径)。sql语句我写的是我要查询的语句(查询dept表中deptno为多少的所有信息)
创建配置文件MyBatis.xml
我这里单独创了一个文件夹存放配置文件,便于以后我们的使用。
路径:config/mybatis/mybatis.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.jdbc.Driver" />
<!-- 数据库网址和端口号和数据库名-->
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<!-- 数据库用户名-->
<property name="username" value="root" />
<!-- 数据库密码-->
<property name="password" value="" />
</dataSource>
</environment>
</environments>
<!-- 映射文件的路径 -->
<mappers>
<mapper resource="mapper/DeptMapper.xml" />
</mappers>
</configuration>
我在代码中做了解释,这里就不讲解了。
测试代码
以上代码就写完了,我们要来测试一下他是否可以运行成。
public class Demo01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String resource = "mybatis/mybatis.xml"; //配置文件的路径
Reader reader = null;
SqlSessionFactory sqlMapper = null;
SqlSession session = null;
try {
//读取配置文件
reader = Resources.getResourceAsReader(resource);
sqlMapper = new SqlSessionFactoryBuilder().build(reader);
//获取SqlSession
session = sqlMapper.openSession();
//第一个参数是映射文件的namespace+id,第二个是要查询的参数
Dept dept = session.selectOne("mapper.DeptMapper.selectDeptByDeptno", 10);
System.out.println(dept);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(session!=null){
session.close();
}
}
}
}
把要查询的参数信息封装成一个对象,然后返回这个对象。这里可能会报错,所以用try…catch。启动了SqlSessin,最后也要把他关闭了。
这样子,所有代码就完成了,我们来看一下最后的运行结果。
和我们数据库表中的数据信息是一样的,所以这个程序就成功了。
我们来总结一下MyBatis的优缺点。 优点:
1. 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
2. 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
3. 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
4. 提供映射标签,支持对象与数据库的orm字段关系映射
5. 提供对象关系映射标签,支持对象关系组建维护
6. 提供xml标签,支持编写动态sql。
缺点:
1. 编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。
2. SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。
3. 框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。
4. 二级缓存机制不佳
功能架构
我们把Mybatis的功能架构分为三层:
(1)API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
(2)数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
(3)基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
框架架构
框架架构讲解:
(1)加载配置:配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
(2)SQL解析:当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。
(3)SQL执行:将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果。
(4)结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,并将最终结果返回。
如果还不懂的话可以去看一下下面的文档
参考文档:W3Cschool https://www.w3cschool.cn/mybatis/