思路:搭建环境–导入MyBatis–>编写代码–>测试!
1.搭建环境
1.1 搭建数据库
-- 创建数据库
CREATE DATABASE `mybatis`;
USE 'mybatis';
-- 创建表
CREATE TABLE user(
id INT(20) PRIMARY KEY,
name VARCHAR(30) DEFAULT NULL,
pwd VARCHAR(30) DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;
--插入数据
INSERT INTO user(id,name,pwd)
VALUES
(1,'张三','123'),
(2,'李四','123'),
(3,'王五','123')
-- 验证结果
SELECT * FROM USER;
问题:
①什么是"ENGINE=INNODB"?link
②DEFAULT CHARSET设置的是什么的字符编码?设置的就是这张表存储的数据采用的编码格式
1.2 新建一个干净的MAVEN项目
1.2.1 配置父工程的pom.xml
<dependencies>
<!--数据库连接依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!--junit测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
1.2.2 创建一个子模块
1.2.3 使用mybatis的步骤
- 编写mybatis核心配置文件(和编写JDBC区别1:将4大参数写到了mybatis核心配置文件中)
在maven项目的resources文件下创建一个名为"mybatis-config.xml"的文件,这个命名是mybatis开发手册推荐的
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--核心配置文件-->
<!--配置节点-->
<configuration>
<!--环境节点-->
<environments default="development"><!--environments节点的default属性指定配置的众多环境中默认使用哪一个环境-->
<!--环境1,我们还可以配置其他很多的环境节点-->
<environment id="development">
<transactionManager type="JDBC"/><!--事务管理,这里使用的就是JDBC中的事务管理-->
<dataSource type="POOLED">
<!--属性节点,name设置属性名称,value设置属性值-->
<!--这里配置的就是JDBC4大参数-->
<property name="driver" value="com.mysql.jdbc.Driver"/><!--驱动-->
<!--注意:在XML中使不能直接使用&连接参数,我们需要转义,使用&代替&-->
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8"/><!--数据库的URL-->
<property name="username" value="root"/><!--连接数据库的账号-->
<property name="password" value="123"/><!--连接数据库的密码-->
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/thhh/dao/UserMapper.xml"/>
</mappers>
</configuration>
- 编写mybatis工具类(和编写JDBC区别2:将数据库连接对象更换为SqlSession 对象,我们去看这个类的源码可以发现它将获取conn对象的代码封装在内部,且方法名称就叫getConnection())
package com.thhh.dao.utils;
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;
//获取SqlSession对象
public class MyBatisUtils {
//获取SqlSessionFactory对象
private static SqlSessionFactory sqlSessionFactory = null;
static{
String resource = "mybatis-config.xml";//mybatis核心配置文件的路径
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);//加载mybatis核心配置文件
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//调用SqlSessionFactoryBuilder对象的build(),并传入mybatis核心配置文件的数据流,我们就可以获取到SqlSessionFactory这个工厂类对象
} catch (IOException e) {
e.printStackTrace();
}
}
//获取SqlSession对象,这个对象其实就和原来手动写JDBC代码的时候的conn对象相对应
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
-
编写操作数据库的DAO层的代码
- 实体类
package com.thhh.dao.pojo; import java.io.Serializable; public class User implements Serializable { private int id; private String name; private String pwd; public User() { } public User(int id, String name, String pwd) { this.id = id; this.name = name; this.pwd = pwd; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", pwd='" + pwd + '\'' + '}'; } }
- Dao接口
package com.thhh.dao; import com.thhh.pojo.User; import java.util.List; //在mybatis中,我们一般不写dao,而将其改写为mapper,其实二者是一样的,只是名字变了 public interface UserDao { List<User> getUserList(); }
- 接口实现类(和编写JDBC区别3:使用XML文件来实现 Mapper/Dao 接口)
<?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节点,mapper 映射器--> <mapper namespace="com.thhh.dao.UserDao"><!--属性namespace,即命名空间,用于绑定一个 mapper/dao 接口--> <!--select:查询语句,注意:resultType属性必须写上pojo的--> <select id="getUserList" resultType="com.thhh.pojo.User"> <!--属性id表示我们要调用mapper接口中的哪个方法,属性resultType用于指定方法返回一个数据类型--> select * from mybatis.user </select> </mapper>
-
测试(使用junit测试)
按照maven项目的要求,我们应该将测试的代码写在Test文件夹中
这个文件夹的使用我们默认和java文件夹得结构保持一致,并且在对应位置创建要测试得test类现在我们要测试的是刚刚写的Dao实现,所以我们就在Test文件夹得java文件夹下创建和UserDao相同得文件夹结构,并创建UserDaoTest的java文件
package com.thhh.dao; import com.thhh.dao.dao.UserDao; import com.thhh.dao.pojo.User; import com.thhh.dao.utils.MyBatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.List; public class UserDaoTest { @Test public void test(){ //1、获取SqlSession对象 SqlSession sqlSession = MyBatisUtils.getSqlSession(); //2、获取执行SQL的对象,获取的方法就是通过sqlSession.getMapper(),去获取User.class的mapper映射器 UserDao mapper = sqlSession.getMapper(UserDao.class); List<User> userList = mapper.getUserList(); for (User user : userList) { System.out.println(user); } sqlSession.close(); } }
经典报错
①org.apache.ibatis.binding.BindingException: Type interface com.thhh.dao.dao.UserDao is not known to the MapperRegistry.
原因:MapperRegistry就是mapper注册,意思就是我们的UserDao对应的Mapper.xml文件在我们的mybatis核心配置文件中没有注册
注意:每一个Mapper.xml文件都需要在mybatis核心配置文件中进行注册之后才能够使用
解决:<mappers> <mapper resource="com/thhh/dao/UserMapper.xml"/> </mappers>
②报错如图
原因:MAVEN项目约定大于配置的原因:因为我们的XML文件属于一种资源文件,在maven项目中,资源文件应该被放在resources下面,而java文件夹下面只存放*.java文件,我们在编写的时候为了便于理解,我们就将Dao接口和实现这个接口的XML文件写在了一起,maven项目导出的时候不会导出java文件夹中的资源文件,所以我们的项目会报错
解决:在父工程的pom.xml文件中加一下配置信息
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
解释一下上面的配置信息,由于MAVEN项目约定大于配置,所以我们要想让maven项目运行之后输出的项目文件导出java文件夹下的资源文件,我们就需要给它添加约定,否则java文件夹中的资源文件在导出的时候就会被过滤掉
resources — directory — include— * / .properties 和 * /.xml
– 导出资源约定
– 目录src/main/resources和src/main/java约定
– 包含约定
– 任意目录下的* .properties文件和 *.xml 包含在导出的文件夹中
为了保险,我们在父工程和子模块的pom.xml中都加上上面的配置
③Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
我在网上找了很多博客,大多数都是说的连接超时,数据库断开连接,按照他们的方法试了一遍,修改了MYSQL的my.ini文件,调大生命周期,还是没用😀,所以我就自己改BUG
无意间我发现修改数据库连接4大参数中的URL即可,原来的URL为
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/><!--数据库的URL-->
方法1:
这个设置报错
删除"useSSL=true&"
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8"/><!--数据库的URL-->
再次测试
但是新问题就是我们不使用SSL安全连接,会报警告,因为在高版本的MYSQL中,要求必须使用安全连接参数
Fri Sep 11 09:32:07 GMT+08:00 2020 WARN: Establishing SSL connection without server’s identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn’t set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to ‘false’. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
方法2:
将useSSL设置为false
这个BUG就算暂时解决了吧,后面再看看有没有更好的解决办法
④Cause: org.apache.ibatis.builder.BuilderException: Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 5; columnNumber: 5; 1 字节的 UTF-8 序列的字节 1 无效
我觉得这个BUG最神奇,因为XML文件我是直接粘贴的官网上的,然而运行的时候就翻车了,解决办法有两个
法1:将UTF-8改为UTF8
法2:将UTF-8改为GBK
终于,我的第一个mybatis程序跑起来了😭BUG改的人都麻了
小结一下,为了使用mybatis实现对数据库的操作,我们进行了4步操作
- 编写mybatis核心配置文件,这个文件中我们需要配上JDBC4大参数,并将DAO接口的实现XML文件在这个文件中进行注册
- 编写mybatis工具类,编写工具类其实就是为了获取SqlSession 对象,这个SqlSession 对象和原来JDBC中的conn对象相对应;下图写出了3者关系和官方文档建议怎么使用这3个类
- 编写操作数据库的DAO层的代码
- 编写实体类
- 编写Dao接口
- Dao接口实现(使用XML文件实现)
- 使用junit测试