MyBatis ~ 从入门到入坑。
框架。
ta 是软件开发中的一套解决方案,不同的框架解决不同的问题。
框架封装了很多细节,使用开发者可以使用极简的方式实现功能。大大提高开发效率。
三层构架。
表现层 ——> 用于展示数据。
业务层 ——> 处理业务需求。
持久层 ——> 和数据库交互。
持久层技术解决方案。
JDBC 技术。
Connection
PreparedStatement
ResultSetSpring 的 JdbcTemplate。
Spring 中对 jdbc 的简单封装。。
Apache 的 DBUtils。
ta 和 Spring 的 JdbcTemplate 很像,也是对 Jdbc 的简单封装。
以上都不是框架,
JDBC 是规范,
Spring 的 JdbcTemplate 和 Apache 的 DBUtils 都只是基于 JDBC 规范的实现工具类。
MyBatis ~ what。
MyBatis 是一个持久层框架,用 Java 编写。
ta 封装了 jdbc 操作很多细节,使开发者只需关注 sql 语句本身,而无需关注注册驱动、创建连接等。
ORM:Object Ralational Mapping,对象映射关系。
把数据库表和实体类的属性对应起来,让我们操作实体就实现对数据库的操作。
实体类中的属性要和数据库表的字段名保持一致。
user(id,user_name)
User(id,user_name)
环境搭建。
创建 Maven 工程并导入坐标。
创建实体类和 dao 接口。
创建 MyBatis 主配置文件(SqlMapConfig.xml)。
创建映射配置文件(IUserDao.xml)。
- 所需的 jar 包。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.geek</groupId>
<artifactId>mybatis_demo01</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
</dependencies>
</project>
项目结构。
代码。
- User 实体类。
package com.geek.domain;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
}
- dao 层。
public interface IUserDao {}
// 这里命名:IUserDao —> 大写 I 开头表示是接口,个人编程习惯。
接口内定义要对数据库操作的方法,不用再写实现类。
package com.geek.dao;
import com.geek.domain.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* 用户的持久层接口。
*
* @author geek
*/
public interface IUserDao {
/**
* 查询所有操作。
*
* @return
*/
@Select("select * from user;")
List<User> findAll();
}
关键,在 resources 目录下,
创建 SqlMapConfig.xml。
此文件是 MyBatis 主配置文件。
<?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="development">
<!-- 配置 MySQL 的环境。可以配置多个,具体使用哪个以 <environments default="development"> 的选择为准。-->
<environment id="development">
<!-- 配置事务的类型。-->
<transactionManager type="JDBC"/>
<!-- 配置数据源。有 3 种。POOLED, UNPOOLED, JNDI。-->
<dataSource type="POOLED"><!-- MySQL 连接参数。-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.223.128:3306/mybatis_demo"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 指定映射配置文件的位置。映射配置文件指的是每个 dao 独立的配置文件。-->
<mappers>
<mapper resource="com/geek/dao/IUserDao.xml"/>
</mappers>
</configuration>
配置文件目录注意事项。
- 在
resources
目录下建立文件夹。
文件目录层次有严格要求。
如,src.main.java
中接口如图定义(以 . 分隔)。
则resources
下的.xml
文件要以相同的目录层级结构定义。
并且
,我们在定义类或接口时是以.
分隔目录的。
但是
,在此我们定义 mapper.xml
文件时,目录不能用.
分隔,而是使用/
分隔。
否则会报错。
虽然创建之后看不出区别。
但当我们以文件管理器打开就会发现其实并不一样。
正确的结构应是第一个
。
mybatis_demo01/src/main/resources/com/geek/dao/IUserDao.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="com.geek.dao.IUserDao"><!-- 接口全限定名。-->
<!-- 配置查询所有。-->
<select id="findAll" resultType="com.geek.domain.User">
select * from user;
</select>
</mapper>
其中,mapper
是根标签,namespace
指 dao 接口的全限定名
。
子标签可以有以下选择,表示执行 sql 的增(insert)删(delete)改(update)查(select)
等。
- id 属性。
与 dao 接口中的方法名对应,只要调用了接口中的方法,如 userDao.findAll();
(当然,UserDao 是接口,这里需要通过代理对象调用),就会通过此处定义的 namespace - id
执行标签体中的 sql 语句。
而这一切都由框架帮你完成。
- resultType 属性。
对象的全限定名,MyBatis 框架会将 sql 的查询结果自动封装为此对象。(这里要求对象的类的成员变量名和 MySQL 表中的字段名完全一致)
。
最终测试类。
package com.geek.test;
import com.geek.dao.IUserDao;
import com.geek.domain.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 java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MyBatisTest {
public static void main(String[] args) throws IOException {
// 读取配置文件。
InputStream is = Resources.getResourceAsStream("sqlMapConfig.xml");
// 创建 SqlSessionFactory 工厂。
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
// 使用工厂生产 SqlSession 对象。
SqlSession sqlSession = sqlSessionFactory.openSession();
// 使用 SqlSession 创建 Dao 接口的代理对象。
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
// 使用代理对象执行方法。
List<User> userList = userDao.findAll();
for (User user : userList) {
System.out.println(user);
}
// 释放资源。
sqlSession.close();
is.close();
}
}
最终查询到的结果即为 User 对象。
User{id=1, username='geek', birthday=null, sex='m', address='null'}
User{id=2, username='geek', birthday=null, sex='m', address='null'}
User{id=3, username='geek02', birthday=null, sex='f', address='null'}
git 代码地址。
https://github.com/lyfGeek/MyBatis_my.git