在前几篇文章中,我对反射机制进行了详细的介绍,并且使用反射手写了一个SpringIOC框架。为了巩固和加深对反射机制的理解,本篇文章将使用反射封装一个简单的ORM框架。如果对反射不太熟悉的小伙伴,可以看我之前写的几篇文章【反射详解】【使用反射手写SpringIOC】,知识点非常齐全,相信看完以后,你一定会有所收获,并且可以更好的理解本篇文章。
我们在做开发的过程中,需要经常对数据库进行操作,这时我们就需要使用到ORM框架,例如比较常用的MyBatis和Hibernate。下面我将对ORM框架进行详细的介绍并且封装一个简单的ORM框架。
1.什么是ORM框架?
ORM,即0bject Relational Mapping (对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法即可。
简单来讲,就是通过类与数据库表的映射关系,将对象持久化到数据库中。
2.ORM框架的优点
当我们不使用ORM框架开发一个应用程序时,需要写很多sql语句,每一次执行,都要打开/关闭数据连接,这样在开发的过程是很麻烦的,而且开发效率低。并且像读取、保存和删除对象信息这些代码都是重复的,会造成代码冗余。而使用ORM框架可以很好的解决这些问题,使我们减少很多繁琐重复的工作量,让我们的注意力集中在实现业务上。
ORM框架优点如下:
- 操作简单,提高了开发效率;
- 减少重复代码,消除冗余;
- 数据访问更抽象,更轻便;
- 支持面向对象封装。
3.使用反射封装ORM框架
下面我将使用反射机制封装一个简单的ORM框架来实现插入功能。
3.1创建数据库表
首先需要创建一个数据库表,下面我们就使用user表进行演示。
create table user(
userId varchar(20) PRIMARY KEY not null,
userName varchar(20) not null,
password varchar(20) not null,
emil varchar(20) not null
);
3.2创建实体类
接着我们需要创建user表所对应的实体类。
public class User {
public String userId;
public String userName;
public String password;
public String emil;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
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 String getEmil() {
return emil;
}
public void setEmil(String emil) {
this.emil = emil;
}
}
3.3使用反射进行封装
使用反射把获取属性和属性值的功能进行封装,更有利于扩展。
public class DBUtils {
static final String JDBC_DRIVER="com.mysql.jdbc.Driver";
//数据库连接地址,根据自己的实际情况就行修改
static final String DB_URL="jdbc:mysql://127.0.0.1:3306/orm?useUnicode=true&characterEncoding=utf-8&useSSL=false";
//用户名和密码,根据自己的实际情况就行修改
static final String USER="root";
static final String PASSWORD="root";
public static Connection getConnection() throws Exception {
Connection connection=null;
try{
//1.加载驱动程序
Class.forName(JDBC_DRIVER);
//2.获得数据库链接
connection= DriverManager.getConnection(DB_URL, USER, PASSWORD);
System.out.println("数据库连接成功!");
}catch (Exception e){
e.printStackTrace();
}
return connection;
}
public static boolean insert(Object obj) throws Exception {
//1.获取数据库连接
Connection conn=getConnection();
//2.通过反射获取类对象
Class cls = obj.getClass();
//3.获取表名
String tableName=cls.getSimpleName();
//4.拼接sql语句
SQL sql = new SQL();
sql.INSERT_INTO(tableName);
sql.VALUES(Field(obj), FieldValue(obj));
String s=sql.toString();
//5.执行
Statement statement=conn.createStatement();
int result=statement.executeUpdate(s);
if(result!=0){
System.out.println("插入数据成功!");
return true;
}
return false;
}
public static String Field(Object obj) {
if (obj == null) {
return null;
}
// 获取class文件
Class cls = obj.getClass();
// 获取当前类所有属性
Field[] Fields = cls.getDeclaredFields();
String fieldSql = getField(Fields);
return fieldSql ;
}
public static String getField(Field[] declaredFields) {
StringBuffer sf = new StringBuffer();
for (int i = 0; i < declaredFields.length; i++) {
sf.append(declaredFields[i].getName());
if (i < declaredFields.length - 1) {
sf.append(",");
}
}
return sf.toString();
}
public static String FieldValue(Object obj) {
if (obj == null) {
return null;
}
// 获取class文件
Class cls = obj.getClass();
// 获取当前类的属性值
Field[] Fields = cls.getDeclaredFields();
String fieldValueSql = getFieldValue(obj, Fields);
return fieldValueSql ;
}
public static String getFieldValue(Object obj, Field[] declaredFields) {
StringBuffer sf = new StringBuffer();
for (int i = 0; i < declaredFields.length; i++) {
// 获取到属性值
try {
Field field = declaredFields[i];
// 允许操作私有属性
field.setAccessible(true);
// 获取当前属性的值
Object value = field.get(obj);
// 标识类型是否为string类型
boolean flag = false;
if (value != null && (value instanceof String || value instanceof Timestamp)) {
flag = true;
}
//如果是String类型,则加上'',不是则不加
if (flag) {
sf.append("'"+value+"'");
} else {
sf.append(value);
}
if (i < declaredFields.length - 1) {
sf.append(",");
}
} catch (Exception e) {
e.printStackTrace();
}
}
return sf.toString();
}
}
3.4效果演示
public class Test {
public static void main(String[] args) throws Exception {
User user=new User();
user.setUserId("000001");
user.setUserName("zhangsan");
user.setPassword("123456");
user.setEmil("123456789@qq.com");
DBUtils.insert(user);
}
}
运行结果
数据库user表
由运行结果可以看出,使用ORM框架插入数据成功。
我把源码打包放在了百度云网盘里面,如果有需要的请自取【源码地址】提取码【c3at】