mybatis详解一:使用mybatis的理由

一:什么是mybatis
    	MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,
并且改名为MyBatis 。2013年11月迁移到Github。
    	iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。
    	iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)。
    	MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。
    	MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。
    	MyBatis 使用简单的 XML或注解用于配置和原始映射,
    将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。

二:使用mybatis替换jdbc原因
1.创建数据库user表
CREATE TABLE `user`  (
  `id` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `username` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名称',
  `birthday` timestamp NULL DEFAULT NULL COMMENT '生日',
  `sex` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '性别',
  `address` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
2.我们先看看jdbc的代码,再看我们不使用jdbc的原因。
package com.mybatis.pojo;

import java.util.Date;
import java.util.List;
public class User {
    private String id; //用户id
    private String username;//用户姓名
    private Timestamp birthday;//用户生日
    private String sex;//用户性别
    private String address;//用户地址

    public User() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Timestamp getBirthday() {
        return birthday;
    }

    public void setBirthday(Timestamp 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;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}
package com.mybatis;

import com.mybatis.pojo.User;

import java.sql.*;

/**
 * Created by user on 2019/1/24.
 */
public class JdbcUtils {
    //MySQL数据库驱动
    public static String driverClass = "com.mysql.jdbc.Driver";
    //数据库用户名
    public static String userName = "root";
    //数据库密码
    public static String passWord = "123";
    //数据库 URL
    public static String url = "jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8";
    //定义数据库连接
    public static Connection conn = null;
    //定义声明数据库语句,使用 预编译声明 PreparedStatement提高数据库执行性能
    public static PreparedStatement ps = null;
    //定义返回结果集
    public static ResultSet rs = null;

    public static User getUserById(String id){
        User user = new User();
        try {
            //加载数据库驱动
            Class.forName(driverClass);
            //获取数据库连接
            conn = DriverManager.getConnection(url, userName, passWord);
            //定义 sql 语句,?表示占位符
            String sql = "select * from `user` where `id`=?";
            //获取预编译处理的statement
            ps = conn.prepareStatement(sql);
            //设置sql语句中的参数,第一个为sql语句中的参数的?(从1开始),第二个为设置的参数值
            ps.setString(1, id);
            //向数据库发出 sql 语句查询,并返回结果集
            rs = ps.executeQuery();
            while (rs.next()) {

               user.setId(rs.getString("id"));
               user.setUsername(rs.getString("username"));
               user.setAddress(rs.getString("address"));
               user.setBirthday(rs.getTimestamp("birthday"));
               user.setSex(rs.getString("sex"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            //关闭数据库连接
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(ps!=null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return  user;
    }

    public static void main(String[] args) {
        System.out.println(JdbcUtils.getUserById("1"));
    }
}
三:分析
(如果你对mybatis还不熟悉,请暂时跳过此处分析,但是希望您掌握里mybatis的基本使用之后一定要回头看看此处分析,因为这是面试题经常问的一个问题)

通过上面的例子我们可以分析如下几点:

①、问题一:
//加载数据库驱动
Class.forName(driverClass);
//获取数据库连接
conn = DriverManager.getConnection(url, userName, passWord);
这两句代码让我们频繁的获取连接和关闭连接,造成数据库资源浪费,影响数据库性能。

解决办法:使用数据库连接池管理数据库连接

②、问题二:将 sql 语句硬编码到程序中,如果sql语句修改了,那么需要重新编译 Java 代码,不利于系统维护,也就不满足程序对扩展开放对修改关闭的条件。

解决办法:将 sql 语句配置到 xml 文件中,即使 sql 语句变化了,我们也不需要对 Java 代码进行修改,重新编译

③、问题三:在 PreparedStatement 中设置参数,对占位符设置值都是硬编码在Java代码中,不利于系统维护

解决办法:将 sql 语句以及占位符和参数都配置到 xml 文件中

④、问题四:从 resultset 中遍历结果集时,对表的字段存在硬编码,不利于系统维护

解决办法:将查询的结果集自动映射为 Java 对象

⑤、问题五:重复性代码特别多,频繁的 try-catch

解决办法:将其整合到一个 try-catch 代码块中

⑥、问题六:缓存做的很差,如果存在数据量很大的情况下,这种方式性能特别低

解决办法:集成缓存框架去操作数据库

⑦、问题七:sql 的移植性不好,如果换个数据库,那么sql 语句可能要重写

解决办法:在 JDBC 和 数据库之间插入第三方框架,用第三方去生成 sql 语句,屏蔽数据库的差异
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值