1.简介
关于 Mybatis 框架的介绍请记住如下要点:
- Mybatis 是互联网时代流行的 ORM 框架。
- ORM (Object-Relation Mapping)定义:是一种编程技术,能够实现面向编程语言与关系型数据库之间的数据映射;面向编程语言:常见的如 java、python 等;关系型数据库:常见的如 mysql、oracle;
- Mybatis 是作用于数据层(Dao),可以用来简化 JDBC 操作,实现数据的持久化;
2.入门案例
我们先通过一个实际案例,了解下搭建一个 Mybatis 框架的基本步骤,具体过程如下:
- 第一步:在开发工具 IDEA 中创建一个 Maven 工程,在 pom.xml 文件中引入如下 jar 包;
<!--Mybatis依赖的 jar 包--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <!--访问数据库的JDBC--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.6</version> </dependency>
- 第二步:在 mysql 数据库中创建一个表,建表语句如下所示:
create table employee ( emp_id int not null comment '员工编号' primary key, emp_name varchar(50) not null comment '员工姓名', sex varchar(10) not null comment '性别', dept_id int not null comment '部门编号', manager int null comment '经理编号', hire_date date not null comment '入职日期', job_id int not null comment '职位编号', salary decimal(8,2) not null comment '月薪', bonus decimal(8,2) null comment '奖金', email varchar(100) not null comment '电子邮箱' )comment '员工表';
- 第三步:创建与表 employee 具有映射关系的实体类 Employee;
package com.entity; import java.math.BigDecimal; import java.util.Date; /** * 类注释 * * @author Lenovo * @Title: Employee * @ProjectName mybatisYG * @Description: TODO 与表 employee 对应 * @date 2019/11/1314:58 */ public class Employee { //员工编号 private int empId; //员工姓名 private String empName; //员工性别 private String sex; //部门编号 private int deptId; //部门经理编号 private int manager; //入职日期 private Date date; //职位编号 private int jobId; //员工月薪 private BigDecimal salary; //员工奖金 private BigDecimal bonus; //员工邮箱 private String email; @Setter @Getter @toString
}
- 第四步:创建实体类 Employee 和表 employee 一一对应的映射文件 employeeMapper.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文件的全路径名,不要写.xml后缀--> <mapper namespace="com.entity.employeeMapper"> <select id="queryEmployeeById" resultType="com.entity.Employee" parameterType="int"> select emp_id empId,emp_name empName,sex,dept_id deptId,manager,hire_date date, job_id jobId,salary,bonus,email from employee where emp_id = #{empId} </select> </mapper>
对以上配置文件说明如下:
★★namespace:值应该为 Mapper 文件的全路径名,注意不要写 .xml后缀;
★★select标签: id 代表唯一区分此SQL的标记,原则上可以随意命名,resultType代表 sql 查询结果的返回值类型,parameterType 为 sql语句中 where 查询条件的数据类型,例如 int;
★★当表中定义的字段与映射实体类中的属性命名不一致时,必须采用别名,将数据库字段映射为实体类属性,例如 employee 表的 emp_id 被映射为实体类 Employee 的属性 empId;
★★注意 where 条件中的参数写法 #{},{}里面的值为实体类的属性值,例如 #{empId};
- 第五步:创建 Mybatis 的配置文件 mybatis-config.xml 文件,文件建议新建在 Resources 文件夹下,配置的具体内容如下所示:
<?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="prod"><!--与 id 值保持一致--> <environment id="prod"><!--与 defaule 值保持一致--> <transactionManager type="JDBC"/><!--数据库事务的处理方式,默认为 JDBC--> <dataSource type="POOLED"><!--数据库连接池类型保持默认值 POOLED--> <!--配置数据库信息--> <property name="driver" value="com.mysql.cj.jdbc.Driver"/><!--数据库驱动方式,需要导入 JDBC驱动的 jar 包--> <property name="url" value="jdbc:mysql://localhost:3306/db?serverTimezone=UTC"/><!--数据库 URL 地址--> <property name="username" value="root"/><!--数据库用户名--> <property name="password" value="root"/><!--数据库密码--> </dataSource> </environment> </environments> <mappers> <!--加载映射文件,为对应的mapper.xml 文件所在的路径,中间用 / 间隔--> <mapper resource="com/entity/employeeMapper.xml"/> </mappers> </configuration>
★★注意:当数据库驱动采用的是 com.mysql.cj.jdbc.Driver时,此时数据库 URL 后面必须增加 ?serverTimezone=UTC,否则报错;
- 第六步:编写测试类,测试类内容如下:
package com.entity; 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.Reader; /** * 类注释 * * @author Lenovo * @Title: TestEmployee * @ProjectName mybatisYG * @Description: TODO 测试下简单的查询案例 * @date 2019/11/1317:26 */ public class TestEmployee { public static void main(String[] args) throws Exception { //第一步:加载 Mybatis-config.xml 文件,并使用 字符串输入流 Reader 进行读取; Reader reader = Resources.getResourceAsReader( "mybatis-config.xml" ); //第二步:创建 SqlSession 的单例工厂 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build( reader ); //第三步:创建访问数据库的Session--connection SqlSession session = sessionFactory.openSession(); //第四步:找到 待操作的 mapper.xml文件中待执行的 sql 语句,通过 namespace和 select 标签中的id进行定位; String statement = "com.entity.employeeMapper.queryEmployeeById"; //第五步:执行 SQL 语句 Employee employee = session.selectOne( statement, 2 ); System.out.println( "职工编号为1的员工的基本信息为::" + employee ); //第六步:关闭会话 session.close(); } }
3.初步搭建案例错误集锦以及解决方案
- 第一个错误:找不到实体类定义的 mapper.xml 文件,具体报错信息如下:
Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException:
### Error building SqlSession.
### The error may exist in com/entity/employeeMapper.xml
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/entity/employeeMapper.xml
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:52)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:36)
at com.entity.TestEmployee.main(TestEmployee.java:24)
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/entity/employeeMapper.xml
at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:121)
at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:99)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:50)
... 2 more
Caused by: java.io.IOException: Could not find resource com/entity/employeeMapper.xml
at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:114)
at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:100)
at org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XMLConfigBuilder.java:371)
at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:119)
... 4 more
错误导致原因:在于 maven 工程的 pom.xml 文件中缺少配置,使得编译的时候在 target 目录下加载不到 mapper.xml 文件;
错误解决方案:需要在 pom.xml 文件中增加如下配置;
<build> <!-- 定义classpath --> <resources> <!-- resources文件 --> <resource> <directory>src/main/resources</directory> <!-- 是否被过滤,如果被过滤则无法使用 --> <filtering>false</filtering> </resource> <!-- java文件夹 --> <resource> <directory>src/main/java</directory> <!-- 引入映射文件等 --> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </resource> </resources> </build>
- 第二个错误:采用的数据库驱动与数据库 URL 不匹配导致的报错,具体报错信息如下所示:
Caused by: com.mysql.cj.core.exceptions.InvalidConnectionAttributeException: The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
错误导致原因:Mysql 依据版本不同,会采用不同的驱动,包括 com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver,当采用的驱动是 com.mysql.cj.jdbc.Driver 时,此时对应的数据库 URL 地址必须指定时区;
错误解决方法:给 URL 地址加上时区;
<property name="url" value="jdbc:mysql://localhost:3306/db?serverTimezone=UTC"/><!--数据库 URL 地址,此对应的驱动为 com.mysql.cj.jdbc.Driver--> <property name="url" value="jdbc:mysql://localhost:3306/db"/><!--此 URL 对应的驱动为 com.mysql.jdbc.Driver-->