一、Mybatis 简介
1、简要历史
原来的名字叫ibatis,从 Apache 迁移到 Google 的时候, 改名为Mybatis。
2、Mybatis 总体技术体系
3、Mybatis 和其他持久化层技术对比
① 开发效率
Hibernate>Mybatis>JDBC
② 运行效率
JDBC>Mybatis>Hibernate
4、了解 Java 实体类
实体类是和现实世界中某一个具体或抽象的概念对应,是软件开发过程中,为了管理现实世界中的数据而设计的模型。
实体类的多个不同的叫法:
domain:领域模型
entity:实体
POJO:Plain Old Java Object
Java bean:一个 Java 类
二、搭建 Mybatis 框架的开发环境
① 导入 jar 包
[1]mybatis 需要的 jar 包:
- mybatis-3.4.1.jar:Mybatis 核心包
- mysql-connector-java-5.1.37-bin.jar:MySQL 驱动
[2]junit 框架需要的 jar 包:
- junit-4.12.jar:junit 框架
- hamcrest-core-1.3.jar:junit 框架
添加到当前工程模块的运行时环境
② 准备配置文件
[1]Mybatis 全局配置文件
习惯上命名为 mybatis-config.xml,这个文件名仅仅只是建议,并不是强制要求。将来整合 Spring 之后,这个配置文件可以省略。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| <?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> <properties resource="jdbc.properties"/>
<settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
<environments default="development"> <environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${wechat.dev.driver}"/> <property name="url" value="${wechat.dev.url}"/> <property name="username" value="${wechat.dev.username}"/> <property name="password" value="${wechat.dev.password}"/>
</dataSource> </environment> </environments>
<mappers> <mapper resource="com/atguigu/mybatis/dao/EmployeeMapper.xml"/> </mappers> </configuration>
|
注意:配置文件存放的位置是 src 根目录下。
[2]关联外部属性文件
① 需求
在实际开发时,同一套代码往往会对应多个不同的具体服务器环境。使用的数据库连接参数也不同。为了更好的维护这些信息,我们建议把数据库连接信息提取到 Mybatis 全局配置文件外边。
② 做法
创建 jdbc.properties 配置文件
1 2 3 4 5 6 7 8 9
| wechat.dev.driver=com.mysql.jdbc.Driver wechat.dev.url=jdbc:mysql://localhost:3306/mybatis wechat.dev.username=root wechat.dev.password=root
wechat.test.driver=com.mysql.jdbc.Driver wechat.test.url=jdbc:mysql://localhost:3306/mybatis wechat.test.username=root wechat.test.password=root
|
在 Mybatis 全局配置文件中指定外部 jdbc.properties 文件的位置
1
| <properties resource="jdbc.properties"/>
|
在需要具体属性值的时候使用${key}格式引用属性文件中的键
1 2 3 4 5 6
| <dataSource type="POOLED"> <property name="driver" value="${wechat.dev.driver}"/> <property name="url" value="${wechat.dev.url}"/> <property name="username" value="${wechat.dev.username}"/> <property name="password" value="${wechat.dev.password}"/> </dataSource>
|
[3]Mybatis 映射文件
相关概念:ORM(Object Relationship Mapping)对象关系映射。对象指的是 Java 的实体类对象,关系指的是关系型数据库,映射指的是二者之间的对应关系。
Java 概念 | 数据库概念 |
---|
类 | 表 |
属性 | 字段/列 |
对象 | 记录/行 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?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.atguigu.mybatis.dao.EmployeeMapper">
<select id="selectEmployee" resultType="com.atguigu.mybatis.entity.Employee"> select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{empId} </select> </mapper>
|
三、junit 测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| @Test public void testSelectEmployee() throws IOException {
String mybatisConfigFilePath = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(mybatisConfigFilePath);
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sessionFactory.openSession();
String statement = "com.atguigu.mybatis.dao.EmployeeMapper.selectEmployee";
Integer empId = 2;
Object result = session.selectOne(statement, empId);
System.out.println("o = " + result);
session.close(); }
|
说明:
- SqlSession:代表 Java 程序和数据库之间的会话。(HttpSession 是 Java 程序和浏览器之间的会话)
- SqlSessionFactory:是“生产”SqlSession 的“工厂”。
- 工厂模式:如果创建某一个对象,使用的过程基本固定,那么我们就可以把创建这个对象的相关代码封装到一个“工厂类”中,以后都使用这个工厂类来“生产”我们需要的对象。
1、图解整体思路
- 根据 Mybatis 全局配置文件创建 SqlSessionFactory 对象
- 根据 Mybatis 全局配置文件中 mappers/mapper 配置加载映射配置文件
- 通过 SqlSessionFactory 对象开启会话,创建 SqlSession 对象
- 调用 SqlSession 对象的方法,根据名称空间和 SQL 的 id 找到具体的一条 SQL 语句
- Mybatis 底层把 SQL 语句封装到 PreparedStatement 对象中发送给数据库执行
2、加入 log4j 日志打印
① 需求
在 Mybatis 工作过程中,通过打印日志的方式,将要执行的 SQL 语句打印出来。
② 操作
[1]加入 log4j 的 jar 包
log4j.jar
[2]加入 log4j 的配置文件
支持 XML 和 properties 属性文件两种形式。无论使用哪种形式,文件名是固定的:
- log4j.xml
- log4j.properties
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> <param name="Encoding" value="UTF-8" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" /> </layout> </appender> <logger name="java.sql"> <level value="debug" /> </logger> <logger name="org.apache.ibatis"> <level value="info" /> </logger> <root> <level value="debug" /> <appender-ref ref="STDOUT" /> </root> </log4j:configuration>
|
注意:配置文件存放的位置是 src 根目录下。
③ 日志的级别
FATAL(致命)>ERROR(错误)>WARN(警告)>INFO(信息)>DEBUG(调试)
从左到右打印的内容越来越详细
④STDOUT
是 standard output 的缩写,意思是标准输出。对于 Java 程序来说,打印到标准输出就是打印到控制台。
3、用上 Mapper 接口
Mybatis 中的 Mapper 接口相当于以前的 Dao。但是区别在于,Mapper 仅仅是接口,我们不需要提供实现类。
① 思路
② 调整 junit 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class PromotedMybatisTest {
private SqlSessionFactory sessionFactory;
@Before public void init() throws IOException { String mybatisConfigFilePath = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(mybatisConfigFilePath);
sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); }
@Test public void testSelectEmployee() throws IOException {
SqlSession session = sessionFactory.openSession(); session.close(); }
}
|
③ 完成 Mapper 接口
1 2 3 4 5
| public interface EmployeeMapper {
Employee selectEmployee(Integer empId);
}
|
- 方法名和 SQL 的 id 一致
- 方法返回值和 resultType 一致
- 方法的参数和 SQL 的参数一致
- 接口的全类名和映射配置文件的名称空间一致
④ 最终的 junit 测试方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Test public void testSelectEmployee() throws IOException {
SqlSession session = sessionFactory.openSession();
EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
Employee employee = employeeMapper.selectEmployee(2);
System.out.println("employee = " + employee);
session.close(); }
|
4、实现增删改操作
①insert
SQL 语句
1 2 3
| <insert id="insertEmployee"> insert into t_emp(emp_name,emp_salary) values(#{empName},#{empSalary}) </insert>
|
Java 代码中的 Mapper 接口:
1 2 3 4 5 6
| public interface EmployeeMapper {
Employee selectEmployee(Integer empId);
int insertEmployee(Employee employee); }
|
Java 代码中的 junit 测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @Test public void testSaveEmployee() {
SqlSession session = sessionFactory.openSession();
EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
Employee employee = new Employee();
employee.setEmpName("jerry"); employee.setEmpSalary(5000.33);
int result = employeeMapper.insertEmployee(employee);
System.out.println("result = " + result);
session.commit();
session.close(); }
|
②delete
SQL 语句
1 2 3
| <delete id="deleteEmployee"> delete from t_emp where emp_id=#{empId} </delete>
|
Java 代码中的 Mapper 接口:
1 2 3 4 5 6 7 8
| public interface EmployeeMapper {
Employee selectEmployee(Integer empId);
int insertEmployee(Employee employee);
int deleteEmployee(Integer empId); }
|
Java 代码中的 junit 测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Test public void testRemoveEmployee() { SqlSession session = sessionFactory.openSession();
EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
int result = employeeMapper.deleteEmployee(1);
System.out.println("result = " + result);
session.commit();
session.close(); }
|
③update
SQL 语句:
1 2 3
| <update id="updateEmployee"> update t_emp set emp_name=#{empName},emp_salary=#{empSalary} where emp_id=#{empId} </update>
|
Java 代码中的 Mapper 接口:
1 2 3 4 5 6 7 8 9 10
| public interface EmployeeMapper {
Employee selectEmployee(Integer empId);
int insertEmployee(Employee employee);
int deleteEmployee(Integer empId);
int updateEmployee(Employee employee); }
|
Java 代码中的 junit 测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Test public void testUpdateEmployee() { SqlSession session = sessionFactory.openSession();
EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
Employee employee = new Employee(2, "AAAAAA", 6666.66);
int result = employeeMapper.updateEmployee(employee);
System.out.println("result = " + result);
session.commit();
session.close(); }
|