一、数据持久层框架的发展历程
1、JDBC
- JDBC(Java Data Base Connection),是一种用于执行SQL语句的Java API,为多种关系型数据库提供了统一访问的方式,它由一组用Java语言编写的类和接口组成。JDBC提供了一种规范,可以其基础上构建更高级的工具和接口,使开发人员能够编写数据库应用程序。
- 特点:
- 优点:快捷、高效(运行期);
- 缺点:代码量大、繁琐、不支持数据库跨平台(编辑期);
- 核心API:
- DriverManager:连接数据库
- Connection:连接数据库的抽象
- Statement:执行SQL
- ResultSet:执行后的数据结果集
2、DBUtils
- DBUtils是Java编程中数据库操作的实用小工具,小巧简单实用;
- DBUtils封装了对JDBC的操作,简化了JDBC的操作过程,减少了冗余代码的编写;
- DBUtils三个核心的功能:
- QueryRunner中提供了对sql语句操作的API;
- ResultSetHandle接口,用于定义查询操作后,如何封装结果集;
- 它是一个工具类,定义了关闭资源与事务处理的方法;
3、Hibernate
- Hibernate是由Gavin King于2001年创建的开源的ORM框架。
- Hibernate将Java类映射到数据库表中,从Java数据类型映射到SQL数据类型中。
- Hibernate 是传统 Java 对象和数据库服务器之间的桥梁,用来处理基于 O/R 映射机制和模式的那些对象。
- 特点:
- 优点:
- Hibernate使用XML文件来处理映射Java类到数据库表中,并且不需要再编写任何其它代码;
- 为在数据库中直接检索和存储Java对象提供了简单的API;
- 如果数据库中的表结构有变化,只需要更新XML文件即可;
- 缺点:
- Hibernate的完全封装导致无法使用数据的一些功能;
- Hibernate对代码的耦合度太高;
- Hibernate在进行批量数据操作时,需要大量的内存空间且执行过程中涉及到的对象太多;
- 优点:
4、JDBCTemplate
- JdbcTemplate针对数据查询提供了多个重载的模版方法,你可以根据需要选择不同的模版方法。如果查询的很简单,仅仅只是调用对应的方法,传入相应的sql语句以及涉及到的参数,既可以获取一个单一的结果;
- 特点:
- 优点:高效、内嵌在Spring框架中,支持基于AOP的声明式事务;
- 缺点:必须与Spring框架结合使用,不支持数据库跨平台,默认没有缓存;
二、初识Mybatis
1、什么是Mybatis
-
MyBatis 是一款优秀的半自动化持久层ORM框架,它支持自定义SQL语句、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的XML文件或者注解的方式来配置和完成对象关系映射(具体指:类与数据库表的关系、类属性与表字段的关系)。
-
特点
- 优点:
- 简化了JDBC的开发,封装了繁杂冗余的JDBC操作,提高了开发的效率;
- 是一款简单易学的持久层框架;
- 将SQL从Java代码中分离了出来,降低了代码依赖的耦合度,且SQL可重用;
- 提供了XML标签,支持编写动态SQL;
- 提供了映射标签,支持对象与数据库的ORM关系映射;
- 支持缓存、数据库连接池等等;
- 缺点:
- SQL语句编写的工作量较大,且对开发人员编写SQL的能力要求较高;
- 对数据库的移植性较差;
- 优点:
2、Mybatis的核心组件
三、快速搭建入门
1、导入相关依赖
xml
<dependencies>
<!--Mybatis的核心jar包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!-- MySQL的依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<!--jUnit测试单元的依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
2、创建对应的数据库表
sql
CREATE TABLE `emp` (
`eid` int(11) NOT NULL AUTO_INCREMENT,
`e_name` varchar(50) DEFAULT NULL,
`e_mail` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`salary` decimal(10,2) DEFAULT NULL,
`did` int(11) DEFAULT NULL,
PRIMARY KEY (`eid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='员工表';
3、创建POJO实体类对象
java
public class Emp implements Serializable {
private Integer eId;
private String eName;
private String eMail;
private Double salary;
private Integer did;
//相关get和set方法
//声明构造方法
//重写toString()方法
}
4、创建对应的Mapper接口
java
public interface EmpMapper {
Emp selectEmpById(Integer id);
int insertEmp(Emp emp);
@Select("select * from emp where e_name=#{ename}")
Emp selectEmpByName(String ename);
}
5、编写mybatis的配置文件
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--配置外部属性资源文件,通过 ${} 来进行引用-->
<properties resource="db.properties">
<!--也可以在内部自定义属性-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/trs-db?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull"/>
<property name="username" value="root"/>
<property name="password" value="rootxq"/>
</properties>
<!--配置数据源连接信息-->
<environments default="development">
<environment id="development">
<!--事务管理器:type 设置事务管理类型
(1)JDBC:使用JDBC的事务管理方式
(2)MANAGED:不运用事务 -->
<transactionManager type="JDBC"/>
<!--数据源:type 设置数据源类型
(1)UNPOOLED:不使用连接池
(2)POOLED:使用Mybatis的连接池-->
<dataSource type="POOLED">
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
<!--配置映射器-->
<mappers>
<mapper resource="mapper/DeptMapper.xml"/>
<mapper resource="mapper/EmpMapper.xml"/>
</mappers>
</configuration>
6、编写xml映射文件
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.EmpMapper">
<select id="selectEmpById" resultType="org.example.pojo.Emp">
select * from emp where eid = #{id}
</select>
<insert id="insertEmp" >
insert into emp
(eid,e_name,e_mail,salary,did)
values
(#{eId},#{eName},#{eMail},#{salary},#{did})
</insert>
</mapper>
7、编写测试类
java
@Test
public void testMybatis(){
try {
// 根据mybatis全局配置文件来构建SqlSessionFactory
String config = "mybatis-config.xml";
InputStream resourceAsStream = Resources.getResourceAsStream(config);
//构建SqlSessionFactory(将配置文件信息和所有的mapper全部加载到Configuration中被缓存起来)
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获取SqlSession对象(负责执行具体的数据库操作)
/**
* 给openSession设置不同的参数会给SqlSession后续的数据库操作造成不同的影响:
* 1、boolean autoCommit:true表示开启自动提交(默认),false表示关闭自动提交(手动提交)
* 2、Connection connection:将在当前环境配置的 DataSource 实例中获取 Connection 对象
* 3、TransactionIsolationLevel level:事务隔离级别将会使用驱动或者数据源的默认设置
* 4、ExecutorType executorType:执行器类型,默认 SIMPLE,预处理语句是否复用、是否批量处理更新
*
*/
SqlSession sqlSession = sessionFactory.openSession(true);
//1、方式一:基于xml映射文件的原生方式(namespace + id)
Emp emp = sqlSession.selectOne("org.example.mapper.EmpMapper.selectEmpById", 1);
System.out.println(emp);
//2、方式二:基于接口绑定的方式(接口 + 方法名)
//Mybatis在底层会为接口创建一个代理对象(JDK动态代理),代理对象会实现接口中的方法,所以可以直接调用接口中的方法
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp empInfo = mapper.selectEmpById(1);
System.out.println(empInfo);
//3、方式三:基于注解的方式(接口 + 方法名)
Emp emp3 = mapper.selectEmpByName("WEZ");
System.out.println(emp3);
//插入数据
Emp emp2 = new Emp();
emp2.seteName("WEZZ");
emp2.seteMail("wezZ@163.com");
emp2.setSalary(10000.0);
emp2.setDid(1);
mapper.insertEmp(emp2);
System.out.println(emp2);
logger.info("测试成功");
} catch (IOException ioException) {
logger.error("测试失败");
}
}