一.概述
1.1 简介
MyBatis是定制化SQL,存储过程以及高级映射的优先的持久层框架。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
1.2 为什么使用MyBatis?
- JDBC
(1)SQL夹在Java代码块中,耦合度高导致硬编码内伤
(2)维护不易且实际开发需求中SQL是有变化,频繁修改的情况多见
- Hibernate
(1)长难复杂SQL,对于Hibernate而言处理也不容易
(2)内部自动生产的SQL,不容易做特殊优化
(3)基于全映射的全自动框架,大量字段的POJO进行部分映射时比较苦难,导致数据库性能下载。
对于开发人员而言,核心SQL还是需要自己优化的。SQL和Java编码分来,功能边界清晰,一个专注于业务,一个专注于数据,MyBatis就可以满足这个需求。
- MyBatis是一个半自动化的持久化层框架:
(1)MyBatis将重要的步骤抽取出来可以人工定制,其他步骤自动化
(2)重要步骤都是写在配置文件中(好维护)
(3)完全解决数据库优化问题
(4)MyBatis底层就是对原生JDBC的一个简单封装
(5)即将Java编码与SQL抽取出来,还不会失去自动化功能,半自动的持久化
(6)一个轻量级的框架
1.3 去哪里找MyBatis?
二.HelloWorld实验代码
1.基础环境搭建
(1)创建一个Java工程
(2)创建测试库,测试表,以及封装数据的JavaBean,和操作数据库的dao
创建数据库表:
创建JavaBean:Employee(封装表的数据)
package com.test.bean;
public class Employee {
private Integer id;
private String empname;
private String email;
private Integer gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getEmpname() {
return empname;
}
public void setEmpname(String empname) {
this.empname = empname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Employee [id=" + id + ", empname=" + empname + ", email="
+ email + ", gender=" + gender + "]";
}
}
创建一个Dao接口,用来操作数据库:
package com.test.dao;
import com.test.bean.Employee;
public interface EmployeeDao {
//按照员工id查询
public Employee getEmpById(Integer id);
}
2.用MyBatis操作数据库
1)导包
//数据库驱动
mysql-connector-java-5.1.37-bin.jar
mybatis-3.4.1.jar
//建议导入日志包,这样在MyBatis在关键环节就有日志打印(log4j),依赖于类路径下一个log4j.xml配置文件
//log4j-1.2.17.jar
2)写配置(两个配置文件,全局配置文件和dao接口的实现文件)
(1)第一个配置文件(称为MyBatis的全局配置文件,知道MyBatis如何正确运行,比如连接到哪个数据库):
<?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="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
</configuration>
(2)第二个配置文件(编写每一个方法都如何向数据库发送sql语句,如何执行,相当于接口的实现类):
将mapper标签的namespaces属性改为接口的全类名;
<?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:名称空间,写接口的全类名,相当于告诉MyBatis是实现哪个接口 -->
<mapper namespace="com.test.dao.EmployeeDao">
<!-- public Employee getEmpById(Integer id); -->
<!-- select标签用来定义一个查询操作 ,
id:方法名,相当于这个配置是对于某个方法的实现
resultType:指定方法运行后的返回值类型,查询操作必须指定的
#{属性名}:代表取出传递过来的某个参数的值-->
<select id="getEmpById" resultType="com.test.bean.Employee">
select * from t_employee where id=#{id}
</mapper>
(3)写的dao接口的实现文件,MyBatis默认是不知道的,需要在全局配置文件中注册;
<!-- 引用我们自己编写的每一个接口的实现文件 -->
<mappers>
<!-- resource:从类路径下找资源 -->
<mapper resource="EmployeeDao.xml"/>
</mappers>
3)测试
package com.test.test;
import java.io.IOException;
import java.io.InputStream;
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 com.test.bean.Employee;
import com.test.dao.EmployeeDao;
public class MyBatisTest {
@Test
public void test() throws IOException {
//1.根据全局配置文件创建出一个SqlSessionFactory
//SqlSessionFactory是SqlSession工厂,负责创建SqlSession对象
//SqlSession:sql会话,代表和数据库的一次会话
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFcatory=new SqlSessionFactoryBuilder().build(inputStream);
//2.获取和数据库的一次会话;getConnection()
SqlSession session=sqlSessionFcatory.openSession();
EmployeeDao empDao=null;
Employee em=null;
try{
//3.使用SqlSession操作数据库,获取到dao接口的实现
empDao= session.getMapper(EmployeeDao.class);
em= empDao.getEmpById(1);
}finally{
session.close();
}
System.out.println(em);
}
}
注意:
-
在上面的实验时进行查询操作,在mapper标签中进行增删改操作的时候,增删改不用写返回值类型,增删改是返回影响多少行
mybatis自动判断,如果是数字(int,long)。如果是boolean值,影响0行就自动封装false
- 如果按照上面实验测试方法执行,增删改执行成功,但是在数据库中数据并没有操作成功,要自己设置手动提交。
session.commit();
细节:
1)获取到的是接口的代理对象,MyBatis自动创建的
2)SqlSessionFactory创建SqlSession对象,工厂类只创建一次。SqlSession相当于connection和数据库进行交互的,和数据库的一次会话,就应该创建一个新的SqlSession