大家好,我是冰河~~最近很多朋友对ORM框架的实现很感兴趣。很多读者在冰河的微信上提问:冰河,你知道ORM框架是怎么实现的吗?比如MyBatis和Hibernte等ORM框架是如何实现的?为了让小伙伴们对ORM框架的实现原理有更深入更清晰的了解,冰河决定自己搭建一个极简版的ORM框架,让小伙伴们看一看就能明白什么是ORM框架?ORM框架是如何工作的?ORM框架如何映射程序对象和数据库中的数据?不过,在正式开始介绍ORM框架之前,我们需要搞清楚什么是ORM框架。什么是ORM框架?ORM的全称是:ObjectRelationalMapping,中文翻译为:ObjectRelationalMapping。也就是说,ORM框架是一个对象-关系映射框架,它通过元数据来描述对象-关系映射的细节。ORM框架在运行时,可以根据对应关系和映射关系将数据持久化到数据库中。其实本质上,ORM框架主要实现了程序对象到关系数据库数据的映射。说白了:ORM框架就是将实体以及实体与实体之间的关系转换成对应的SQL语句,通过SQL语句操作数据库,将数据持久化到数据库中,并进行相应的增删改查,对数据进行修改和查询操作。最常用的ORM框架有:MyBatis、Hibernate和JFinal。手动ORM框架在这里,我们通过Hibernate框架来模拟ORM的实现。小伙伴们也可以模拟其他ORM框架的实现。核心原则是相同的。如果你在模拟其他框架手工实现ORM时遇到问题,可以私聊我进行交流。如果我看到了,我会尽快回复你。好吧,让我们开始吧。@Table注解的实现首先,我们创建一个io.mykit.annotation.jdk.db.providerJava包,并在这个Java包中创建一个@Table注解。@Table注解标注在Java类上,表示当前类将映射到数据库中的哪个数据表上,如下图。packageio.mykit.annotation.jdk.db.provider;importjava.lang.annotation.Documented;importjava.lang.annotation.ElementType;importjava.lang.annotation.Inherited;importjava.lang.annotation.Retention;importjava.lang.annotation。RetentionPolicy;importjava.lang.annotation.Target;/***自定义表注解*@authorbinghe**/@Inherited@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceTable{Stringvalue()default"";}@Column注解的实现同理,在io.mykit.annotation.jdk.db.provider包下创建@Column注解,@Column注解标注在类中的字段上,表示当前类中的字段映射到数据表中的哪个字段,如下图。packageio.mykit.annotation.jdk.db.provider;importjava.lang.annotation.Documented;importjava.lang.annotation.ElementType;importjava.lang.annotation.Inherited;importjava.lang.annotation.Retention;importjava.lang.annotation。RetentionPolicy;importjava.lang.annotation.Target;/***自定义列注解*@authorbinghe**/@Inherited@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceColumn{Stringvalue()default"";}看到这里,不管是用过MyBatis的朋友,还是用过Hibernate的朋友,应该都有点体会了吧?是的,@Table注解和@Column注解,无论是在MyBatis框架还是在Hibernate框架中都会用到。这里,我们在包含极简ORM框架的时候,也用到了这两个经典的注解。创建一个实体类在io.mykit.annotation.jdk.db.provider.entity包下创建一个实体类User,@Table注解和@Column注解会分别注解在User类和User类中的字段上.映射到数据库中的数据表和数据表中的字段,如下图。packageio.mykit.annotation.jdk.db.provider.entity;importio.mykit.annotation.jdk.db.provider.Column;importio.mykit.annotation.jdk.db.provider.Table;/***自定义使用注解实体*@authorbinghe**/@Table("t_user")publicclassUserimplementsSerializable{@Column("id")privateStringid;@Column("name")privateStringname;publicUser(){super();}publicUser(Stringid,Stringname){super();this.id=id;this.name=name;}publicStringgetId(){returnid;}publicvoidsetId(Stringid){this.id=id;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}@OverridepublicStringtoString(){return"User[id="+id+",name="+name+"]";}}注解解析类的实现在io.mykit.annotation.jdk.db中。provider在.parser包中创建一个AnnotationParser类。AnnotationParser类是整个框架的核心。它负责解析标注在实体类上的注解,并将对应的实体类及其字段信息映射到对应的数据表和字段中,如下所示。packageio.mykit.annotation.jdk.db.provider.parser;importjava.lang.reflect.Field;importjava.lang.reflect.Method;importio.mykit.annotation.jdk.db.provider.Column;importio.mykit.annotation。jdk.db.provider.Table;/***解析自定义注解*@authorbinghe**/publicclassAnnotationParser{/***通过注解组装查询条件生成查询语句*@paramobj*@return*/publicstaticStringassembleSqlFromObj(Objectobj){Tabletable=obj.getClass().getAnnotation(Table.class);StringBuffersbSql=newStringBuffer();StringtableName=table.value();sbSql.append("select*from"+tableName+"where1=1");字段[]字段=obj.getClass().getDeclaredFields();for(Fieldf:fields){StringfieldName=f.getName();StringmethodName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);try{Columncolumn=f.getAnnotation(Column.class);if(column!=null){Methodmethod=obj.getClass().getMethod(methodName);Objectv=method.invoke(obj);if(v!=null){if(vinstanceofString){Stringvalue=v.toString().trim();//判断参数是否为类型参数1,2,3if(value.contains(",")){//去掉value,StringsqlParams=value.replace(",","").trim();//value为纯数字if(isNum(sqlParams)){sbSql.append("and"+column.value()+"in("+value+")");}else{String[]split=value.split(",");//重新将值设为空值="";for(inti=0;i
