MyBatis原理总结(手写实现类)

匿名 (未验证) 提交于 2019-12-02 23:48:02

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

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

目录结构:

/**  * 用户的持久层接口  */ 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语句的。

执行结果,一模一样。

引申


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

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

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

MyBatis原理分析:

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

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

进而做如下操作:

使用反射封装

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

5.返回结果

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

1. 连接信息

通过方法:

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

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

Proxy.newProxyInstance()

此方法的封装:

<?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>

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!