我们在实际开发中,越简单越好,所以都是采用不写Dao实现类的方式。不管是使用xml还是直接配置。

但是MyBatis是支持写Dao实现类的

注意sqlSession是这里面的一个灵魂,有很多执行api

目录结构:

方法:

/**
* 用户的持久层接口
*/
public interface IUserDao {
List<User> findAll();
}

实现类:

public class UserDaoImpl implements IUserDao {

    private SqlSessionFactory factory;
//覆盖掉默认构造函数,这样就有了工厂,可以进一步创建对象
public UserDaoImpl(SqlSessionFactory factory){
this.factory = factory;
}
@Override
public List<User> findAll() {
//1.使用工厂创建SqlSession对象
SqlSession sqlSession = factory.openSession();
//2.使用sqlSession执行查询所有方法(此处需要的参数:(String statement)从配置文件中获取) namespace + id
List<User> userList = sqlSession.selectList("com.toov5.dao.IUserDao.findAll");
//使用完后关闭掉
sqlSession.close();
return userList;
}
}

实体类:

public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address; 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 getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} 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 +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}

全局配置文件:

<?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>
<!-- 配置环境 -->
<environments default="mysql">
<!-- 配置mysql的环境-->
<environment id="mysql">
<!-- 配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源(也叫连接池) -->
<dataSource type="POOLED">
<!-- 配置连接数据库的4个基本信息 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments> <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
<mappers>
<!--resource目录下 对应要创建相应的包 -->
<mapper resource="com/toov5/dao/IUserDao.xml"/>
</mappers>
</configuration>

映射文件:

<?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.toov5.dao.IUserDao">
<!--查询所有-->
<select id="findAll" resultType="com.toov5.entity.User">
select * from user;
</select>
</mapper>

测试类:

/**
* MyBatis测试类
*/
public class MyBatisTest {
public static void main(String[] args) throws IOException {
//1.读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2. 创建SqlSessonFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//如何解析,如何封装已经底层帮助实现了。细节封装了。
SqlSessionFactory factory = builder.build(in);
// SqlSessionFactory 是个接口,需要找实现。这个工厂是用来创建对象的,创建过程省略了
//3. 使用工厂生产SqlSession对象
SqlSession sqlSession = factory.openSession();
//不需要代理类了,SqlSession 是有查询方法的.使用工厂创建Dao对象,传入工厂
IUserDao userDao = new UserDaoImpl(factory);
//5.使用代理对象执行方法
List<User> userList = userDao.findAll();
userList.stream().forEach(
user ->{
System.out.println(user);
}
);
//6.释放资源
in.close();
}
}

Mybatis在用动态代理dao方式时候,也是找到对应的sql语句的。

执行结果,一模一样。

引申


补充,对于绝对路径和相对路径,绝对路径不准确,采用相对路径。

相对路径有两种方案可以获得。 1. 类加载器,只能读取类路径的配置文件     2. 使用ServletContext对象的getRealPath()

创建工厂,采用了构建这模式。隐藏了创建细节。使用户直接调用方法就可以拿到对象了

使用工厂模式生产SqlSession。降低类间的依赖,解耦合。

创建dao接口实现类使用了代理模式。不修改源码基础上对已有的方法增强。

MyBatis原理分析:

MyBatis在使用代理Dao的方式实现增删改查时候,做的什么事呢?

两件事:

一: 创建对象

二: 在代理对象中调用selectList

从一开始就需要解析配置文件,

进而做如下操作:

1. 根据配置文件的信息创建Connection对象,注册驱动,获取连接

2. 获取预处理对象PreparedStatement,此时需要SQL语句。 com.prepareStatement(sql)

3. 执行查询 ResultSet resultSet = preparedStatement.executeQuery();

4.遍历结果用于封装

List<E> list = new ArrayList();

while(resultSet.next()){

E element = xxx;   // 可以通过反射后去 class.forName("配置的全限定类名").newInstance();   使用反射封装

//  进行封装。把每个rs的内容都添加到element中,把element加入到list中

list.add(element);

}

于是我们就可以把表的列名看成是实体类的属性名称,就可以使用反射的方式来根据名称获取每个属性。

5.返回结果

综上所述: 需要提供方法两个信息

1. 连接信息

2. 映射信息,包含两部分:  执行的sql语句; 封装结果的实体类全限定类名。这两个信息作为属性定义对象。

     String  key  : nameSpace+id

     Mapper value :  String的sql语句    方法的全类名

通过方法:

session.getMapper(IUserDao.class) 实现了代理对象的创建

根据dao接口的字节码创建到的代理对象

public <T> getMapper(Class<T> daoInterfaceClass){

}

使用的的参数是 : 类加载器(与被代理对象使用相同的类加载器), Class数组:代理对象要实现接口的字节码数组, 如何代理(Handler)

Proxy.newProxyInstance()

此方法的封装:

s1.类加载器: 它使用的和被代理对象是相同的类加载器

s2.代理对象要实现的接口: 和被代理对象实现相同的接口

s3.如何代理: 它就是增强的方法,我们需要自己来提供

此处是一个InvocationHandler的接口,我们需要写一个该接口的实现类

调用该类的selectList方法

自定义MyBatis能通过入门案例看到的类:

class Resources

class SqlSessionFactoryBuilder

interface SqlSessionFactory

此时的pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.test</groupId>
<artifactId>mybatis</artifactId>
<version>1.0-SNAPSHOT</version> <dependencies>
<!--<dependency>-->
<!--<groupId>org.mybatis</groupId>-->
<!--<artifactId>mybatis</artifactId>-->
<!--<version>3.4.5</version>-->
<!--</dependency>-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

构建者构建工厂,工厂生产SqlSession。SqlSession可以做的事情很多。

总结:读取配置文件io流,解析出我们要的信息,交给构建者,构建者使用工具类,构建了工厂对象,工厂的openSession方法提供了sqlSession对象,sqlSession去干活。

下图信息量很大:

MyBatis原理总结(代码实现流程)的更多相关文章

  1. Mybatis原理和代码剖析

    参考资料(官方) Mybatis官方文档: https://mybatis.org/mybatis-3/ Mybatis-Parent : https://github.com/mybatis/par ...

  2. MyBatis原理-架构流程

    一 .MyBatis原理架构图 Mybatis的功能架构分为三层: API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库.接口层一接收到调用请求就会调用数据处理层来完成具体 ...

  3. mybatis自动生成代码插件mybatis-generator使用流程(亲测可用)

    mybatis-generator是一款在使用mybatis框架时,自动生成model,dao和mapper的工具,很大程度上减少了业务开发人员的手动编码时间 坐着在idea上用maven构建spri ...

  4. Mybatis技术原理理——整体流程理解

    前言:2018年,是最杂乱的一年!所以你看我的博客,是不是很空! 网上有很多关于Mybatis原理介绍的博文,这里介绍两篇我个人很推荐的博文 Mybatis3.4.x技术内幕和 MyBaits源码分析 ...

  5. mybatis 原理

    什么是Mybatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为 ...

  6. 《深入理解mybatis原理6》 MyBatis的一级缓存实现详解 及使用注意事项

    <深入理解mybatis原理> MyBatis的一级缓存实现详解 及使用注意事项 0.写在前面   MyBatis是一个简单,小巧但功能非常强大的ORM开源框架,它的功能强大也体现在它的缓 ...

  7. flume原理及代码实现

    转载标明出处:http://www.cnblogs.com/adealjason/p/6240122.html 最近想玩一下流计算,先看了flume的实现原理及源码 源码可以去apache 官网下载 ...

  8. OAuth的机制原理讲解及开发流程

    本想前段时间就把自己通过QQ OAuth1.0.OAuth2.0协议进行验证而实现QQ登录的心得及Demo实例分享给大家,可一直很忙,今天抽点时间说下OAuth1.0协议原理,及讲解下QQ对于Oaut ...

  9. 《深入理解mybatis原理》 MyBatis事务管理机制

    MyBatis作为Java语言的数据库框架,对数据库的事务管理是其很重要的一个方面.本文将讲述MyBatis的事务管理的实现机制. 首先介绍MyBatis的事务Transaction的接口设计以及其不 ...

随机推荐

  1. (一)WCF基础

    我们近期在做项目的时候用到了WCF,之前已经看了部分视频,对于WCF有了一定的了解,但仅限于能够根据搭建好的框架使用WCF,还不了解.所以就进行了研究,这样既有实践也能增加理论,二者结合,使用起来更胜 ...

  2. mysql占用内存过高调优方法

    最近测试一个站点,用mysql 5.6+mencache  内存16GB,但是进行查询的时候还是导致CPU占用过高,达到80%左右,所以想办法如何进行调优.以下几个参数进行参考选择 优化mysql数据 ...

  3. 【Java】《Java程序设计基础教程》第三章学习

    3.1 类 类在Java语言中是一种最基本的引用数据类型,是组成Java程序的基本要素.具有相同属性(状态)和方法(行为)的一组对象的集合称为类,其内部包括属性和方法两个主要部分. 3.11 类的定义 ...

  4. win 10 VMware与Hyper-v共存

    管理员身份运行命令提示符 cmd bcdedit /copy {current} /d "Windows10 no Hyper-V bcdedit /set {XXXXXXXX-XXXX-X ...

  5. 《Flask Web开发实战:入门、进阶与原理解析》 学习笔记

    一个视图函数可以绑定多个 URL 为了让互联网上的人都可以访问,需要安装程序的服务器有公网ip 如果过度使用扩展,在不需要 的地方引人,那么相应也会导致代码不容易维护 ,应该尽量从实际需求出发,只在需 ...

  6. SSM整合Dubbo案例

    一.Consumer子类 MyController类 @Controller @RequestMapping("/login") public class MyController ...

  7. Python + Apache Kylin 让数据分析更加简单!

    现如今,大数据.数据科学和机器学习不仅是技术圈的热门话题,也是当今社会的重要组成.数据就在每个人身边,同时每天正以惊人的速度快速增长,据福布斯报道:到 2025 年,每年将产生大约 175 个 Zet ...

  8. 代码格式化工具---indent工具

    indent工具,可以把代码格式化成某种风格. 通过命令:rpm -qa | grep indent 查看是否安装了indent工具. 若没有,可使用命令sudo apt-get  install   ...

  9. 利用fgetc统计文件所在字节 和 总行数 和单词数

    #include <stdio.h> #include <stdlib.h> #define IS_WHITE_SPACE(c) ((c)==' '||(c)=='\t'||( ...

  10. 机器学习---用python实现最小二乘线性回归算法并用随机梯度下降法求解 (Machine Learning Least Squares Linear Regression Application SGD)

    在<机器学习---线性回归(Machine Learning Linear Regression)>一文中,我们主要介绍了最小二乘线性回归算法以及简单地介绍了梯度下降法.现在,让我们来实践 ...