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对象)映射成数据库中的记录。
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;
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 语句,屏蔽数据库的差异