文章目录
前言
MyBatis 本是 Apache 的一个开源项目 iBatis,2010年这个项目由Apache Software Foundation迁移到
了Google Code,并且改名为MyBatis。
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架,iBATIS提供的持久层框
架包括SQL Maps和Data Access Objects(DAOs)
MyBatis是一个优秀的持久层框架,它对JDBC操作数据库的过程进行封装,使开发者只需要关注 SQL
本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、
结果集检索等JDBC繁杂的过程代码。
MyBatis通过 xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过 Java 对象和
statement 中 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由MyBatis框架执行sql并将结果
映射成Java对象并返回
一、概述
1.1 JDBC编程存在的问题
- 硬编码-代码写死了 代码维护性差
- 操作繁琐
1.2 MyBatis对于JDBC的简化操作
- 连接池配置文件
- SQL语句配置文件
- 自动封装结果集
二、MyBatis快速入门
2.1 快速入门步骤
数据库创建测试用表并添加数据
- 建表
CREATE TABLE User(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(10) ,
age INT ,
phoneNum VARCHAR(20)
);
- 插入数据的操作自定义完成
insert into user(id,name,age,phoneNum) values (1,'郭AP0',41,'13106483328');
.
.
.
创建Maven项目
- MyBatis需要创建Maven项目 在Maven项目中去进行
- 有关Maven项目的配置与创建可以参考以下博客
【链接地址】 - 创建Maven项目后 导入所需依赖——pom.xml文件
- 所需依赖在Maven仓库中可以根据想要的版本搜索到
- pom.xml 如下
<?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>org.example</groupId>
<artifactId>mybatis-study</artifactId>
<version>1.0-SNAPSHOT</version>
<name>mybatis-study</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- mybatis 依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!-- mysql驱动 依赖 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- slf4j日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
<build>
</build>
</project>
实体类
package com.wedu.pojo;
//数据库对应的实体类
public class User {
private int id;
private String name;
private int age;
private String telephoneNum;
public User() {
}
public User(int id, String name, int age, String telephoneNum) {
this.id = id;
this.name = name;
this.age = age;
this.telephoneNum = telephoneNum;
}
/**
* 获取
* @return id
*/
public int getId() {
return id;
}
/**
* 设置
* @param id
*/
public void setId(int id) {
this.id = id;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
public String getTelephoneNum() {
return telephoneNum;
}
public void setTelephoneNum(String telephoneNum) {
this.telephoneNum = telephoneNum;
}
public String toString() {
return "User{id = " + id + ", name = " + name + ", age = " + age + ", phoneNumber = " + telephoneNum + "}";
}
}
MyBatis核心配置文件
- 从官网参考MyBatis核心配置文件——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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 数据库连接信息 需要修改下面${}的内容 -->
<!-- <property name="driver" value="${driver}"/>-->
<!-- <property name="url" value="${url}"/>-->
<!-- <property name="username" value="${username}"/>-->
<!-- <property name="password" value="${password}"/>-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/my_db1"/>
<property name="username" value="root"/>
<property name="password" value="6666"/>
</dataSource>
</environment>
</environments>
<!-- mappers 指定当前的sql映射文件的绝对路径 加载sql映射文件 -->
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
mappers加载的sql映射文件
-
从官网参考mappers加载的sql映射文件规范写法——UserMapper.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">
<!--
namespace:名称空间
-->
<mapper namespace="test">
<!-- 编写增删改查语句 -->
<!-- select中
id:唯一标识
resultType:返回值类型 指定返回值为被包装的类型
一般封装为实体类对象 因此此处写实体类的引用即可
-->
<select id="selectAll" resultType="com.wedu.pojo.User">
select * from user;
</select>
</mapper>
测试类
package com.wedu.test;
import com.wedu.pojo.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;
/**
* MyBatis快速入门示例
*/
public class MyBatisDemo01 {
public static void main(String[] args) throws IOException {
// 1.加载mybatis的核心配置文件 获取SqlSessionFactory 通常只需要加载一次
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2. 通过sqlSessionFactory调用方法获取sqlSession对象 用其执行sql语句
SqlSession sqlSession = sqlSessionFactory.openSession();
//sqlSession对象调用获取数据库数据返回一个list集合的方法 selectList("名称空间.唯一标识")
List<User> users = sqlSession.selectList("test.selectAll");
System.out.println(users);
// for (User user : users) {
// System.out.println(user);
// }
// 3.释放资源 只需要释放sqlSession对象
sqlSession.close();
}
}
2.2 Mapper代理开发
-
在快速入门基础步骤中
- 在测试类中通过sqlSession对象调用方法
(方法中传入mapper配置文件其中的命名空间引用字符串) - 获取到list集合 即执行sql操作的这一步
- 在测试类中通过sqlSession对象调用方法
-
还是属于硬编码 代码维护性还是比较高
因此使用Mapper代理开发的规范进行简化
-
使用Mapper代理的前提条件:
-
定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下
- 实现接口与sql映射文件在同一个目录下,并且保证映射文件还是属于资源根目录下
- 在资源根目录下创建一个与接口包路径完全一致的目录名称
实现依据:在maven项目comple编译后的文件都将在tar…/classes目录下 在该目录里能实现接口与sql映射文件在同一个目录下
- 在资源根目录下创建一个与接口包路径完全一致的目录名称
- 实现接口与sql映射文件在同一个目录下,并且保证映射文件还是属于资源根目录下
-
设置SQL映射文件的namespace属性为Mapper接口全限定名
-
在 Mapper 接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
-
在测试类中进行编码
-
通过 SqlSession 的 getMapper方法获取 Mapper接囗的代理对象
-
代理对象 调用对应方法完成sql的执行——MyBatisDemo01.java
/**
* 2. 快速入门法二: 使用Mapper代理
*/
// 1.加载mybatis的核心配置文件 获取SqlSessionFactory 通常只需要加载一次
String resource2 = "mybatis-config.xml";
InputStream inputStream2 = Resources.getResourceAsStream(resource2);
SqlSessionFactory sqlSessionFactory2 = new SqlSessionFactoryBuilder().build(inputStream2);
// 2.通过sqlSessionFactory对象调用方法获取sqlSession对象 用其执行sql语句
SqlSession sqlSession2 = sqlSessionFactory2.openSession();
// 3.通过sqlSession2对象获取Mapper接口的对象
UserMapper userMapper = sqlSession2.getMapper(UserMapper.class);
// 4.调用接口中的方法 其中会自动加载映射文件中的sql语句的标识 自动完成执行sql语句的操作
List<User> users1 = userMapper.selectAll();
System.out.println(users1);
// for (User user : users) {
// System.out.println(user);
// }
// 3.释放资源 只需要释放sqlSession对象
sqlSession2.close();
- Mapper代理实用tip:
之后sql映射文件越来越多,可以通过Mapper代理的方式,直接包扫描
三、动态SQL
MyBatis 对动态SQL有很强大的支撑
-
if 标签 类似于java 中的if判断
-
choose (when, otherwise) 类似于java中的swich
-
trim (where,set) where、set动态标签
可以规避一些动态sql的语句错误
trim 标签的主要属性有四个,如下表所示:
属性名 | 作用 |
---|---|
prefix | 给sql增加前缀 |
suffix | 给sql增加后缀 |
prefixOverrides | 去掉sql前面多余的关键字或者字符 |
suffixOverrides | 去掉sql后面多余的关键字或者字符 |
- foreach 遍历
用于在sql语句中遍历集合和数组
collection属性需要注意的一个点
- 示例
<!-- 3. 多条件动态查询-->
<!-- name里含有A的 age=41 phoneNumber含有3328的 -->
<!-- select * from 表名 where (模糊查询) 列名 like/= #{对应的实体类对象属性名} ps: 字符串类型用like 整型/浮点用 = 即可-->
<select id="selectByCondition" resultMap="userResultMap">
select * from user
<where>
<if test="name != null and name != '' ">
and name like#{name}
</if>
<if test="age != null">
and age=#{age}
</if>
<if test="telephoneNum != null and telephoneNum != '' ">
<!-- phoneNum: 数据库中的列名 telephoneNum: 实体类中的属性名 -->
and phoneNum like#{telephoneNum}
</if>
</where>
</select>
<!-- 4. 单条件动态查询 -->
<select id="selectByConditionSingle" resultMap="userResultMap">
select * from user
<where>
<choose>
<when test="name != null and name != '' ">
name like#{name}
</when>
<when test="age != null">
and age=#{age}
</when>
<when test="telephoneNum != null and telephoneNum != '' ">
and phoneNum like#{telephoneNum}
</when>
</choose>
</where>
</select>