框架概述
- 框架表现为一组抽象构件以及构件实例间交互的方法,是可被应用开发者定制的应用骨架;
- 通俗来说,框架是软件开发中的一套解决方案,不同的框架解决的是不同的问题,框架封装了很多的细节,使开发者可以使用简便的方式实现功能,从而大大提高开发效率。
- Mybatis 是在持久层应用的一种框架,内部封装了JDBC,屏蔽了JDBC Api底层访问细节,通过
xml
或注解的方式配置,采用ORM思想解决了实体和数据库的映射
; - Mybatis 通过 xml 或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 Mybatis 框架执行 sql 并将结果映射为 java 对象并返回;
- 实体类中的属性需要和数据库的字段名称保持一致
环境搭建
- IDEA创建
(1)创建maven项目,输入名称
(2)选择创建位置,即可创建完成
(3)创建数据库 - pom.xml配置
(1)添加打包方式<packaging>jar</packagiing>
(2)依赖导入
(3)数据库配置
(4)日志配置
(5)单元测试导入 - 创建实体类、主配置文件和各个Dao接口的映射配置文件
- 注意事项:
(1)Mybatis的映射配置文件必须和dao的接口在同一结构内即resources
和java
两个目录必须是一致的
(2)映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名
(3)映射配置文件的操作配置,id属性的取值必须是dao接口的方法名
(4)resources
文件目录下的文件夹要一个一个创建,不要在创建文件夹时直接写com.***.***.***
,会直接创建为一个一级目录而不是三级目录
SqlMapConfig.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">
<!-- mybatis的主配置文件 -->
<configuration>
<!-- 配置环境 -->
<environments default="mysql">
<!-- 配置mysql管径 -->
<environment id="mysql">
<!-- 配置事务的类型 -->
<transactionManager type="JDBC"/>
<!-- 配置数据源(连接池) -->
<dataSource type="POOLED">
<!-- 配置连接数据库的4个基本属性 -->
<!-- 有了这些便能创建Connection对象 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/databaseName"/>
<property name="username" value="Root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
<!-- 制定映射配置文件的位置 -->
<!-- 有了这些便能知道映射配置文件的信息 -->
<mappers>
<mapper resource="com/demo/dao/IUserDao.xml"/>
<!-- <mapper class="com.demo.dao.IUserDao"/> 使用注解则改成这个语句 -->
</mappers>
</configuration>
IUserDao.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">
<!-- 有了这些就有了执行的SQL语句
可以获取PreparedStatement
还有封装的实体类全限定类名,指定返回的对象类型
-->
<mapper namespace="********">
<!-- 配置查询所有 -->
<!-- resultType 表示指定返回的是哪一种对象 -->
<select id="findAll" resultType="IUserDao接口的路径">
select * from user
</select>
</mapper>
pom.xml 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>com.learn.mybatisDemo</groupId>
<artifactId>demo1_first_use</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<finalName>webapp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.2</version>
<configuration>
<source>12</source>
<target>12</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.30</version>
</dependency>
</dependencies>
</project>
入门案例
使用步骤
(1)读取配置文件
(2)创建SqlSessionFactory工厂
(3)使用工厂生产SqlSession对象
(4)使用SqlSession创建dao接口的代理对象
(5)使用代理对象的执行放阿飞
(6)释放资源
- 代码
// 1 读取配置文件
InputStream in = Resources.getResourceAsStream("配置文件路径")
// 2 创建SqlSessionFactory工厂
// Mybatis把工厂的创建细节封装在SqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
// 3 使用工厂生产SqlSession对象
SqlSession session = factory.openSession();
// 4 使用SqlSession创建dao接口的代理对象
IUserDao userDao = session.getMapper(IUserDao.class);
// 5 使用代理对象的执行方法
List<User> users = userDao.findAll();
for(User user:users){
SYstem.out.println(user);
}
// 6 释放资源
session.close();
in.close();
开发过程中的一些问题
- 读文件的路径
使用绝对路径会不灵活,使用相对路径在工程部署后一些文件结构会发生变动,因此一般在开发时采用类加载器
(只能读取类路径的配置文件)和使用ServletContex对象的getRealPath()
(获取当前应用部署的绝对路径) - 创建工厂Mybatis使用了构建者模式(类似于找个包工队帮你装修),builder就是构建者
- session的创建使用了工厂模式(要什么给什么),优势在于解耦,降低类之间的依赖关系
- getMapper中使用了代理模式,优势在于不修改源码的基础上对已有的方法增强
注解的使用方式
- 使用注解就不再需要映射配置文件了,移除即可
- 在dao方法中添加注解
- 在主配置文件的 mapper 标签中配置,使用 class 属性
核心配置文件
<!-- 使用注解配置,就要使用class属性制定被注解的dao的全限定类名 -->
<mappers>
<mapper class="类路径"/>
</mappers>
Dao
@Select("select * from user")
List<User> findAll(){
...
}
自定义dao接口的实现类
- Mybatis支持自定义实现类,但是没有意义,一般不采用,了解即可
public class UserDaoImpl implements IUserDao{
private SqlSessionFactory factory;
public UserDaoImpl (SqlSessionFactory factory){
this.factory = factory;
}
public List<User> findAll(){
//使用工厂创建SqlSession对象
SqlSession session = factory.openSession();
//使用session执行查询所有方法
List<User> users = session.selectList("xml中namespace的路径+id");
session.closr();
return users;
...
}
}
- 那么在使用的时候就不再需要使用代理对象
// 1 读取配置文件
InputStream in = Resources.getResourceAsStream("配置文件路径")
// 2 创建SqlSessionFactory工厂
// Mybatis把工厂的创建细节封装在SqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
// 3 使用工厂创建dao对象
IUserDao userDao = new UserDaoImpl(factory);
// 4 使用对象的执行方法
List<User> users = userDao.findAll();
for(User user:users){
SYstem.out.println(user);
}
// 5 释放资源
in.close();
-
其实这个实际开发基本不会采用,但是也要了解一下,主要是为了让大家了解 Mybatis 的执行细节,分析Mybatis在使用代理dao的方式实现增删改查时做的事情:
(1)创建代理对象
(2)在代理对象中调用selectList或其他方法 -
读取 xml 配置文件:用到解析XML的技术,此处用的是dom4j解析XML技术(解析技术有很多,了解即可);目的是给方法提供数据库连接信息和映射信息(包含执行的SQL语句和封装结果的实体类全限定类名)
-
要让方法能够执行,需要将映射信息封装,定义成一个Map对象,将接口类中要实现的方法和 xml 文件中的映射信息相对应,即 xml 文件中
mapper
标签中的内容 -
CRUD 方法中 Mybatis 执行流程:
(1)根据配置文件的信息创建Connection对象:注册驱动,获取连接
(2)获取预处理对象,此时需要SQL语句:conn.prepareStatement(sql)
就是从映射配置文件中获取
(3)执行CRUD操作:ResultSet rs = preparedStatement.executeQuery();
(4)遍历结果集进行封装:- 创建集合;
- 开始循环;
- 根据映射配置文件的返回类型创建对象
E element = (E) Class.forName(配置的全限定类名).newInstance();
; - 封装对象
封装的时候使用反射封装的方式根据名称获取每个属性并赋值,这也就是要求表的列名和实体类属性一致的原因
; - 将对象添加到集合;
- 继续下一个;
- 遍历结束退出返回集合;
(5)返回 list
创建代理对象的分析
// 4 使用SqlSession创建dao接口的代理对象
IUserDao userDao = session.getMapper(IUserDao.class);
- 方法实现过程
//根据Dao接口的字节码创建Dao的代理对象
public <T> getMapper(Class<T> daoInterfaceClass){
/*
类加载器:使用的和被代理对象是相同的类加载器
代理对象要实现的接口:和被代理对象实现相同的接口
如何代理:就是增强的方法,需要自己提供,此处是一个InvocationHandler的接口
我们需要写一个该接口的实现类,并在实现类中调用dao中的关于CRUD的方法
*/
Proxy.newProxyInstance(类加载器, 代理对象要实现的接口字节码数组,如何代理);
}
自定义Mybatis中能通过入门案例看到的类
- 类
(1)Resouce 使用类加载器读取配置文件的类
(2)SqlSessionFactoryBuilder 用于创建SqlSessionFactory对象
- 接口
(1)SqlSessionFactory 提供一个工厂
(2)SqlSession 和数据库交互的核心类,里面可以创建dao接口的代理对象