目录
一,MyBatis的几个基本知识点。
1,MyBatis是什么?
MyBatis 是一个开源、轻量级的数据持久化框架,是 JDBC 和 Hibernate 的替代方 案。 MyBatis 内部封装了 JDBC ,简化了加载驱动、创建连接、创建 statement 等繁杂的过 程,开发者只需要关注 SQL 语句本身。
2,什么是持久化?
数据持久化是将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中数据模型的 统称。例如,文件的存储、数据的读取以及对数据表的增删改查等都是数据持久化操作
MyBatis 支持定制化 SQL 、存储过程以及高级映射,可以在实体类和 SQL 语句之间建 立 mapping 映射关系,是一种半自动化的 ORM 实现。其封装性低于 Hibernate ,但性能优 秀、小巧、简单易学、应用广泛。
3, MyBatis的优点
MyBatis 是免费且开源的。 与 JDBC 相比,减少了 50% 以上的代码量。 MyBatis 是最简单的持久化框架,体积小巧并且学习门槛低。 MyBatis 相当灵活,不会对应用程序或者数据库的现有设计强加任何影响,SQL 写在 XML 中,和程序逻辑代码分离,降低耦合度,便于同一管理和优化,提高了代码的可重用性。 提供 XML 标签,支持编写动态 SQL 语句。 提供映射标签,支持实体对象与数据库的表字段关系映射。
4, MyBatis的缺点
编写 SQL 语句工作量较大,对开发人员编写 SQL 语句的功底有一定要求。 ● SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库
二,准备工作。
接下来,准备好我们本次作业需要用到的类和配置文件。
1.下载并添加MyBatis依赖(官网链接附上~)
下载并解压后,需要将核心包mybatis-3.5.10.jar和lib目录下的依赖包全部添加至项目构建路径中
2,创建数据库表结构
DROP TABLE IF EXISTS `website`;
CREATE TABLE `website` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`url` varchar(30) COLLATE utf8_unicode_ci DEFAULT '',
`age` tinyint(3) unsigned NOT NULL,
`country` char(3) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`createtime` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Employee实体类:
package com.apesource.entity;
import java.util.List;
// 员工
public class Employee {
private int empId; // 员工编号
private String empName; // 员工姓名
private double empSalary; // 月薪
private Department dept; // 所在部门
private String phoneNumber; // 手机号码
public int length;
// 无参构造
public Employee() {
}
// 有参构造
public Employee(String empName, double empSalary, int deptNo, String phoneNumber) {
this.empName = empName;
this.empSalary = empSalary;
this.dept = new Department();
this.dept.setDeptNo(deptNo);
this.phoneNumber = phoneNumber;
}
public Employee(List<Employee> list) {
}
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public double getEmpSalary() {
return empSalary;
}
public void setEmpSalary(double empSalary) {
this.empSalary = empSalary;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public Department getDept() {
return dept;
}
public void setDept(Department dept) {
this.dept = dept;
}
}
sql映射文件:
<?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.apesource.mapper.EmployeeMapper">
<!-- 按照部门名查询 -->
<!-- 自定义结果集 -->
<resultMap type="com.apesource.entity.Employee" id="employeeResultMap">
<id column="emp_id" property="empId"/>
<result column="emp_name" property="empName"/>
<result column="emp_salary" property="empSalary"/>
<result column="phone_number" property="phoneNumber"/>
<association property="dept" javaType="com.apesource.entity.Department">
<id column="dept_id" property="deptNo"/>
<result column="dept_name" property="deptName"/>
<result column="dept_manager" property="deptManager"/>
</association>
</resultMap>
<select id="selectEmployeeListInDeptNames" resultMap="employeeResultMap">
SELECT * FROM employee_info as emp
INNER JOIN department_info as dept
ON emp.dept_id=dept.dept_id
WHERE dept.dept_name IN
<foreach collection="list" item="deptName" separator="," open="(" close=")">
#{deptName}
</foreach>
</select>
</mapper>
EmployeeMapper的接口
package com.apesource.mapper;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
import com.apesource.dao.OrderMode;
import com.apesource.entity.Employee;
public interface EmployeeMapper {
// 按照指定部门名称列表查询
public List<Employee> selectEmployeeListInDeptNames(List<String> deptNames);
}
测试代码段:
package com.apesource.test;
// 测试selectEmployeeListInDeptNames()方法
import java.util.Arrays;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.session.SqlSession;
import com.apesource.dao.MyBatisUtils;
import com.apesource.entity.Department;
import com.apesource.entity.Employee;
import com.apesource.mapper.EmployeeMapper;
public class Test02 {
public static void main(String[] args) {
// 按照指定部门名称列表查询
String deptName = "软件事业部"; // 指定部门名称
SqlSession sqlsession = MyBatisUtils.getSqlSession();
EmployeeMapper employeeMapper = sqlsession.getMapper(EmployeeMapper.class);
List<Employee> resultList = employeeMapper.selectEmployeeListInDeptNames(Arrays.asList("软件事业部","产品研发部","财务中心"));
for (Employee employee : resultList) {
System.out.println(employee);
}
// 输出
System.out.println("员工姓名:"+employee.getEmpName());
System.out.println("所在部门:"+employee.getDept().getDeptName());
System.out.println("员工月薪:"+employee.getEmpSalary());
System.out.println("电话号码:"+employee.getPhoneNumber());
}
}
MyBatisUtils类
package com.apesource.dao;
import java.io.IOException;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtils {
private static SqlSessionFactory factory = null;
static {
try {
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
factory = builder.build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
SqlSession session = null;
if(factory != null ) {
session = factory.openSession();
}
return session;
}
//批处理模式的SqlSession
public static SqlSession getBatchSqlSession() {
SqlSession session = null;
if(factory != null ) {
session = factory.openSession(ExecutorType.BATCH);
}
return session;
}
}
核心配置文件:
<?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>
<settings>
<!-- 日志 -->
<setting name="logImpl" value="LOG4J" />
</settings>
<!-- 配置mybatis运行环境 -->
<environments default="development">
<environment id="development">
<!-- 使用JDBC的事务管理 -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<!-- MySQL数据库驱动 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<!-- 连接数据库的URL -->
<property name="url"
value="jdbc:mysql://localhost:3306/my_db?charset=utf8mb4&useSSL=false&useTimezone=true&serverTimezone=GMT%2B8" />
<property name="username" value="root" />
<property name="password" value="......" /><!--这里填入自己设置的数据库密码-->
</dataSource>
</environment>
</environments>
<!-- 将mapper文件加入到配置文件中 -->
<mappers>
<mapper resource="com/apesource/mapper/EmployeeMapper.xml" />
</mappers>
</configuration>
日志文件
# Global logging configuration
log4j.rootLogger=ERROR,stdout
# MyBatis logging configuration...
log4j.logger.com.apesource=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
三,遇到的问题
问题1:mapper的映射文件没有加载到主配置文件中。
解决方法:我们给mybatis-config.xml文件中,加上mapper加载映射文件,如下图
问题2:未注意传值
解决方案:在selectEmployeeListInDeptNames方法中加上Arrays.asList(),再填入三个部门名称。
List<Employee> resultList = employeeMapper.selectEmployeeListInDeptNames(Arrays.asList("软件事业部","产品研发部","财务中心"));
问题3:mapper.xml中的的参数类型要与实体类中的不一致,导致出错
解决方案:修改mapper.xml文件中的参数,使其保持一致
问题4:未找到mapper.xml内的接口名
解决方案:mapper.xml文件中的select id="?"这里?的内容要与接口中定义的一至,我们直接修改?里的内容,与接口中的保持一致即可
四,总结
MyBatis 的主要思想是将程序中的大量 SQL 语句剥离出来,使用 XML 文件或注解的方式实现 SQL 的灵活配 置,将 SQL 语句与程序代码分离,在不修改程序代码的情况下,直接在配置文件中修改 SQL 语句。 MyBatis 与 其它持久性框架最大的不同是, MyBatis 强调使用 SQL ,而其它框架(例如 Hibernate )通常使用自定义查询 语言,即 HQL ( Hibernate 查询语言)或 EJB QL ( Enterprise JavaBeans 查询语言)。