文章目录
前言
MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁移到了 google code,并且改名为 MyBatis。
2013 年 11 月迁移到 Github。因此,下载 MyBatis 需要去 Github上下载。当前,最新的版本是MyBatis3.5.2。下载路径为https://github.com/mybatis/mybatis-3/releases。
MyBatis是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。
MyBatis 避免了几乎所有的 JDBC代码和手动设置参数以及获取结果集。
MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java 对象)映射成数据库中的记录。
总而言之,MyBatis 具有以下一些特点:简单易用、性能高效、保留 SQL、开源框架。
一、创建maven项目
本次使用maven进行演示。
项目名不能使用中文,此处只是演示
二、Mybaits的使用
1.导入依赖
在pom.xml文件中添加如下依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
其中两个是jsp需要的包,一个MySQL,另一个就是我们需要的mybatis
2.添加配置文件mybatis-config.xml
我们需要在resources文件夹下创建一个mybatis-config.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>
</configuration>
此处的configuration是我们的根标签。所有配置都需要我们在这里编写
接着在根标签中添加配置项(这里我就不在一一列举,直接整一个基本配置完整的)
<!-- 引入外部属性文件 配置jdbc属性 -->
<properties resource="db.properties" />
<!-- 配置日志文件 -->
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<!-- 配置实体类别名 ?报错? 顺序要放对-->
<typeAliases>
<package name="com.lzl.entity"/>
</typeAliases>
<!-- 环境 -->
<environments default="development">
<environment id="development">
<!-- 事务管理 -->
<transactionManager type="JDBC"/>
<!-- 数据源配置 连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 当mapper在resources文件夹下 <mapper resource="UserMapper.xml"/>-->
<!--<mapper resource="com/lzl/mapper/UserMapper.xml"/>-->
<package name="com.lzl.mapper"/>
<!-- 配置所有的mapper文件 -->
</mappers>
需要注意的是,在编写配置文件的时候,是有先后顺序之分的,如果不按照先后顺序,会报红
接下来,配置我们的数据源,注意,如果不想配置外部数据源,可以直接在数据源value值中写一些值。如下:
<dataSource type="POOLED">
<!--此处用mysql驱动,也可以配置其他的驱动,根据数据库进行选择-->
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/数据库名" />
<property name="username" value="用户名" />
<property name="password" value="密码" />
</dataSource>
配置数据源,需要在resources文件夹下创建一个配置文件
命名为db.properties
文件内容如下
##驱动
jdbc.driver=com.mysql.jdbc.Driver
##数据库连接
jdbc.url=jdbc:mysql://localhost:3306/数据库名
##用户名
jdbc.username=用户名
##密码
jdbc.password=密码
接下来配置日志文件
我使用的log4j日志,所以需要在pom.xml文件中添加log4j的依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
接着在我们的resources问件夹中新建一个名字叫log4j.properties的文件,接着填入一下配置
log4j.rootLogger=debug,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.F.Encoding=utf-8
log4j.appender.stdout.layout.ConversionPattern=%5p[%t]-%m%n
关于log4j的文件配置上边的mybatis-config.xml文件中已经配置好了,此处不再赘述。
3.编写mapper.xml映射文件。
mybatis框架,替换的是我们之前通过JDBC操作数据库的操作过程。这部分都是持久层的东西。所以mybatis是代替的持久层的操作。
使用mybatis我们必须要用mapper.xml映射文件代替DaoImpl
具体如下:
首先创建mapper包,在其下面创建一个UserMapper接口文件,和UserMapper.xml文件。
UserMapper接口中和以前一样,定义我们的抽象方法。
package com.lzl.mapper;
import com.lzl.entity.User;
import org.apache.ibatis.annotations.Param;
/**
* --效率,是成功的核心关键--
* --自负,会让每个人都屈膝下跪--
*
* @Author lzl
* @Date 2022/9/20 10:26
*/
public interface UserMapper {
/**
*@Description 登陆功能
*@Param
*@Return
*/
Integer getLogin(String username, String password);
}
UserMapper.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">
<!-- 根标签 namespace标注了映射的是哪一个接口文件 要使用全限定名 -->
<mapper namespace="com.lzl.mapper.UserMapper">
</mapper>
头文件的命名空间绑定的是接口的全限定名。这样可以让我们的mybatis自动去寻找映射文件所对应的接口。
接着使用标签编写sql语句
<!-- 查询语句 id制定了mapper接口的方法名 resultType指定返回值类型, parameterType指定形参的类型 -->
<select id="getLogin" resultType="int" parameterType="String">
select count(*) from user where username = #{username} and password = #{password}
</select>
至此mapper层编写完成。
4.添加添加junit单元测试,编写测试类
使用junit单元测试来验证我们的方法是否正确。首先在src下边和main同级新建一个test文件夹,根据提示创建如下:
创建TestDemo文件
在pom.xml文件中添加junit单元测试依赖如下:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
接着编写TestDemo中的代码:
package com.lzl;
import com.lzl.entity.User;
import com.lzl.mapper.UserMapper;
import com.lzl.util.MyBatisUtil;
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;
/**
* --效率,是成功的核心关键--
* --自负,会让每个人都屈膝下跪--
*
* @Author lzl
* @Date 2022/9/20 10:51
*/
public class TestDemo {
//测试方法,该注解用来标识测试方法,而不用再使用main方法,需要加入junit依赖
@Test
public void hello() throws IOException {
// 配置文件路径
String resource = "mybatis-config.xml";
// 通过配置文件,获得输入流
InputStream resourceAsStream = Resources.getResourceAsStream(resource);
// 通过流获得SqlSession工厂
// SqlSession就是一次与SQL的交互
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
// 得到SqlSession
SqlSession sqlSession = build.openSession();
// 动态代理的模式
// 可以通过接口得到对应的映射文件,从而让映射文件执行
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 调用接口的方法,其实是执行映射文件中对应的sql语句
// 返回的User是mybatis的自动封装的
Integer key = mapper.getLogin("root","123456");
System.out.println(key);
}
@Test
public void Demo_TestUtil(){
//通过工具类反射获得接口
UserMapper mapper= MyBatisUtil.getMapper(UserMapper.class);
//调用接口的方法获得返回值
Integer key = mapper.getLogin("root","123456");
System.out.println(key);
}
}
此处我们需要添加@Test注解,这样我们就可以运行单个的测试方法
这里提供了两种方法去验证
第一种直接通过动态代理和反射获得mapper接口的方法使用权。
第二种是将上边的复杂操作封装成为一个工具类
我放在下边
package com.lzl.util;
import java.io.IOException;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil {
// 配置文件位置+名称
private final static String CONFIG_FILE = "mybatis-config.xml";
// SqlSessionFactory会话工厂
private static SqlSessionFactory sessionFactory = null;
/*
* 创建本地线程变量,为每一个线程独立管理一个session对象 每一个线程只有且仅有单独且唯�?的一个session对象
* 加上线程变量对session进行管理,可以保证线程安全,避免多实例同时调用同�?个session对象
* 每一个线程都会new�?个线程变量,从�?�分配到自己的session对象
* 通过线程保证会话安全
*/
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
/**
* 静态初始化块,完成创建唯一 SqlSessionFactory 对象
* 会在本类初始化的时候自动执行 只会执行�?�?
*/
static {
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
try {
//创建会话工厂
sessionFactory = builder.build(Resources.getResourceAsStream(CONFIG_FILE));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 线程安全地创�? SqlSession 对象
* @return SqlSession 对象
*/
public static SqlSession getSqlSession() {
SqlSession session = threadLocal.get();
if (session == null) {
session = sessionFactory.openSession(true);
threadLocal.set(session);
}
return session;
}
/**
* 关闭SqlSession
*/
public static void closeSqlSession() {
SqlSession session = threadLocal.get();
if (session != null) {
session.close();
threadLocal.set(null);
}
}
/**
* 获得 Dao 接口实现�?
* @param clazz Dao 接口类型
* @return Dao 接口实现�?
*/
public static <T> T getMapper(Class<T> clazz) {
return getSqlSession().getMapper(clazz);
}
}
关于mybatis工具类,网上版本很多,这里就不再介绍。
可能会出现的BUG
1、首先当接口传入参数是多个参数的时候,运行可能会报错,如下
这是因为我们在接口中传入多个参数时,mybatis不能自动识别。我们需要加一点配置
需要在接口文件中加入注解告知mybatis我们的参数对应的键值。
2、可能配置没有错,却无法运行成功
如下,检查所有配置却没有发现错误。这时候将我们的target文件夹调出
我们将这个选项勾选,可以看出,项目结构下多了一个target的橙色文件夹
其实,这个target才是编译完之后,运行的问件,当我们打开发现,mapper包下边没有mapper.xml文件,所以导致运行时找不到映射文件报错。
这个bug是由于IDEA不会自动将我们的Mapper.xml文件编译到target目录,而eclipse是可以的。
此时我们有两种解决方法
第一,我们可以直接把mapper.xml文件复制粘贴过来,手动导入。
第二,在pom.xml中加入一些配置如下:
<!--解决Intellij构建项目时,target/classes目录下不存在mapper.xml文件-->
<resources>
<resource>
<directory>${basedir}/src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
我们点击maven,找到生命周期,clean一下,(双击即可)
然后再点击compile
操作完上述步骤,发现我们的mapper.xml文件已经编译完成了
可以看到已经执行成功,至此mybatis入门已经完成。