MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。(来自百度百科)
业务层控制层和使用Hibernate框架一样。Hibernate基于hql是完全面向对象,全自动ORM。Mybatis基于sql是半面向对象,半自动的ORM。
每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。
用xml文件构建SqlSessionFactory实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。
我们把Mybatis的功能架构分为三层:
(1)API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
(2)数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
(3)基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
通过这两个下载地址,下载这两个dtd文件,并储存于不常变化位置的地方
http://mybatis.org/dtd/mybatis-3-config.dtd
http://mybatis.org/dtd/mybatis-3-mapper.dtd
之后在eclipse中windows→preferences,按下图找到XML Catalog中的User Specified Entries,然后Add
如下面两图所示,添加刚刚下载的两个文件依赖,其中location为你储存的本地磁盘地址,而key为下载的地址
之后在编辑mybatis的config文件和mapper文件时就会有提示(虽然没有提示也没关系)
需要知道mybatis支持两种sql映射方式,一种是通过xml配置文件映射方式,另一种是通过接口注解方式,接下来将分别给出两种方式的案例
以下为一个.sql文件的内容,可复制到一个txt后改后缀,然后直接导入数据库,详细过程另查。
这个SQL文件的主要内容是建立一个数据库"mybatisdb",然后创建数据表"user"并向其中插入了一些测试数据
CREATE DATABASE /*!32312 IF NOT EXISTS*/`mybatisdb` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `mybatisdb`;
/*Table structure for table `user` */
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`USER_NAME` varchar(30) DEFAULT NULL,
`BIRTHDAY` datetime DEFAULT NULL,
`ADDRESS` varchar(200) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
/*Data for the table `user` */
insert into `user`(`ID`,`USER_NAME`,`BIRTHDAY`,`ADDRESS`) values (1,'夏言','1573-01-01 00:00:00','桂州村'),(2,'严嵩','1587-01-01 00:00:00','分宜县城介桥村'),(3,'徐阶','1580-01-01 00:00:00','明松江府华亭县'),(4,'高拱','1566-01-01 00:00:00','河南省新郑市高老庄村'),(5,'张居正','1558-01-01 00:00:00','江陵'),(6,'tina','1980-02-03 00:00:00','北京');
新建maven工程,详细过程此前讲过,此处不再赘述
在pom.xml文件中引入mybatis依赖和mysql数据库连接依赖
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.3.0.RELEASE
cn.tedu
hn-mybatis
0.0.1-SNAPSHOT
hn-mybatis
Demo project for Spring Boot
1.8
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.3
mysql
mysql-connector-java
runtime
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
org.springframework.boot
spring-boot-maven-plugin
编辑核心配置文件,通过这个文件,设置数据源信息(数据库驱动、数据库连接地址、数据库账户和密码);设置基础配置(某个POJO类的别名,可以开启变量驼峰规则);设置映射文件或映射接口类的路径
xml文件是比较原始的配置文件了,现在一般使用配置更加简洁的yml文件,不过这里先介绍xml文件,以后再介绍yml文件如何配置
这个文件是一个POJO类,对应于数据库中的User表及其字段名,从而形成正确映射。注意最好要用驼峰式规则来对应命名!比如说如果数据库中的字段名为user_name,则此处User的属性名应该对应为userName
package cn.tedu.mybatis.pojo;
import java.util.Date;
/**
* @description 描述:POJO类,要求:1)一堆私有属性,2)get/set方法,3)toString打印
* 封装数据库中数据
*/
public class User { //数据库表user表
//字段(全大写全小写,多个单词以下划线隔开)和属性(驼峰规则)对应,类型
private Integer id;
private String userName;
private Date birthday;
private String address;
//各个属性的getter和setter,以后使用lombok插件后将省去
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", userName=" + userName + ", birthday=" + birthday + ", address=" + address + "]";
}
}
这个文件是用来写sql语句的映射文件的,通过这个文件能够定义一些sql语句,以后需要使用时可以直接调用
INSERT INTO USER (id,user_name,birthday,address)
VALUES(#{id}, #{userName}, #{birthday}, #{address})
UPDATE USER
user_name=#{userName}
, birthday=#{birthday}
, address=#{address}
WHERE id=#{id}
DELETE FROM USER WHERE id = #{id}
DELETE FROM USER WHERE id IN
#{id}
这个文件是测试类,测试能否正常用xml映射文件方式通过mybatis操作数据库
package test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.jupiter.api.Test;
import cn.tedu.mybatis.pojo.User;
public class TestMybatisXml {
@Test
public void find() throws IOException {
SqlSession session = getSession();
//!!!statement = namespace.id namespace和id均在UserMapper.xml中有明确的定义
String statement = "cn.tedu.mybatis.mapper.UserMapper.find";
User param = new User();
param.setId(5);
param.setUserName("张居正");
List userList = session.selectList(statement, param); //底层解析UserMapper.xml获取find的标签内容:sql
//遍历数据
for(User u : userList) {
System.out.println(u); //每一条数据,调用toString()
}
}
@Test
public void get() throws IOException {
SqlSession session = getSession();
String statement = "cn.tedu.mybatis.mapper.UserMapper.get";
User param = new User();
param.setId(5);
param.setUserName("张居正");
User user = session.selectOne(statement, param);
System.out.println(user);
}
@Test
public void add() throws IOException {
SqlSession session = getSession();
String statement = "cn.tedu.mybatis.mapper.UserMapper.add";
User u = new User(); //用pojo对象传参
u.setId(9);
u.setUserName("王超");
u.setBirthday(new Date());
u.setAddress("上海");
session.insert(statement, u);
session.commit(); //事务默认不提交,需要手动提交
}
@Test
public void update() throws IOException {
SqlSession session = getSession();
String statement = "cn.tedu.mybatis.mapper.UserMapper.update";
User u = new User(); //对象的属性不设置默认null
u.setId(8);
//u.setUserName("小超超");
u.setBirthday(new Date());
u.setAddress("上海外滩");
session.update(statement, u);
session.commit();
}
@Test
public void delete() throws IOException {
SqlSession session = getSession();
String statement = "cn.tedu.mybatis.mapper.UserMapper.delete";
session.delete(statement, 6);
session.commit();
}
@Test
public void deleteMuch() throws IOException {
SqlSession session = getSession();
String statement = "cn.tedu.mybatis.mapper.UserMapper.deleteMuch";
Map map = new HashMap();
map.put("ids", new Integer[] {7,8,9,99,88} ); //整数集合作为value
session.delete(statement, map);
session.commit();
}
@Test
public void count() throws IOException {
SqlSession session = getSession();
String statement = "cn.tedu.mybatis.mapper.UserMapper.count";
int count = session.selectOne(statement);
System.out.println("记录总数:" + count);
}
//获取SqlSession对象
public SqlSession getSession() throws IOException {
InputStream is = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();
return session;
}
}
如果上述测试类的每个函数都能正常运行并输出相应内容,则表示我们已经成功配置mybatis并能够通过xml映射方式正常使用mybatis来操作数据库
本例在上面创建的项目中增加修改即可
接口注解方式即把sql语句通过注解的方式来定义,并与某个接口的方法绑定,当调用这个方法时,将会执行对应的sql语句。
当需要达到类似于xml映射方式的动态sql的效果(即根据某些值是否存在来判断要不要拼接sql语句),则需要利用script标签,具体见3.3.1中的update方法的注解
新建一个usermapper接口
package cn.tedu.mybatis.mappers;
import java.util.List;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import cn.tedu.mybatis.pojo.User;
//关系:包名,接口名
public interface UserMapper {
@Select("")
public List find(User user);
@Insert("insert into user(id,username,birthday,address) Values(#{id},#{userName},#{birthday},#{address})")
public void insert(User user);
@Update("")
public void update(User user);
}
修改SqlMapConfig.xml文件中的映射文件为接口类(之前是xml映射文件)
这个文件是测试类,测试能否正常用接口注解方式通过mybatis操作数据库
package test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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.jupiter.api.Test;
import cn.tedu.mybatis.mappers.UserMapper;
import cn.tedu.mybatis.pojo.User;
public class TestMybatisInterface {
public SqlSession getSession() throws IOException {
InputStream is = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
return factory.openSession();
}
@Test
public void find() throws IOException {
SqlSession session=getSession();
UserMapper mapper=session.getMapper(UserMapper.class);
User param=new User();
param.setId(5);
/* param.setUserName("张居正"); */
/* param.setAddress("江陵"); */
List userList = mapper.find(param); //底层解析UserMapper.xml获取find的标签内容:sql
//遍历数据
for(User u : userList) {
System.out.println(u); //每一条数据,调用toString()
}
}
@Test
public void update() throws IOException {
SqlSession session=getSession();
UserMapper mapper=session.getMapper(UserMapper.class);
User param=new User();
param.setId(6);
param.setUserName("yyg");
/* param.setAddress("江陵"); */
mapper.update(param); //底层解析UserMapper.xml获取find的标签内容:sql
session.commit();
}
}
如果上述测试类的测试函数都能正常运行,则表示我们已经成功配置mybatis并能够通过接口注解方式正常使用mybatis来操作数据库
mybatis是一个不错的持久层框架,通过这个框架,可以更高效地实现对数据库的操作。
但之后还会介绍一个更加简便的框架:mybatis plus,他通过继承一个接口,甚至能做到不用写sql语句即可操作数据库,极大地提高了持久层的开发效率