mybatis入门案例分析

mybatis入门案例分析

一、设计模式分析
public class MybatisTest {
    public static void main(String[] args) throws Exception{
        //1.读取配置文件
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3.使用工厂生产SqlSession对象
        SqlSession session = factory.openSession();
        //4.使用SqlSession创建Dao的代理对象
        IUserDao userDao = session.getMapper(IUserDao.class);
        //5.使用代理对象执行方法
        List<User> users = userDao.findAll();
        for(User user : users) {
            System.out.println(user);
        }
        //6.释放资源
        session.close();
        in.close();

    }
}
1.读取配置文件

在读取文件时,通常有两种方法,一种是采用绝对路径,另一种是采用相对路径。如果采用绝对路径,其缺点为不易迁移和部署,在开发时如果我们路径为“D:\SqlMapConfig.xml”,部署到服务器时,可能服务器上没有D盘。相对路径的缺点就在于,如果项目为Web工程,部署之后src目录就不存在了。因此在读取配置文件时,只有两种方法:

1.使用类加载器:只能读取类路径的配置文件。

2.使用SeverletContext对象的getPath()方法。

2.创建工厂

在创建工厂时,mybatis使用了构建者模式,builder就是构建者,把对象的创建细节隐藏,使用户直接调用方法便可获得对象。

3.生产SqlSession对象

生产SqlSession对象时使用了工厂模式,可以降低类间的依赖关系,便于之后对项目进行修改。

4.创建代理对象

创建DAO接口实现类的代理对象实现了使用了代理模式,这样就不需要自己写DAO实现类。

二、mybatis执行查询所有的分析
1.普通的java实现数据库查询

1.注册驱动,获取connection对象

2.创建数据库的执行sql的预处理对象

3.执行sql语句

4.封装查询结果

5.释放资源

public class JDBCTest {
    public static void main(String[] args) {
        JDBCTest test=new JDBCTest();
        test.firstJDBC();
    }

    public void firstJDBC(){
        Connection connection=null;
        PrepareStatement prepareStatement=null;
        ResultSet resultSet=null;

        try {
            //1.register,注册驱动
            DriverManager.registerDriver(new Driver());
            //2.得到数据连接。url格式:jdbc:mysql://主机IP:端口号/数据库名?user=用户名&password=密码
            //因为MySQL安装时,端口号默认设置的是3306,所以都是3306
            String url="jdbc:mysql://localhost:3306/sport?user=root&password=12345678";
            connection=DriverManager.getConnection(url);

            //3.得到数据库的执行sql对象
                String sql="select * from player"; //SQL查询语句
            prepareStatement=connection.prepareStatement();
            //4.执行语句
            resultSet=prepareStatement.executeQuery();
            while(resultSet.next()){
                //取出查询的信息
                String name=resultSet.getString("player_name");
                int age=resultSet.getInt("player_age");
                int score=resultSet.getInt("player_score");
                System.out.println("name="+name+",age="+age+",score="+score);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            //5.关闭资源
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(prepareStatement!=null){
                try {
                    prepareStatement.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(resultSet!=null){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    }

}
2.mybatis中如何实现查询
<!-- mybatis的主配置文件 -->
<configuration>
    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql的环境 -->
        <environment id="mysql">
            <!-- 配置事务的类型 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源(连接池) -->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的四个基本信息 -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="12345678"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
    <mappers>
        <mapper resource="dao/IUserDao.xml" />
    </mappers>
</configuration>

1.创建connection对象。通过主被配置文件SqlMapConfig.xml,我们可以获得连接数据库的信息(驱动、路径、用户名和密码)以及映射配置文件的位置。通过连接数据库的信息,我们可以构建connection对象。

<mapper namespace="dao.IUserDao">
    <!-- 配置查询所有 -->
    <select id="findAll" resultType="domain.User">
        select * from user;
    </select>
</mapper>

2.创建prepareStatement对象。通过映射配置文件的信息,我们可以获得执行的SQL语句和封装的实体类全限定类名,就可以创建prepareStatement对象。mybatis通过dom4j技术来解析xml文件获取上述信息。

3.存储解析结果。在获取相关信息中后,mybatis需要将执行的SQL语句和封装结果的实体类全限定类名组合起来定义成一个Mapper对象,每一个Mapper对象对应一个完整String类型的id(namespace+“.”+id)。例如本项目中的SQL语句为“select * from user;”,封装结果的实体类全限定类名为“domain.user”,完整的id为"dao.IUserDao.findAll",这些都是String类型的字段。

4.利用反射技术封装。创建prePareStatement对象之后,通过resultSet = prepareStatement.executeQuery();语句我们可以获得查询结果集,在对查询结果集进行封装时。我们通过完整的id(即封装结果的全限定类名),利用反射技术(Class.forName("domain.User").getDeclaredConstructor().newInstance();)即可进行封装。由于实体类的属性和数据库表中的列名一致,可以把表的列名当作是实体类的属性名称,然后利用反射技术来根据名称获取每个属性,并把值赋进去。反射参考链接

三、创建代理对象的分析
//MybatisTest.class
IUserDao userDao = session.getMapper(IUserDao.class);

//DefaultSqlSession.class
public <T> T getMapper(Class<T> type) {
        return this.configuration.getMapper(type, this);
}

//Configuration.class
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    return this.mapperRegistry.getMapper(type, sqlSession);
}

//MapperRegistry.class
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
     MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
     if (mapperProxyFactory == null) {
            throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
     } else {
            try {
                return mapperProxyFactory.newInstance(sqlSession);
            } catch (Exception var5) {
                throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
            }
     }
}

//MapperProxyFactory.class
public T newInstance(SqlSession sqlSession) {
        MapperProxy<T> mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);
        return this.newInstance(mapperProxy);
}

protected T newInstance(MapperProxy<T> mapperProxy) {
        return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
}

//Proxy.class
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
                                          InvocationHandler h) {
        Objects.requireNonNull(h);

        final Class<?> caller = System.getSecurityManager() == null
                                    ? null
                                    : Reflection.getCallerClass();

        /*
         * Look up or generate the designated proxy class and its constructor.
         */
        Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);

        return newProxyInstance(caller, cons, h);
}

上述是MybatisTest类中,getMapper()的调用层级。可以看到最终调用的方法是public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h),这个方法有三个参数,分别是:

1.类加载器loader:使用和被代理对象相同的类加载器

2.代理对象要实现的接口字节码数组interfaces:和被代理对象实现的是相同的接口

3.代理方式h:就是增强的方法,实际上就是一个InvocationHandler接口的实现类,在实现类中调用selectList方法(查询所有方法)。

mybatis入门案例,可以参考我的上一篇博客:mybatis入门实例

原文地址:https://www.cnblogs.com/liyier/p/12264180.html

时间: 2024-12-11 01:54:08

mybatis入门案例分析的相关文章

Mybatis入门案例中设计模式的简单分析

Talk is cheap, show me the code! public class TestMybatis { public static void main(String[] args) throws IOException { //1. 读取配置文件 InputStream resource = Resources.getResourceAsStream("mybatis.xml"); //2. 创建sqlSessionFactory工厂 SqlSessionFactory

ArcGIS for Desktop入门教程_第四章_入门案例分析 - ArcGIS知乎-新一代ArcGIS问答社区

原文:ArcGIS for Desktop入门教程_第四章_入门案例分析 - ArcGIS知乎-新一代ArcGIS问答社区 1 入门案例分析 在第一章里,我们已经对ArcGIS系列软件的体系结构有了一个全面的了解,接下来在本章中,将通过一个案例来熟悉ArcGIS for Desktop的使用,从解决问题的过程中,逐渐适应ArcGIS桌面的界面和操作方式. 本章的练习数据是一个住宅小区的简单平面示意图,需要在已有的基础上把楼房的轮廓补充完整,并加以整饰,完成一幅地图. 1.1 打开地图文档并浏览

MyBatis入门案例、增删改查

1.MyBatis是什么?(下载地址:https://github.com/mybatis/mybatis-3/releases) MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进. MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费

MyBatis入门案例 增删改查

一.MyBatis入门案例: ①:引入jar包 ②:创建实体类 Dept,并进行封装 ③ 在Src下创建大配置mybatis-config.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybat

【一】MyBatis入门案例

1. MyBatis的简介 MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架.MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索.MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plan Old Java Objects,普通的 Java 对象)映射成数据库中的记录. 2. 入门案例 (1). 新建一个 Java 工程,其目录结构如下: (2). 依次介绍目录结构下的文件 (a). MyB

Mybatis 入门案例分享

本文分享一下,Mybatis的一些入门案例: 为什么不用JDBC方式来操作数据库,而使用类似于Mybatis的框架呢? 1.  数据库链接创建.释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题. 解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接. 2.  Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码. 解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离. 3

1 mybatis入门案例

1 环境搭建 第一步:创建maven工程并导入坐标 第二步:创建实体类和dao的接口 第三步:创建Mybatis的主配置文件 SqlMapConifg.xml 第四步:创建映射配置文件 IUserDao.xml 2 环境搭建的注意事项 第一个:创建IUserDao.xml 和 IUserDao.java时名称是为了和我们之前的知识保持一致. 在Mybatis中它把持久层的操作接口名称叫做:Mapper 所以:IUserDao 和 IUserMapper是一样的 第二个:在idea中创建目录的时候

spring入门案例分析及原理

Springmvc执行原理: 一. 入门案例的执行流程 1. 当启动Tomcat服务器的时候,因为配置了load-on-startup标签,所以会创建DispatcherServlet对象,就会加载springmvc.xml配置文件2. 开启了注解扫描,那么HelloController对象就会被创建3. 从index.jsp发送请求,请求会先到达DispatcherServlet核心控制器,根据配置@RequestMapping注解找到执行的具体方法4. 根据执行方法的返回值,再根据配置的视图

intellij IDEA Mybatis入门案例

最近打算学习ssm框架  Mybatis 作为入门的第一个持久层框架,学习起来实在费劲.故写此文章作为入门案例. 先打开 IDEA建立一个Maven项目,目录结构如下: 源代码已经上传至GitHub   https://github.com/Wo-com/mybatis_demo,需要的点击下载 接下来说几个要点吧: 1.用mysql创建test数据库,添加一张user表,字段如下: 2.编辑  pom.xml  文件导入 jar包 <?xml version="1.0" enc