什么是MyBatis?
MyBatis是一款优秀的持久层框架,用于简化JDBC开发,它支持自定义 SQL、存储过程以及高级映射。
持久层
负责将数据保存到数据库的那一层代码
JavaEE三层架构:表现层(页面展示)controller、业务层(逻辑处理)service、持久层dao。
JDBC不足分析
在学习MyBatis框架之前,我们先来看一下原生JDBC在操作数据库方面存在的不足,代码如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
publicclassJdbcDemo{
publicstaticvoidmain(String[] args) throws Exception {
// 1.加载数据库驱动, 底层自动会将驱动注册到驱动管理器中
Class.forName("com.mysql.jdbc.Driver");
// 2.通过驱动管理器获取连接对象
Connection conn =
DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?
useUnicode=true&characterEncoding=utf8", "root", "root");
// 3.编写SQL语句
String sql = "select id, name from user where id > ?";
// 4.通过连接对象获取SQL语句执行对象
PreparedStatement ps = conn.prepareStatement(sql);
// 5.设置占位符
ps.setInt(1, 2);
// 6.执行SQL语句, 返回结果集对象
ResultSet rs = ps.executeQuery();
// 7.解析结果集
List<User> users = newArrayList<>();
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
String password = rs.getString("password");
int age = rs.getInt("age");
User user = newUser();
user.setId(id);
user.setName(name);
user.setPassword(password);
user.setAge(age);
users.add(user);
}
for (User user : users) {
System.out.println(user);
}
// 8.释放资源
rs.close();
ps.close();
conn.close();
}
}
通过观察原生JDBC代码不难发现如下问题:
每次执行SQL语句都需要获取连接对象, 影响整个数据库的性能。
SQL语句都是直接编写在Java代码中, SQL和Java的耦合性过高, 如果SQL语句发生修改, 那么就需要修改源代码,不满足开闭原则, 希望能够通过配置文件来修改 SQL 。
设置占位符麻烦, 参数类型也很麻烦, 修改占位符参数的值也需要修改源码。
ResultSet结果集的解析和数据的封装很麻烦, 针对不同的表不同的列,不同值都需要做处理,对Java开发人员要求极高。
MyBatis框架的优点
通过配置的方式配置数据库连接池, 其实你可以不用管连接池,因为MyBatis内置了连接池,后期也可以通过Spring框架来整合第三方数据库连接池,例如c3p0, druid等。
通过配置(XML/注解)的方式配置SQL语句。
框架底层还会自动解析结果集封装到对应的JavaBean中。
MyBatis中支持事务, 但是事务后期会交给Spring容器管理, 后面学习Spring框架的时候学习。
在MyBatis框架中,提供了一个最为核心的功能,框架让开发者不需要编写dao接口的实现类, 底层会通过动态代理创建接口的实现类. 对于开发中来说只需要会编写SQL语句就好了,从而极大程度提高了开发的效率以及代码的可读性,扩展性和维护性。
MyBatis入门
Maven的pom.xml添加依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
从 XML 中构建 SqlSessionFactory
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。
SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。
SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
从 XML 配置文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。 但也可以使用任意的输入流(InputStream)实例,MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,使得从类路径或其它位置加载资源文件非常方便,构建SqlSessionFactory 对象代码如下:
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
mybatis-config.xml配置文件中,包含了对 MyBatis 系统的核心设置,这里罗列一些最关键的配置:
获取数据库连接实例的数据源(DataSource),即数据库连接池。
决定事务作用域控制方式的事务管理器(TransactionManager)。
映射器,这些映射器的 XML 映射文件包含了 SQL 代码和映射定义信息
这里给出一个简单的示例配置代码,如下所示:
<?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/mybatis?
useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/xyr/dao/UserMapper.xml"/>
</mappers>
</configuration>
构建SqlSession
既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL语句。例如:
try (SqlSession session = sqlSessionFactory.openSession()) {
UserMapper mapper = session.getMapper(UserMapper.class);
User u = mapper.selectUserById(2);
}
SQL映射配置
MyBatis支持以下两种方式来配置dao方法和SQL的映射,一种是XML配置,一种是注解配置,我们先看看 XML 定义语句的方式,事实上 MyBatis 提供的所有特性都可以利用基于 XML 的映射语言来实现。这里给出一个基于 XML 映射语句的示例,它应该可以满足上个示例中 SqlSession 的调用。配置如下所示:
<?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="com.xyr.dao.UserMapper">
<select id="selectUserById" parameterType="int"resultType="com.xyr.domain.User">
select * from user where id = #{id}
</select>
</mapper>
MyBatis入门案例
导入依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!--日志依赖-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
创建t_user表
创建实体类
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
private String sex;
private String email;
public User() {
}
public User(Integer id, String username, String password, Integer age, String sex, String email) {
this.id = id;
this.username = username;
this.password = password;
this.age = age;
this.sex = sex;
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", email='" + email + '\'' +
'}';
}
}
配置mybatis-config.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>
<properties resource="dbconfig.properties"/> <!--连接数据库文件-->
<settings>
<setting name="useGeneratedKeys" value="true"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="logImpl" value="LOG4J"/>
</settings>
<typeAliases>
<!--
alias:定义的别名
type:指定要起别名的类型全类名
默认别名就是类名小写
<typeAlias alias="别名" type="指定要起别名的类型全类名"/>
-->
<package name="com.zhk.damin"/>
</typeAliases>
<!--配置连接数据库的环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--
配置事务
transactionManager表示配置事务管理器
type表示事务的类型
取值如下:
JDBC: 表示支持事务, 里面使用MyBatis内置的事务实现, MyBatis默认就是支持事
务, 你可以自己提交事务, 回滚事务
MANAGER: 表示不支持事务
第三方事务: 后期如果想要使用事务,都会交给Spring来处理
-->
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
<!--
配置数据源 dataSource就是配置连接池
type属性表示连接池的类型
取值如下:
POOLED: 表示使用MyBatis自带的连接池
UNPOOLED: 表示不使用连接池, 每次获取连接都是创建一个新的连接对象,性能比较低
JNDI: 表示的是web服务器配置的数据库连接池 [后面学习Tomcat服务器再讲解]
第三方连接池: DBCP, C3P0, DRUID [后期连接池也会交给Spring管理]
-->
</environment>
</environments>
<!--引入映射文件-->
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
<!--XML配置-->
<!--<mappers>
<mapper resource="com/xyr/dao/UserMapper.xml"/>
<mapper resource="com/xyr/dao/OrderMapper.xml"/>
<mapper resource="com/xyr/dao/EmployeeMapper.xml"/>
</mappers>-->
<!--注解配置-->
<!--<mappers>
<mapper class="com.xyr.dao.UserMapper"/>
<mapper class="com.xyr.dao.OrderMapper"/>
<mapper class="com.xyr.dao.EmployeeMapper"/>
</mappers>-->
<!--直接配置映射器所在的包,从而简化配置-->
<!--<mappers>
<package name="com.xyr.dao"/>
</mappers>-->
日志文件
# 全局日志配置
log4j.rootLogger=ERROR, stdout
# MyBatis 日志配置
log4j.logger.com.zhk.dao.UserMapper=TRACE
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
数据库文件
mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/demo01?useUnicode=true&characterEncoding=utf8
mysql.username=root
mysql.password=1234
编写UserMapper.xml
编写dao文件的UserMapper
package com.zhk.dao;
import com.zhk.damin.User;
import java.util.List;
public interface UserMapper {
List<User> getallUser();
}
编写测试类
import com.zhk.damin.User;
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;
/**
* @Author zhk
* @Date 2022/10/18
*/
public class demo2Test {
/*
@BeforeClass – 表示在类中的任意public static void方法执行之前执行
@AfterClass – 表示在类中的任意public static void方法执行之后执行
@Before – 表示在任意使用@Test注解标注的public void方法执行之前执行
@After – 表示在任意使用@Test注解标注的public void方法执行之后执行
@Test – 使用该注解标注的public void方法会表示为一个测试方法
*/
@Test
public void testallUser() throws IOException {
String resource="mybatis-config.xml";
//加载核心配置文件
InputStream is= Resources.getResourceAsStream(resource);
//获取SqlSessionFactoryBuilder
SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();
//获取SqlSessionFactory
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//获取sqlSession
SqlSession sqlSession=sqlSessionFactory.openSession(true);
//获取mapper接口对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//测试功能
List<User> list=mapper.getallUser();
for(User i:list){
System.out.println(i);
}
/*list.forEach(user-> System.out.println(user));*/
}
}
实现效果
结语:通过这个入门案例,初步认识了MyBatis的一个应用流程。