1.数据库脚本
本文采用mysql数据库,数据脚本如下
DROP DATABASE
IF EXISTS mybatis;
CREATE DATABASE mybatis;
USE mybatis;
DROP TABLE
IF EXISTS dept;
CREATE TABLE dept(
dept_id INT AUTO_INCREMENT PRIMARY KEY ,
dept_name NVARCHAR(50) NOT NULL
);
DROP TABLE
IF EXISTS employee;
CREATE TABLE employee(
id INT AUTO_INCREMENT PRIMARY KEY ,
`name` NVARCHAR(50) NOT NULL ,
age INT ,
birthday DATETIME ,
dept_id INT ,
CONSTRAINT fk_dept_id FOREIGN KEY(dept_id) REFERENCES dept(dept_id)
);
INSERT INTO dept(dept_name)
VALUES
('信息技术部') ,
('人事部') ,
('PCB事业部') ,
('无线终端部') ,
('测试部');
INSERT INTO employee(`name` , age , birthday , dept_id)
VALUES
('小花5760 ' , 0 , NOW() , 1) ,
('小花7238 ' , 1 , NOW() , 2) ,
('小花7985 ' , 11 , NOW() , 3) ,
('小花2438 ' , 24 , NOW() , 1) ,
('小花7386 ' , 8 , NOW() , 4) ,
('小花9787 ' , 8 , NOW() , 1) ,
('小花9711 ' , 4 , NOW() , 4) ,
('小花2119 ' , 21 , NOW() , 5);
2. 开发环境准备
开发工具为idea,使用maven构建项目,需要一定的maven基础,可以查看笔者之前关于maven的介绍配置http://www.jianshu.com/p/2eceee248836
先来一张项目结构图
mapper 包主要放置mapper接口以及mapper映射文件
model 包主要放置和数据库表对应的实体对象
util 包放置了一个关于 SQLSession 管理的类和io操作类
resources 目录下面防止了数据库配置文件以及mybatis核心配置文件,接下来笔者带大家一一分析
3. pom 文件主要是mybatis和jdbc驱动的配置
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
</dependencies>
<build>
<!--在maven中设置打包时将xml文件一起打包-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
4. 配置文件
jdbc.properties 文件主要存放和数据库连接相关的信息
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis
username=root
password=
mybatis.xml 主要是mybatis核心配置文件,
<!-- 加载属性文件 -->
<properties resource="jdbc.properties"/>
<!-- 设置实体对象所在的包设置实体对象的别名,
默认是将该类的名称首字母小写,也可以使用@Alias 注解自定义
也可以使用 typeAlias 单一指定
-->
<typeAliases>
<package name="com.zzz.mybatis.model"/>
</typeAliases>
<!-- 开发配置信息 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- mapper 接口所在的包,mybatis会自动扫描查找
也可以使用 mapper 单独指定
-->
<mappers>
<package name="com.zzz.mybatis.mapper"/>
</mappers>
5. 先来看util包中的内容
首先看 SqlSessionFactoryUtil,这里面笔者都做了注释,后面在专门详细介绍,以及后面即将说到的 mapper。
IoUtils 主要负责IO对象的关闭,可自行查看源码,这里不做分析
package com.zzz.mybatis.util;
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;
/**
* Created by tao.zeng on 2017/9/28.
*/
public class SqlSessionFactoryUtil {
private SqlSessionFactoryUtil() {
}
/**
* 主要用来创建 SqlSession 相当于一次会话,类似于jdbc中的Connection对象
* 当程序访问数据库时,就需要使用该对象构建 SqlSession,所以他应该位于整个生命周期
* 并且不希望有多个实例对象,所以做成单例模式
*/
private volatile static SqlSessionFactory mSqlSessionFactory;
/**
* 返回 SqlSession 对象 该对象主要用来执行 sql 语句
* 它应该位于一个应用的请求和操作中,注意使用时需要及时关闭回收资源
*
* @return
*/
public static SqlSession openSqlSession(){
initSqlSessionFactory();
return mSqlSessionFactory.openSession();
}
private static void initSqlSessionFactory() {
InputStream in = null;
try {
// 加载 resources 目录下面的 mybatis.xml 文件
in = Resources.getResourceAsStream("mybatis.xml");
if (mSqlSessionFactory == null) {
synchronized (SqlSessionFactoryUtil.class) {
if (mSqlSessionFactory == null) {
// SqlSessionFactoryBuilder 主要用来生成 SqlSessionFactory 对象
// 一旦 SqlSessionFactory 构建完成,就应该将它回收,所以他在方法内部维护就好
mSqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
IoUtils.close(in);
}
}
}
6.编写 mapper 接口和 mapper映射文件
笔者在这里抽象出了一个 BaseMapper 接口,里面涉及基本的增删改查操作,在这里用到了泛型 T 表示当前操作实体对象的类型,E 表示实体对象id的类型。
package com.zzz.mybatis.mapper;
import java.util.List;
/**
* Created by tao.zeng on 2017/9/28.
*/
public interface BaseMapper<T, E> {
/**
* 查询所有数据
*
* @return
*/
List<T> findAll();
/**
* 根据 id 查询数据
*
* @param id
* @return
*/
T findById(E id);
/**
* 保存数据
*
* @param t
* @return
*/
int save(T t);
/**
* 修改数据
*
* @param t
* @return
*/
int update(T t);
/**
* 删除数据
*
* @param id
* @return
*/
int delete(E id);
}
如果没有特殊的要求,单纯的操作依赖于该类可以完成单表的基本操作。
这里贴一下操作部门的mapper,纳尼?空的?对,目前这里面什么都可以不用做,只需要通过泛型知道操作的是 Dept 对象已经Dept 对象中id的类型
package com.zzz.mybatis.mapper;
import com.zzz.mybatis.model.Dept;
/**
* Created by tao.zeng on 2017/9/29.
*/
public interface DeptMapper extends BaseMapper<Dept, Long> {
}
贴出mapper映射文件
<?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 指定当前 mapper 和 Mapper对象的映射关系 -->
<mapper namespace="com.zzz.mybatis.mapper.DeptMapper">
<!-- 因为实体对象中的属性名称和数据库字段名称不一样,通过resultMap来进行映射 -->
<resultMap id="deptMapper" type="com.zzz.mybatis.model.Dept">
<!-- property 实体对象中的属性名称 column 数据库中字段的名称-->
<id property="deptId" column="dept_id"/>
<result property="deptName" column="dept_name"/>
</resultMap>
<!-- 通过 select 标签进行查询操作,这里查询的是所有信息 -->
<select id="findAll" resultMap="deptMapper">
select * from dept
</select>
</mapper>
7. 测试运行
@org.junit.Test
public void test() {
SqlSession session = SqlSessionFactoryUtil.openSqlSession();
DeptMapper mapper = session.getMapper(DeptMapper.class);
List<Dept> depts = mapper.findAll();
for (Dept dept : depts) {
System.out.println(dept);
}
// 一定记得及时关闭 SqlSession 释放资源
session.close();
}
以上记录了mybatis最基本的操作,完整代码见
https://github.com/zzz-tao/mybatis