两个很有名的持久层hibernate和mybatis应该很熟悉不过了,两者最大相同点是底层都是对jdbc的封装,最大的不同点是前者是自动生成sql语句,后者是需要我们在映射文件中写出sql。
其实从以前就一直想看看mybatis源码的,由于自己太懒了就一直拖了下来,最近没啥事,就看看源码吧!
都说mybatis是对jdbc的封装当然,那到底是怎么封装的呢?眼见为实!还是跟以前一样,如果只看mybatis有点不过瘾,于是我们就顺便从最基本的jdbc开始看起!
1.简单看看JDBC
JDBC大家应该不陌生了,其实就是java对数据库CRUD操作的工具(或者叫做api),然后我们学的所有对数据库操作的框架的底层就是JDBC的一些封装,可能是框架什么的用得多了,我也经常会忘了JDBC步骤是什么,偶尔还是要拿出来看看啊!
不过我掌握JDBC的步骤就五个字 “贾琏欲执事”,其实就是“加,连,预,执,释放”,其实就是加载数据库驱动,获得连接,预处理对象,执行sql语句,释放资源。
大概的逻辑就是如此,我们大概看一下最原始的jdbc代码,没啥好说的!
public class TestJdbc { public void insert() { String driver="com.mysql.jdbc.Driver"; String url="jdbc:mysql:/localhost:3306/testJdbc"; String user="root"; String password="123456"; Connection conn=null; PreparedStatement pstmt=null; String sql="insert into user values(?,?)"; try { //1、注册驱动 Class.forName(driver); //2、获取连接 conn= DriverManager.getConnection(url, user, password); //3、创建预处理对象 并设置参数 pstmt = (PreparedStatement) conn.prepareStatement(sql); pstmt.setString(1, "xiaowang"); pstmt.setString(2, 18); //4、执行sql语句 pstmt.executeUpdate(sql); //5、处理结果集,如果有的话就处理,没有就不用处理,当然insert语句就不用处理了 } catch (Exception e) { e.printStackTrace(); } finally{ //6、关闭资源 try { if(pstmt!=null)pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } try { if(conn!=null)conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
而且JDBC的增删改查其实分为两类,增删改是一类,执行sql语句使用pstmt.executeUpdate(),返回一个整数,1代表成功,0代表失败;查询是另外一类,执行sql语句用pstmt.executeQuery(),返回的是一个结果集ResultSet,后续的就可以对结果集进行遍历,做一些处理从而得到我们需要的数据。
2.搭建原始mybatis环境(JDK1.8+eclipse)
这里我们就看最原始的mybatis就可以了,比较直观!这回我们新建一个最普通的maven项目,目录如下:
不用下mapper接口,指定命名空间即可!
数据库建表语句:
CREATE TABLE `user` ( `user_id` int(32) NOT NULL COMMENT '用户id', `user_name` varchar(64) default NULL COMMENT '用户姓名', `user_age` int(3) default NULL COMMENT '用户年龄', PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
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="com.wyq.mapper"> <resultMap > <id column="user_id" property="id" jdbcType="INTEGER"></id> <result column="user_name" property="name" jdbcType="VARCHAR" /> <result column="user_age" property="age" jdbcType="INTEGER" /> </resultMap> <sql > user_id, user_name, user_age </sql> <!-- 根据id查询 user 表数据 --> <select > select <include ref> from user where user_id = #{id,jdbcType=INTEGER} </select> <!-- 查询 user 表的所有数据 --> <select > select <include ref> from user </select> <!-- 向 user 表插入一条数据 --> <insert > insert into user(<include ref>) value(#{id,jdbcType=INTEGER},#{name,jdbcType=VARCHAR},#{age,jdbcType=INTEGER}) </insert> <!-- 根据 id 更新 user 表的数据 --> <update > update user set user_name=#{name,jdbcType=VARCHAR} where user_id=#{id,jdbcType=INTEGER} </update> <!-- 根据 id 删除 user 表的数据 --> <delete > delete from user where user_id=#{id,jdbcType=INTEGER} </delete> </mapper>