「Mybatis实战八」:Mybatis的dao层开发使用 - 传统开发方式

文章讲述了传统MyBatis开发中遇到的模板代码重复、SQL硬编码耦合和设计复杂性增加等问题,以及MyBatis通过动态代理机制如何简化接口实现,降低代码耦合,提高开发效率和维护性。
摘要由CSDN通过智能技术生成

一、传统开发方式

1、基础工程代码

  1. 数据库环境

    CREATE DATABASE `mybatis_db`;
    USE `mybatis_db`;
    CREATE TABLE `user` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `username` VARCHAR(32) NOT NULL COMMENT '用户名称',
    `birthday` DATETIME DEFAULT NULL COMMENT '生日',
    `sex` CHAR(1) DEFAULT NULL COMMENT '性别',
    `address` VARCHAR(256) DEFAULT NULL COMMENT '地址',
     PRIMARY KEY (`id`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;
    
    
    -- insert.... 
    INSERT INTO USER(id,username,birthday,sex,address) VALUES (1,'张三','2024-01-01 00:00:00','男','北京'),(2,'李四','2023-01-01 00:00:00','男','上海');
    

在这里插入图片描述

  1. 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>org.example</groupId>
       <artifactId>mybatis-dao</artifactId>
       <version>1.0-SNAPSHOT</version>
    
       <!--指定编码及版本-->
       <properties>
           <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
           <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
           <java.version>1.11</java.version>
           <maven.compiler.source>1.11</maven.compiler.source>
           <maven.compiler.target>1.11</maven.compiler.target>
       </properties>
    
       <!--引入相关依赖-->
       <dependencies>
           <!--引入mybatis依赖-->
           <dependency>
               <groupId>org.mybatis</groupId>
               <artifactId>mybatis</artifactId>
               <version>3.5.3</version>
           </dependency>
    
           <!--引入mysql驱动-->
           <dependency>
               <groupId>mysql</groupId>
               <artifactId>mysql-connector-java</artifactId>
               <version>5.1.47</version>
           </dependency>
    
           <!--引入junit-->
           <dependency>
               <groupId>junit</groupId>
               <artifactId>junit</artifactId>
               <version>4.12</version>
           </dependency>
       </dependencies>
    
    </project>
    
  2. jdbc.properties

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql:///mybatis_db?useSSL=false&amp;characterEncoding=UTF-8
    jdbc.username=root
    jdbc.password=root
    
  3. SqlMapConfig.xml

    <?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>
       <properties resource="jdbc.properties"></properties>
    
       <typeAliases>
           <!--方式一:给单个实体起别名-->
    <!--        <typeAlias type="domain.User" alias="user"></typeAlias>-->
           <!--方式二:批量起别名 别名就是类名,且不区分大小写-->
           <package name="domain"/>
       </typeAliases>
    
       <!--环境配置-->
       <environments default="mysql">
           <!--使用mysql环境-->
           <environment id="mysql">
               <!--使用jdbc事务管理亲-->
               <transactionManager type="JDBC"></transactionManager>
               <!-- 使用连接池-->
               <dataSource type="POOLED">
                   <property name="driver" value="${jdbc.driver}"/>
                   <property name="url" value="${jdbc.url}"/>
                   <property name="username" value="${jdbc.username}"/>
                   <property name="password" value="${jdbc.password}"/>
               </dataSource>
           </environment>
       </environments>
    
       <!--加载映射配置-->
       <mappers>
           <mapper resource="UserMapper.xml"></mapper>
       </mappers>
    
    </configuration>
    
  4. UserMapper.xml

    <?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="user">
       <!--  查询所有用户  -->
       <select id="findAll" resultType="user">
           select *
           from user
       </select>
    
       <!--根据id查找用户-->
       <select id="selectById" parameterType="int" resultType="user">
           select * from user where id=#{id}
       </select>
    
       <!--新增用户-->
       <!--#{} : mybatis中的占位符,等同于JDBC中的
           parameterType :指定接收到的参数类型 -->
       <insert id="save" parameterType="domain.User">
           insert into user(username, birthday, sex, address)
           values (#{username}, #{birthday}, #{sex}, #{address})
       </insert>
    
       <!--  更新用户  -->
       <update id="update" parameterType="domain.User">
           update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
       </update>
    
       <!--删除用户 java.lang.Integer-->
       <delete id="delete" parameterType="int">
           delete from user where id = #{id}
       </delete>
    
    </mapper>
    
  5. User类

    package domain;
    
    import java.util.Date;
    
    public class User {
    
       private Integer id;
       private String username;
       private Date birthday;
       private String sex;
       private String address;
    
       @Override
       public String toString() {
           return "User{" +
                   "id=" + id +
                   ", username='" + username + '\'' +
                   ", birthday=" + birthday +
                   ", sex='" + sex + '\'' +
                   ", address='" + 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;
       }
    }
    
    
    

2、基于dao层的代码修改

  1. 编写UserMapper接口
package mapper;

import domain.User;

public interface UserMapper {

    public User findUserById(int id) throws Exception;
}

  1. 编写UserMapper实现
package mapper.impl;

import domain.User;
import mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class UserMapperImpl implements UserMapper {
    @Override
    public User findUserById(int id) throws Exception {
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //执行sql
        User user = sqlSession.selectOne("user.selectById", id);

        sqlSession.close();
        return user;
    }
}

  1. 测试代码

    package test;
    
    import domain.User;
    import mapper.UserMapper;
    import mapper.impl.UserMapperImpl;
    import org.junit.Test;
    
    public class MybatisTest {
    
        @Test
        public void testFindUserById() throws Exception {
            UserMapper mapper = new UserMapperImpl();
            User user = mapper.findUserById(1);
            System.out.println(user);
        }
    }
    
    
  2. 测试结果

    在这里插入图片描述

二、传统方式有哪些问题?

  1. 模板代码重复
    实现类(即DAO层的具体实现)中通常需要编写大量模板化的代码来与MyBatis的SqlSession进行交互,如打开会话、执行SQL、处理结果集以及关闭会话等。这些操作在每个DAO方法中都会出现,造成代码冗余。

  2. SQL硬编码耦合
    在Java实现类的方法中直接调用XML映射文件中的SQL statement时,往往需要硬编码具体的statement ID到Java代码中,导致了SQL语句和业务逻辑的紧密耦合,不便于维护和管理。

  3. 设计复杂性增加
    每个数据访问对象(DAO)都需要对应的接口和实现类,增加了项目的复杂性和工作量,并且使得项目架构不够简洁和易于扩展。

针对上述问题,MyBatis通过动态代理机制提供了优化方案:
MyBatis利用Java的动态代理技术,允许开发者只定义接口而不需编写其实现类。只需在接口方法上添加注解或在Mapper XML文件中配置SQL语句,MyBatis会在运行时自动生成接口的代理对象,该代理对象能够自动处理与数据库的交互过程,包括获取SqlSession、执行映射的SQL、处理结果并关闭会话等操作。这样不仅消除了模板代码重复的问题,同时也降低了SQL与Java代码之间的耦合度,使开发更加模块化和易维护。

  • 26
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值