1. 基础扫盲与知识梳理
1.1 什么是数据库?
数据库:存储在计算机内、有组织的、统一管理的相关数据的集合(这个集合通常是一张张二维表即关系型数据库)。
数据库管理系统:用于用户与操作系统之间的一层数据库管理软件,它提供访问数据库的基本方法。
数据库系统:实现有组织地、动态地存储大量关联数据、方便多用户访问的系统。
提出以上三个概念主要是引出以下结论。
总结:数据库中并没有语句,全是数据(SELECT,INSERT这些语句是由数据库管理系统提供的),数据库管理系统还提供命令行和远程命令调用的方式来访问数据库。
1.2 什么是JDBC?
JDBC(java database connection它是用于Java编程语言和数据库之间的数据库无关连接的标准Java API。也就是说java要想连数据库,必须找他。(除非你手写底层协议,因为任何网络连接在java中都是一个socket,除非你能手写一个jdbc连接的socket,这没有必要,因为你手写也必须按照数据库连接的标准来写,写出来的百分之80和jdbc雷同,还有百分之二十是bug。)数据库连接其实是java线程与数据库系统进行连接访问(因为数据库只是表,不能解析sql,sql指令最终发给的是数据库管理系统)。
总结:java语言想要连接访问数据库必须用JDBC。除非手写底层协议。
1.3 什么是mybatis?
对mybatis的描述有很多,从应用者可以描述为mybatis是一个半ORM框架,什么是orm框架呢?orm(Object Relation Mapping对象关系映射)框架是指实现了关系型数据库到对象映射的框架,打个比方,下面这条两条语句执行完数据库就应该要插入一条名字叫tom,年龄18,身高160的记录。
User user = new User("tom",18,160);
user.save();
那么为什么又要说mybatis是一个半ORM框架呢?这个半字体现在哪里?
1.4 ORM框架的基本要求
ORM框架是对象关系映射的框架,根据名字可以得到两个重要的角色:对象,关系。对象是指java中的对象,也就是类的实例。关系这里表示的是关系型数据库。也就是说ORM是对对象和表之间映射操作的封装,按照这个理解就应该是java程序员只需要关心哪个对象对应哪张或者哪几张表就行了,而不需要去写select,insert,等语句。因为如果是要写select、insert这些语句的话那么就应该叫做对象关系映射操作框架其中“操作”就是指的CURD操作。
总结:ORM应该是一个操作者只需要关心哪张表或哪几张表对应哪个对象怎么个对应法的框架,其他操作ORM框架应该自我完善和提供。
1.5 ORM框架的基础
前面说到ORM框架是一个对象关系映射的框架,这里的关系是指数据库表,那么从这个层面看,ORM框架就是一个封装了数据库表操作的一个框架。那么它的实现必须要基于JDBC。ORM框架能做的就是尽量让程序员少些一点代码。
总结:ORM框架基于JDBC,封装JDBC的繁琐代码
1.6 JDBC中最基础的三个对象
JDBC是一套标准接口,简单的来说JDBC是一堆接口,并没有实现的代码,实现的代码由各个数据库厂商提供。所以要对mysql进行连接需要mysql的驱动包,需要对oracle连接需要oracle的驱动包。但是任何数据库连接都需要有三个基本的角色(抽象的通信):
Connection | 连接对象 | 找服务器 |
---|---|---|
Statement | 称述(请求)对象 | 发送指令(sql) |
ResultSet | 结果集对象 | 接收结果 |
为什么一定要有这三个对象,jdbc中有很多对象为什么这三个才是基础呢?因为它们三个完整的刻画了一次通信。connection用于通信它的功能在于为你找到你想要连接的数据库并且连接它,statement用于包装请求的信息,比如说你想要到数据库中查一条记录你如何表述这个消息?statement用来发给数据库的指令,ResultSet用于包装指令的返回结果。这样这三个对象就刻画了一次通信。(细细想来web通信也是如此呢,HttpServlet,HttpRequest,HttpResponse)
总结:JDBC中最基本的三个对象(连接,请求,结果集)可以刻画一次完整的通信。
1.7 用原生的jdbc来写一个数据库访问操作
- 建库建表,为了方便我借用eova的系统表来演示(eova是一个能快速开发的基于元数据驱动的系统,是一个系统,不需要写java代码就能开发出一个web项目大家如果需要极速开发可以考虑),sql语句如下:
/*
Navicat MySQL Data Transfer
Source Server : localhost
Source Server Type : MySQL
Source Server Version : 50719
Source Host : localhost:3306
Source Schema : eova
Target Server Type : MySQL
Target Server Version : 50719
File Encoding : 65001
Date: 15/08/2019 15:43:20
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for eova_user
-- ----------------------------
DROP TABLE IF EXISTS `eova_user`;
CREATE TABLE `eova_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`login_id` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '帐号',
`login_pwd` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密码',
`rid` int(11) NOT NULL DEFAULT 0 COMMENT '角色ID',
`version` int(11) NULL DEFAULT 1,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 'EOVA用户' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of eova_user
-- ----------------------------
INSERT INTO `eova_user` VALUES (1, 'IcantleaveU', '123456', 1, 1);
SET FOREIGN_KEY_CHECKS = 1;
- 导入mysql驱动jar包
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
-
编写java程序进行数据库查询操作
pojo对象作为实体类。
package cn.framework.entity; /** * @author lxc Q:1210922622 * @create 2019-08-14 9:37 * @desc **/ public class User { private int id; private String username; private String password; private int rid; private int version; @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", rid=" + rid + ", version=" + version + '}'; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getRid() { return rid; } public void setRid(int rid) { this.rid = rid; } public int getVersion() { return version; } public void setVersion(int version) { this.version = version; } }
主方法:
package cn.framework.core; import cn.framework.entity.User; import java.sql.*; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * @author lxc Q:1210922622 * @create 2019-08-14 9:31 * @desc **/ public class JdbcTest { public static void main(String[] args) { Connection conn=null; PreparedStatement pstm=null; ResultSet rs=null; List result= new ArrayList<User>(); try{ /**加载驱动类,因为jdbc只是数据库操作的接口而已,它并不知道有mysql的存在。因此需要加载mysql的驱动。执行完这一步相当于在DriverManager中add了一个mysql自己写的Driver驱动类,以后所有有关于jdbc:mysql:开头的协议都由Driver提供连接。 **/ Class.forName("com.mysql.jdbc.Driver"); /**获取连接,有jdbc:mysql打头的协议统统交给com.mysql.jdbc.Driver类所注册的对象,由它里面的方法来得到一个专属于mysql的连接。 **/ conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/eova?username=root&password=123456&useSSL=true"); /**连接已经拿到表示数据库管理系统与java进程已经得到了连接可以传输数据了,数据库管理系统是可以解析指令的,所以可以写sql语句进行查询操作。 **/ pstm = conn.prepareStatement("select * from eova_user"); /** 执行这条语句时,相当于在向数据库服务器发起远程请求,数据库服务器接到请求后会回复信息,信息会以二进制的方式进行传输,传输到java进程监听的端口上,而mysql的jdbc驱动正在监听这个端口,于是拿到了数据并把它封装成了一个ResultSet(一个标准的JDBC结果集)对象 **/ rs = pstm.executeQuery(); /** ResultSet标准接口里面封装了以"""行"""的形式组织起来的数据结构,以游标作为索引,提供了一个next方法进行游标移动的方法,初始情况下游标在第一条数据的上一行,所以要想获得第一条数据需要先执行rs.next();next方法还会返回一个值表示即将要移动到的行是否已经溢出当前resultSet结果集 **/ while(rs.next()){ User user = new User(); user.setId(rs.getInt("id")); user.setUsername(rs.getString("login_id")); user.setPassword(rs.getString("login_pwd")); user.setRid(rs.getInt("rid")); user.setVersion(rs.getInt("version")); result.add(user); } }catch (Exception e){ e.printStackTrace(); }finally { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } try { pstm.close(); } catch (SQLException e) { e.printStackTrace(); } try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } result.stream().forEach(x->System.out.print(x)); } }
运行结果:
1.8 本章总结
本章主要介绍了mybatis框架的本质是一个对JDBC封装的框架,以及为什么mybatis是一个半ORM框架。阅读完本章你应该要较为清晰的明白数据库系统对于JDBC来说就像是一个网站服务器一样,也有自己的host和port。原因是数据库系统与外部的交互本质是TCP协议支持的交互。