目前流行的编程语言,例如Java、C#等,都是面向对象的;目前主流的数据库产品,例如Oracle、Mysql,依然是关系数据库。编程语言和底层数据库发展不协调,催生出了ORM框架,ORM框架可作为面向对象编程语言和关系型数据库之间的桥梁。
确切的说MyBatis并不完全是一种ORM框架,它的设计思想和ORM相似,只是它允许开发人员直接编写SQL语句,使数据库访问更灵活。
ORM(对象/关系数据库映射)
以下是ORM工作示意图:
它把持久化对象的保存、修改、删除等操作,转换成对数据库的操作。由此,程序员可以以面向对象的方式操作持久化对象,而ORM框架负责将相关操作转换成对应的SQL操作。
基本映射方式
ORM工具有如下几条基本映射关系:
- 数据表映射类。就是说,持久化类被映射到数据表。程序对持久化类的操作会自动转换为对数据表的CRUD操作。
- 数据表的行映射对象(即实例)。持久化类会生成很多实例,每个实例就对应数据表中的一行记录。所以,程序修改持久化类的某一个实例的时候,也就是转换为修改某一行数据。
- 既然有行映射,那么也就有列映射。
流行的ORM框架简介
目前主流的有如下产品:
- JPA。JPA本身只是一种ORM规范,而不是ORM产品。所以它最大的优势就是它是官方标准。
- Hibernate。目前最流行的开源ORM框架,已经被选为JBoss的持久层解决方案。它设计灵巧、性能优秀。
- MyBatis。早期也叫iBatis,Apache的子项目。**与其说它是一种ORM框架,不如称为SQL Mapper框架。**它允许开发人员直接编写SQL语句,更加灵活。
MyBatis概述
纵观目前主流的ORM,无论是Hibernate还是JPA,都是对数据库结构提供了较为完整的封装,提供了从POJO到数据库表的全套映射机制。程序猿只需要定义好从POJO到数据库表的映射关系,即可通过Hibernate或者JPA提供的方法完成持久层操作。程序猿甚至不需要熟练掌握SQL,因为它们会自动生成对应的SQL。
大部分情况下,这个机制无往而不利,但在一些特定的环境下,未必适合,例如:
- 系统的部分或全部数据来自现有数据库,但出于安全考虑,只对开发团队提供几条Select SQL,具体表结构不做公开。
- 开发规范要求,所有牵涉到业务逻辑部分的数据库操作,必须在数据库层由存储过程实现(银行系统)。
- 系统数据处理量巨大,性能要求极为苛刻,这要求我们使用高度优化的SQL语句。
而半自动化的MyBatis提供了这些功能。
MyBatis入门
创建数据库
create database mybatis;
USE mybatis;
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(18) DEFAULT NULL,
`sex` char(2) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
下面是POJO类:
package com.leesanghyuk.model;
public class User {
//用户标识
private Integer id;
//用户姓名
private String name;
//用户性别
private String sex;
//用户年龄
private String age;
//无参构造器
public User() {
}
//有参构造器
public User(String name, String sex, String age) {
this.name = name;
this.sex = sex;
this.age = age;
}
//getter setter
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
MyBatis可以通过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">
<mapper namespace="com.leesanghyuk.mapper.UserMapper">
<insert id="save" parameterType="com.leesanghyuk.model.User"
useGeneratedKeys="true">
INSERT INTO TB_USER(name,sex,age) VALUES (#{name},#{sex},#{age})
</insert>
</mapper>
下面来解释一下:
- namespace习惯上设置为包名+sql映射文件名,这样就能保证namespace的值是唯一的,例如
namespace='com.leesanghyuk.UserMapper'
就是com.leesanghyuk(包名)+UserMapper(.xml) - insert标签中编写插入语句,其id属性值为save。id属性值是唯一的。
- parameterType属性指明插入时使用的参数类型,这里是User类。
- useGeneratedKeys='true’表示使用数据库的自动增长策略,这需要底层数据库的支持。
- insert的插入语句中的
#{xxx}
,xxx表示去参数中对象的xxx属性。
接下来,我们还需要配置连接池、连接数据库等等配置:
<?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">
<!--xml配置文件包含对mybatis系统的核心设置-->
<configuration>
<!--指定MyBatis所用日志的具体实现-->
<settings>
<setting name="logImpl" value="LOG4J"></setting>
</settings>
<!--环境配置,即连接的数据库-->
<environments default="mysql">
<environment id="mysql">
<!--指定事务管理类型,type="JDBC"指直接简单的使用JDBC的提交和回滚设置-->
<transactionManager type="JDBC"></transactionManager>
<!--dataSource指数据源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="woshixiao"/>
</dataSource>
</environment>
</environments>
<!--mappers告诉了Mybatis去哪里找持久化类的映射文件-->
<mappers>
<mapper resource="com/leesanghyuk/mapper/UserMapper.xml"/>
</mappers>
</configuration>
MyBatis配置文件被命名为mybatis-config.xml,应用程序运行时需要先加载该文件。
下面是数据插入的代码:
package com.leesanghyuk.tst;
import com.leesanghyuk.model.User;
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;
public class MyBatisTest {
public static void main(String[] args) throws IOException {
//读取mybatis-config.xml文件
InputStream inputStream= Resources.getResourceAsStream("mybatis-config.xml");
//初始化mybatis,创建sqlSessionFactory类的实例
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//创建Session实例
SqlSession sqlSession=sqlSessionFactory.openSession();
//创建User对象
User user=new User("admin","男",26);
//插入数据
sqlSession.insert("com.leesanghyuk.mapper.UserMapper.save",user);
//提交事务
sqlSession.commit();
//关闭session
sqlSession.close();
}
}
为了查看控制台输出的SQL语句,需要假如日志框架LOG4J的相关jar包,并在classpath下增加一个log4j.properties文件:
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.org.fkit.mapper.UserMapper=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
然后,运行。
但是出错了,一是我们log4j没有配置好,二是因为,UserMapper.xml找不到。
找不到mapper的解决方法:
https://blog.csdn.net/u010648555/article/details/70880425
那么如何配置log4j呢?
查询资料知道,mybatis3.1之前的版本对<setting name="logImpl" value="LOG4J">
不能识别,所以修改dependency即可。
运行结果:
有经验的读者可以通过日志信息了解Mybatis的执行过程:在执行session.insert之前,先要获取到sqlSession对象。POJO只有在SqlSession的管理下才可完成数据库访问。
为了使用Mybatis进行持久化操作,通常有以下操作:
- 开发持久化类POJO和编写持久化操作Mapper.xml,在其中定义SQL语句。
- 获取SqlSessionFactory
- 获取SqlSession
- 用面向对象的方式操作数据库。
- 提交事务,关闭SqlSession