MyBatis

DAO层的其他工具与框架

JDBC 的缺陷

  • 代码啰嗦、开发效率低
  • 需要关注 Connection, preparedStatement, ResultSet 对象的创建与释放
  • ResultSet 的查询结果,需要自己封装为 List
  • 代码重复的地方多,
  • 业务代码和数据库的操作混杂在一起
  • 最严重的:SQL语句是硬编码在程序中的,造成了强耦合——如果要优化 SQL 语句,就需要对整个项目进行重新编译,打包。

Hibernate-数据库交互的框架(Object Relation Mapping,ORM),他将整个与 MySQL 操作有关的逻辑都封装好了。我们在编写业务的时候,不用管MySQL的具体操作。

  • 随这业务逻辑便的越来越复杂,对MySQL操作语句的要求变得越来越高,而Hibernate关于MySQL的操作又是封闭的,这就带来很大不便。即:无法满足定制SQL
  • 是一个全映射框架(即,每次查询默认查询所有字段),部分字段映射能做,但是很困难。

所以我们现希望:一个能支持定制化SQL,同时SQL语句也不要硬编码在Java程序中,并有着强大的功能。

原生 JDBC 的操作流程

  1. 获取数据库连接
  2. 写 SQL
  3. 获取 PreparedStatementps= connection.preparedStatement(sql),将参数化的SQL语句传给数据库进行预编译。
  4. 填充参数:ps.setObject(i+1, ars[i])
  5. 执行 sql:ps.excute()
  6. 封装结果

MyBatis

中文文档地址

MyBatis 是 SQL Mapper Framework for Java(SQL 映射框架),是一个强化版的 JDBC,即:

  • SQL Mapper:SQL 映射
    • 把数据库的表中的一行数据,映射成为一个 Java 对象。对这个对象的操作,就相当于操作表中的数据
  • Data Access Objects (DAOs): 数据访问
    • 对数据库进行增删改查。

MyBatis 底层就是对原生 JDBC 的一个简单封装。但其,将SQL硬编码在Java程序中这一部分抽取出来,改写在配置文件中。实现了 SQL 和 Java 编码分开的效果,功能边界清晰,一个专注业务,一个专注数据。

其余的步骤则封装成一个整体。

这样就完全解决了数据库优化问题,在带来了便捷性还保证了灵活性。

MyBatis 提供了哪些功能:

  • 提供了创建 Connection, Statement(PreparedStatement), ResultSet 的能力,不在需要我们来创建这些对象了
  • 提供了执行 sql 语句的能力,不用我们自己执行 sql
  • 提供了循环 sql,把 sql 查询结果转化为 Java 对象,List 集合的能力
  • 提供了关闭资源的能力,不用我们手动关闭了。

因此,我们只需要提供 SQL 语句。流程是:

  1. 提供 sql 语句
  2. MyBatis 处理该语句
  3. 得到 JavaBean 对象或 List 集合

Hello World

基础环境搭建:

  1. 创建一个数据库,其内有一个 user 表,字段如下:

    • id

    • name

    • password

    • address

    • phone

  2. 创建一个对应的 JavaBean:User

  3. 创建 UserDAO 接口

    public interface UserDAO {
         
        User getUserById(Integer id);
    }
    

MyBatis 开始:

  1. 导入三个包:

    • mybatis-3.5.7.jar
    • mysql-connector-java-8.0.23.jar
    • log4j-1.2.17:日志包,依赖于 classpath 目录下的 log4j.xml。(不需要日志的话,可不用)
  2. 写配置:

    1. 第一个配置文件:mybatis-config.xml,其作为 MyBatis 的 全局配置文件,配置了事务管理器,和dataSource。目的是:

      • 指导 MyBatis 如何正确运行,比如连接向哪个数据库。
    2. 第二个配置文件:编写 DAO 接口的实现配置文件,相当于 DAOImpl。主要实现以下几个地方

      • 1、namespace 属性:告诉 Mabits 当前配置文件用于实现哪个接口类

      • 2、重写接口类中的方法,如:<select> 标签用于重写查询类的方法,其中:

        • 属性:id-所实现接口中的方法名,resultType 指定返回值类型
        • 方法体中的占位符用:#{变量名} 代替。表示从传入参数中,取出变量名的值。
        <?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:名称空间:写接口的全类名,相当于告诉 Mybatis,这个配置文件用于实现哪个接口类-->
        <mapper namespace="top.soultop.dao.UserDAO">
            <!--select标签:用于定义一个查询操作.
                id 为接口中的方法名
                resultType 指定返回值类型(查询操作必须指定)
                #{id} 取出传递过来的id参数值-->
            <!--相当于对 public User getUserById(Integer id); 方法的实现-->
            <select id="getUserById" resultType="top.soultop.bean.User">
                select *
                from user
                where id = #{id}
            </select>
        </mapper>
        
      1. 在全局配置文件中,注册第二步的标签文件。最终的全局配置文件如下:

        <?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="development">
                <environment id="development">
                    <transactionManager type="JDBC"/>
                    <!--配置连接池-->
                    <dataSource type="POOLED">
                        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                        <property name="url" value="jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true"/>
                        <property name="username" value="root"/>
                        <property name="password" value="*******"/>
                    </dataSource>
                </environment>
            </environments>
        
            <!--引入我们自己编写的 每一个接口的 实现文件-->
            <mappers>
                <!--resource:从类目下 指出实现文件-->
                <mapper resource="UserDAO.xml"/>
            </mappers>
        </configuration>
        
  3. 测试:

    1. 先构建一个 SqlSessionFactory,用于创建 SqlSession
    2. 获取 SqlSession 用于操作数据库
    3. 获取 DAO 实现类
    public class MyBatisTest {
         
        @Test
        public void tt() throws Exception{
         
            // 1. 从 XML 中构建 SqlSessionFactory
            // SqlSession 工厂,用于创建 SqlSession对象 -- 类似于 Connection
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    
            // 2. 从 SqlSessionFactory 中获取 SqlSession(相当于getConnection())
            SqlSession openSession = sqlSessionFactory.openSession();
    
            try {
         
                //3.  获取到DAO接口的实现
                UserDAO userDAOMapper = openSession.getMapper(UserDAO.class);
    
                // 可以发现,userDAOMapper 中,可以调用 UserDAO 接口的实现。
                User userById = userDAOMapper.getUserById(1);
    
                System.out.println(userById);
            } finally {
         
                // 关闭资源
                openSession.close();
            }
        }
    }
    
    /**
    DEBUG 05-14 20:46:22,214 ==>  Preparing: select * from user where id = ?  (BaseJdbcLogger.java:137)  执行的sql语句
    DEBUG 05-14 20:46:22,251 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:137) 	参数填充过程
    DEBUG 05-14 20:46:22,292 <==      Total: 1  (BaseJdbcLogger.java:137) 	查询结果的数量
    User{id=1, name='章子怡', password='qwerty', address='Beijing', phone='13788658672'}
    */
    

流程总结

配置文件部分:

  1. 先写 MyBatis 的 全局配置文件,用于配置事务管理器,和 dataSource。作用是,指导 MyBatis 连接数据库的配置,及如何操作数据库

    • <configuration> :数据源配置
    • <mappers>:引入 接口实现的 配置文件
  2. 为 DAO 接口编写配置文件,相当于 DAOImpl。格式如下:

    <mapper namespace="top.soultop.dao.UserDAO">
        <!--select标签:用于定义一个查询操作.-->
        <select id
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值