前言
一、mybaits框架是什么?
MyBatis是一个用Java语言编写的持久层框架,其封装了JDBC的操作细节,使得开发者只需关注SQL语句本身,而无需关注注册驱动,创建连接等繁琐重复的过程。MyBatis框架使用了ORM(Object Relational Mapping)的思想来实现结果集的封装。(ORM简单说就是将数据库表与实体类及类的属性对应起来,通过操作实体类来操作数据库)
二、三层体系架构
在了解什么是MyBatis框架之前,我们需要先回忆一下在软件体系结构中学习到的三层体系架构(表现层、业务层与持久层),表现层顾名思义用于向用户展现页面与信息,是与用户直接接触的,表现层采用MVC模式,即Model模型、View视图与Controller控制器;业务层将项目的业务中所有的操作封装成方法;持久层则用于建立实体类与数据路表间的映射,完成对象数据和关系数据的转换。MyBatis是持久层的框架
三、mybaits如何使用JDBC完成动态配置ORM映射的?
mybaits使用mybaits-config.xml解析xml里面的内容将数据封装到jdbc的代码中,通过反射和动态代理实现从代码到数据库字段的ORM映射。其实使用mapper的配置地址绑定真实mapper文件的xml,通过namespace实现映射绑定。
MyBaits组件大致内容
四、使用jdbc代码简单实现mybaits的查询
1.实现mybaits简单查询的代码主体
1)依赖文件
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>compile</scope>
</dependency>
2)代码文件
package com.org.mybaits;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.*;
public class MybaitsV1<T> {
private static Properties properties=new Properties();
@Test
public void test() throws Exception {
try {
loadProperties("jdbc.properties");
} catch (IOException e) {
e.printStackTrace();
}
// 实现查询user的
Map map=new HashMap();
map.put("userName","xiaohua");
map.put("address","北京");
List<T> prepare = queryByParams("prepare", map);
System.out.println(prepare.toString());
}
public List<T> queryByParams(String StatementType, Object param) throws Exception {
DruidDataSource druidDataSource=new DruidDataSource();
druidDataSource.setDriverClassName(properties.getProperty("db.mybaits.driver"));
druidDataSource.setUrl(properties.getProperty("db.mybaits.url"));
druidDataSource.setUsername(properties.getProperty("db.mybaits.username"));
druidDataSource.setPassword(properties.getProperty("db.mybaits.password"));
DruidPooledConnection connection = druidDataSource.getConnection();
PreparedStatement statement=null;
if(StatementType.equals("prepare")){
statement = connection.prepareStatement(properties.getProperty("db.mybaits.queryById"));
}
// 获取参数并且设置参数
if(param instanceof Integer){
statement.setObject(1,param);
}else if(param instanceof String){
statement.setObject(1,param);
}else if(param instanceof Map){
Map map=(Map) param;
String[] params = properties.getProperty("db.mybaits.params").split(",");
for (int i = 0; i < params.length ; i++) {
String name =params[i];
Object value=map.get(name);
statement.setObject(i+1,value);
}
}
// 获取返回结果
ResultSet resultSet = statement.executeQuery();
Class forName= Class.forName(properties.getProperty("db.mybatis.resultType"));
List<T> targetList=new ArrayList<T>();
while (resultSet.next()){
Object o = forName.newInstance();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
for (int i = 0; i < columnCount; i++) {
String columnName = metaData.getColumnName(i+1);
Field declaredField = forName.getDeclaredField(columnName);
declaredField.setAccessible(true);
declaredField.set(o,resultSet.getObject(columnName));
}
targetList.add((T) o);
}
return targetList;
}
public static void loadProperties(String propertiesName) throws IOException {
properties.load(getInputStream(propertiesName));
}
private static InputStream getInputStream(String propertiesName) {
return MybaitsV1.class.getClassLoader().getResourceAsStream(propertiesName);
}
}
2.jdbc.properties配置文件
db.mybaits.driver=com.mysql.cj.jdbc.Driver
db.mybaits.url=jdbc:mysql://localhost:3306/ssmigtn?useUnicode=true&useSSL=true&Character=UTF8&serverTime=UTC
db.mybaits.username=root
db.mybaits.password=123
db.mybaits.queryById=select * from user where userName=? or address=?
db.mybaits.params=userName,address
db.mybatis.resultType=com.org.mybaits.po.User
3.实体类
package com.org.mybaits.po;
import lombok.Data;
@Data
public class User {
private Long userId;
private String userName;
private String passWord;
private Integer age;
private String phone;
private String address;
}
4.数据库表文件
/*
Navicat MySQL Data Transfer
Source Server : localhost_3306
Source Server Version : 80022
Source Host : localhost:3306
Source Database : ssmigtn
Target Server Type : MYSQL
Target Server Version : 80022
File Encoding : 65001
Date: 2022-03-18 14:15:14
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`userId` bigint NOT NULL COMMENT '用户编号',
`userName` varchar(30) DEFAULT NULL COMMENT '用户名称',
`passWord` varchar(30) DEFAULT '123456' COMMENT '用户密码',
`age` int DEFAULT NULL COMMENT '用户年龄',
`phone` varchar(10) DEFAULT NULL COMMENT '电话',
`address` varchar(30) DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('99622521338331136', 'admin', '123456', '18', '11232334', '北京');
INSERT INTO `user` VALUES ('99622521338331137', 'xiaohua', '333333', '21', '2525255', '上海');
这是简单对jdbc面向对象简单实现mybaits框架的过程。下次会使用xml的形式发布第二版,到时候基本和mybaits的源码实现有大部分相同。大家可以通过这个demo来深入了解mybaits的框架做了什么,对于新手来说能有更好的理解。