架构分析


MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。 MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索。MyBatis 可以使用简单的XML 或注解用于配置和原始映射,将接口和 Java 的 POJO( Plain Old Java Objects,普通的Java 对象)映射成数据库中的记录。

该图引用于51CTO

借助于该架构图我们可以发现,Mybatis的功能架构分为三层:

(1)API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。

(2)数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。

(3) 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

作为持久层框架,mybatis可以将程序中的大量sql语句剥离出来,配置在配置文件中,实现sql的灵活配置。可以将sql语句和代码分离,无需修改代码,在配置文件中修改配置文件即可到达修改sql的目的。

开发人员面对的是纯粹的java对象,和hibernate的orm思想一致。但对于具体的数据操作,hibernate会自动生成sql语句,而mybatis使用的时候,需要开发人员编写配置文件,将sql所需要的参数和返回的结果字段映射到具体的pojo。


maven依赖

为了方便,构建的是maven项目,需要的依赖分别有:

  1. junit     (java单元测试依赖)
  2. mybatis(mybatis依赖)
  3. mysql   (mysql数据库依赖)
  4. log4j    (日志信息依赖)
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.1</version>
</dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency> </dependencies>

建立数据库

为了测试mybatis的功能,首先建立一个简单的数据库,比较简单,数据库字段含义不再赘述。

create database mybatis;

use mybatis;

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`)
)

建立pojo对象

在这里建立了一个非常简单的pojo类,用于测试mybatis的功能。

/**
* fayuan.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package com.fayuan.domain; /**
* 用户类
*
* @author fayuan.fzw
* @version $Id: User.java, v 0.1 2018年02月18日 上午11:05 fayuan.fzw Exp $
*/
public class User { /** id */
private int id; /** 姓名 */
private String name; /** 性别 */
private String sex; /** 年龄 */
private int age; public User(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
} public int getId() {
return id;
} public void setId(int 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 int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
}
}

  这个类其实就是一个普通的javaBean,mybatis使用pojo类作为持久化类,这也是mybatis低侵入设计的关键。mybatis不需要持久化类继承任何父类,或者实现接口,可以保证代码的无侵入无污染。


pojo和数据库表字段映射

为了实现pojo和数据表中字段的映射,需要通过配置文件来配置具体的映射。

<?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 namespace="com.fayuan.mapper.UserMapper"> <!--
id="save"是唯一的标示符
parameterType属性指明插入时使用的参数类型
useGeneratedKeys="true"表示使用数据库的自动增长策略
-->
<insert id="save" parameterType="com.fayuan.domain.User" useGeneratedKeys="true">
insert into tb_user (name,sex,age) VALUES (#{name},#{sex},#{age})
</insert> <!-- select操作
parameterType="int"表示该查询语句需要一个int类型的参数
resultType="user"表示返回的是一个user对象 -->
<select id="select" parameterType="int" resultType="User">
select * from tb_user where id=#{id}
</select> <!-- update操作
parameterType="user"表示该更新语句需要一个user对象作为参数-->
<update id="update" parameterType="User">
update tb_user set name= #{name},sex= #{sex},age=#{age} where id= #{id}
</update> <!-- delete操作
parameterType="int"表示该查询语句需要一个int类型的参数-->
<delete id="delete" parameterType="int">
delete from tb_user where id=#{id}
</delete> </mapper>

在这里一次性添加了增、删、查、改的映射关系,为了实现每一部分的功能,对于每一部分单独写一个测试类。

插入

/**
* Alipay.com Inc.
* Copyright (c) 2004-2018 All Rights Reserved.
*/
package com.fayuan.test; import java.io.InputStream; import com.fayuan.domain.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; /**
* 测试插入功能
*
* @author fayuan.fzw
* @version $Id: InsertTest.java, v 0.1 2018年02月19日 下午4:02 fayuan.fzw Exp $
*/
public class InsertTest {
public static void main(String[] args) throws Exception { //读取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 ("fayuan","男",24); //插入数据
sqlSession.insert("com.fayuan.mapper.UserMapper.save", user); //提交事务
sqlSession.commit(); //关闭session
sqlSession.close();
}
}

打印出来的日志:

DEBUG [main] - ==>  Preparing: insert into tb_user (name,sex,age) VALUES (?,?,?)
DEBUG [main] - ==> Parameters: fayuan(String), 男(String), 24(Integer)
DEBUG [main] - <== Updates: 1

查找

/**
* fayuan.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package com.fayuan.test; import com.fayuan.domain.User;
import com.fayuan.factory.SqlSessionFactoryClass;
import org.apache.ibatis.session.SqlSession; /**
* 测试查找功能
*
* @author fayuan.fzw
* @version $Id: SelectTest.java, v 0.1 2018年02月24日 下午11:19 fayuan.fzw Exp $
*/
public class SelectTest {
public static void main(String[] args) { //获取Session实例
SqlSession sqlSession = SqlSessionFactoryClass.getSqlSession(); // 创建User对象
User user = sqlSession.selectOne("com.fayuan.mapper.UserMapper.select", 1); System.out.println("name = " + user.getName() + ", sex = " + user.getSex() +", age = " + user.getAge()); //提交事务
sqlSession.commit(); //关闭Session
sqlSession.close();
}
}

打印出来的日志:

DEBUG [main] - ==>  Preparing: select * from tb_user where id=?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1

修改

/**
* fayuan.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package com.fayuan.test; import com.fayuan.domain.User;
import com.fayuan.factory.SqlSessionFactoryClass;
import org.apache.ibatis.session.SqlSession; /**
* 测试修改功能
* @author fayuan.fzw
* @version $Id: UpdateTest.java, v 0.1 2018年02月24日 下午11:03 fayuan.fzw Exp $
*/
public class UpdateTest {
public static void main(String[] args) { //获取Session实例
SqlSession sqlSession = SqlSessionFactoryClass.getSqlSession(); // 根据id查询User对象
User user = sqlSession.selectOne("com.fayuan.mapper.UserMapper.select",1);
// 修改User对象的属性值
user.setName("tom");
user.setAge(25);
// 修改User对象
sqlSession.update("update", user);
// 提交事务
sqlSession.commit();
// 关闭Session
sqlSession.close();
}
}

打印出来的日志:

DEBUG [main] - ==>  Preparing: select * from tb_user where id=?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
DEBUG [main] - ==> Preparing: update tb_user set name= ?,sex= ?,age=? where id= ?
DEBUG [main] - ==> Parameters: tom(String), ?(String), 25(Integer), 1(Integer)
DEBUG [main] - <== Updates: 1

删除

/**
* fayuan.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package com.fayuan.test; import com.fayuan.factory.SqlSessionFactoryClass;
import org.apache.ibatis.session.SqlSession; /**
* 测试删除功能
*
* @author fayuan.fzw
* @version $Id: DeleteTest.java, v 0.1 2018年02月24日 下午11:55 fayuan.fzw Exp $
*/
public class DeleteTest {
public static void main(String[] args) throws Exception { // 获得Session实例
SqlSession session = SqlSessionFactoryClass.getSqlSession();
// 删除id为1的User对象
session.delete("com.fayuan.mapper.UserMapper.delete", 1);
// 提交事务
session.commit();
// 关闭Session
session.close();
} }

打印出来的日志:

DEBUG [main] - ==>  Preparing: delete from tb_user where id=?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Updates: 1 

问题总结:

  • 配置文件位置声明
  • pojo需要加上无参构造,否则在内部的反射机制是无法获得pojo对象的
  • 使用log4j观察执行状况
  • aliases的使用
  • 其他配置(pool、别名......)

关于mybatis的思考(1)——mybatis的使用实例的更多相关文章

  1. MyBatis学习(一)、MyBatis简介与配置MyBatis+Spring+MySql

    一.MyBatis简介与配置MyBatis+Spring+MySql 1.1MyBatis简介 MyBatis 是一个可以自定义SQL.存储过程和高级映射的持久层框架.MyBatis 摒除了大部分的J ...

  2. MyBatis学习总结(七)——Mybatis缓存(转载)

      孤傲苍狼 只为成功找方法,不为失败找借口! MyBatis学习总结(七)--Mybatis缓存 一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的 ...

  3. MyBatis学习 之 一、MyBatis简介与配置MyBatis+Spring+MySql

    目录(?)[-] 一MyBatis简介与配置MyBatisSpringMySql MyBatis简介 MyBatisSpringMySql简单配置 搭建Spring环境 建立MySql数据库 搭建My ...

  4. MyBatis简介与配置MyBatis+Spring+MySql

    MyBatis学习 之 一.MyBatis简介与配置MyBatis+Spring+MySql MyBatis学习 之 二.SQL语句映射文件(1)resultMap MyBatis学习 之 二.SQL ...

  5. 【转】MyBatis学习总结(七)——Mybatis缓存

    [转]MyBatis学习总结(七)——Mybatis缓存 一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualC ...

  6. 【转】MyBatis学习总结(一)——MyBatis快速入门

    [转]MyBatis学习总结(一)——MyBatis快速入门 一.Mybatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC ...

  7. 使用Mybatis Generator自动生成Mybatis相关代码

    本文将简要介绍怎样利用Mybatis Generator自动生成Mybatis的相关代码: 一.构建一个环境: 1. 首先创建一个表: CREATE TABLE pet (name VARCHAR(2 ...

  8. Mybatis特殊字符处理,Mybatis中xml文件特殊字符的处理

    Mybatis特殊字符处理,Mybatis中xml文件特殊字符的处理 >>>>>>>>>>>>>>>>& ...

  9. mybatis系列笔记(1)---mybatis入门

    mybatis入门   MyBatis是什么? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了goog ...

随机推荐

  1. 基于 HTML5 WebGL 的计量站三维可视化监控系统 Web 组态工控应用

    得益于 HTML5 WebGL 技术的成熟,从技术上对工控管理的可视化,数据可视化变得简单易行!完成对工控设备的管理效率,资源管理,风险管理等的大幅度提高,同时也对国家工业4.0计划作出有力响应! 如 ...

  2. Verilog 位拼接运算符的优先级

    最近研究FIFO的时候,在开源工程中看到这样一段代码 ; always @(posedge rd_clk) {'b0}}; else {'b0}}; else if(re) rp_bin <= ...

  3. 数据结构与算法之Stack(栈)的应用——in dart

    参考教科书上的一个应用例子,用栈来分析一行输入中的括号brackets是否匹配.用stdin读取用户输入,并输出检查结果.exit 退出. 注意这行代码: import 'stack.dart';// ...

  4. 修复Gradle CreateProcess error=206

    插件地址:https://plugins.gradle.org/plugin/ua.eshepelyuk.ManifestClasspath 修复Window系统中Gradle 路径太长问题, Fix ...

  5. 2017-2018-1 20155317 《信息安全系统设计基础》课堂实践——实现mypwd

    2017-2018-1 20155317 <信息安全系统设计基础>课堂实践——实现mypwd 1 . 学习使用pwd 很显然pwd命令的意思是打印出该文件当前的绝对路径 2 . 了解pwd ...

  6. 20155327 java第四周学习笔记

    20155327 java第四周学习笔记 五六章知识整理 1子类与父类 父类是接口或者是抽象类,子类必须继承自父类. 2子类的继承性 在Java中,通过关键字extends继承一个已有的类,被继承的类 ...

  7. JavaScript流程控制及函数

    1 流程控制 1.1 条件语句 分支结构 单向分支 if (条件表达式) { code...} 双向分支 if (条件表达式){    } else {    } <!DOCTYPE html& ...

  8. 异步任务(Celery)详解

    一.背景 在开发中,我们可能经常会遇到一些需要执行时间很长的任务,如果放在前端,会让用户一直卡在那儿等待或者一直转圈圈,体验非常不好.为了改善这种体验,我赶紧上网搜索,果然,前人早已有解决办法了.那就 ...

  9. WPF中的颜色转换

    HEX16色转Bursh: Brush brush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFF ...

  10. JUC——并发集合类

    如果要进行多个数据的保存,无疑首选类集(List.Set.Queue.Map),在类集的学习的时候也知道一个概念:许多集合的子类都具有同步与异步的差别,但是如果真的要在多线程之中去使用这些类,是否真的 ...