ORM即Object Relation Mapping,Object就是对象,Relation就是关系数据库,Mapping映射,就是说Java中的对象和关系数据库中的表存在一种对应关系。

现在常见的ORM框架比如Hibernate和mybatis,都是采用了ORM的方式,基本原则就是类-表(Table)、属性-列(Column)这样的对应,所以一个对象就能表示数据表中的一行数据啦。

本文转自http://m.blog.csdn.net/woshisangsang/article/details/61916687

CSDN博客

基于注解和反射的Java ORM框架(1)-通过注解描述映射关系

发表于2017/3/13 14:09:39  330人阅读

分类: Java

一,ORM概念

ORM即Object Relation Mapping,Object就是对象,Relation就是关系数据库,Mapping映射,就是说Java中的对象和关系数据库中的表存在一种对应关系。

现在常见的ORM框架比如Hibernate和mybatis,都是采用了ORM的方式,基本原则就是类-表(Table)、属性-列(Column)这样的对应,所以一个对象就能表示数据表中的一行数据啦。

二,XML实现简单的ORM映射

使用XML实现简单的ORM映射还是非常直观的,加入有一张用户表结构如下:

对应的Java类如下:

package demo;
public class User {
private String userId;
private String userName;
}
  • 1
  • 2
  • 3
  • 4
  • 5

那么我们可以使用下面的xml描述对象-关系映射(具体的节点名、属性名都是随意设计的,只是为了说明意思):

<?xml version="1.0" encoding="UTF-8"?>
<!-- orm是所有映射的根节点 -->
<orm>
<!-- 每对映射使用一个mapping节点 -->
<mapping class="orm.User" table="User">
<property name="userId" column="user_id"/>
<property name="userName" column="user_name"/>
</mapping>
</orm>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

实际上,有了上面的xml文件,orm.User对象和User表的映射就建立明白了。当ORM框架运作的时候,只需要从xml加载这一个映射关系,就能知道对User对象进行操作时,该对那张表那些列进行操作了。从xml文件中读取数据的方法也有很多,此处不再介绍。

三,自定义注解

之前的xml配置文件是描述映射的,这些描述完全可以使用注解来实现,笔者感觉会更加简洁、直接。

既然是自定义注解,我们首先需要了解哪些是方面是可以自定义的:

1,可以自定义注解应用的元素。Java注解可以应用于包、类(接口)、方法、属性、构造器等,一般常用的也就类(接口)、方法、属性。

2,可以自定义注解使用的时机。比如是否编译的时候就把注解的信息丢掉,比如JVM运行时还是保留注解信息。如果运行时保留的话,就可以通过反射读取注解的内容了,所以自定义注解里面保存的ORM映射信息是可以在程序运行时使用的。

3,是否将注解包含在Javadoc帮助文档里面。

OK,口说太空洞我们来定义一个最简单注解,该注解的作用非常简单,就是说明类与数据库表的映射关系。自定义类使用的关键字是class,自定义注解使用的关键字更加高端的关键字@interface

package demo;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)//该注解用于修饰TYPE元素,也就是修饰类和接口等类型
@Retention(RetentionPolicy.RUNTIME)//该注解信息运行时保留
@Documented//该注解包含在Javadoc中
public @interface Table {//注解名为Table
//此处需要注意,注解中的每个方法表示该注解的一个可配置参数,default表示该配置参数的默认值
public String tableName() default "";
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

将该注解应用于User就是:

package demo;
//@Table对应自定义注解,tableName对应自定义注解中的方法,如果只用@Table则表示tableName采用默认的""作为值
@Table(tableName="User")
public class User {
private String userId;
private String userName;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

接下来就是需要详细的了解下@Target和@Retention的用法了,因为他俩决定了如何去定义一个注解。

@Target(ElementType.TYPE):表示注解用以修饰类、接口、enum、注解。
@Target(ElementType.FIELD):表示注解用以修饰属性
@Target(ElementType.METHOD):表示注解用以方法    @Retention(RetentionPolicy.SOURCE):源码之中是有的,编译时候丢弃
@Retention(RetentionPolicy.CLASS):编译后.class文件中还有,JVM丢弃之,所以运行时也看不到
@Retention(RetentionPolicy.RUNTIME):表示注解运行时可用
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

根据以上描述,我们需要自定义两个注解,分别用来描述类-表对应关系及属性-列对应关系,所以全部的源码应为:

//1,Table注解,描述类与表对应
package demo;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)//该注解用于修饰TYPE元素,也就是修饰类和接口等类型
@Retention(RetentionPolicy.RUNTIME)//该注解信息运行时保留
@Documented//该注解包含在Javadoc中
public @interface Table {//注解名为Table
//此处需要注意,注解中的每个方法表示该注解的一个可配置参数,default表示该配置参数的默认值
public String tableName() default "";
}
//2,Column注解,描述属性与列对应
package demo;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Column {
public String columnName() default "";
}
//3,注解应用在User类上
package demo;
//@Table对应自定义注解,tableName对应自定义注解中的方法,如果只用@Table则表示tableName采用默认的""作为值
@Table(tableName="User")
public class User {
@Column(columnName="user_id")
private String userId;
@Column(columnName="user_name")
private String userName;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

四,自定义注解信息的获取

之前分别使用xml和注解描述了User类和User表的对应关系,xml可以通过Java语言文件流等方式直接读取,而注解包含信息该如何读取呢。

既然注解是包含在Java语言中的信息,实际上可以通过反射来读取注解信息,对上述User类中注解读取的方法如下:

package demo;
import java.lang.reflect.Field;
@Table(tableName="User")
public class User {
@Column(columnName="user_id")
private String userId;
@Column(columnName="user_name")
private String userName;
public static void main(String[] args){
Class userClass=User.class;//获取User类信息
if(userClass.isAnnotationPresent(Table.class)){//判断userClass是否使用了Table注解
Table table=(Table)userClass.getAnnotation(Table.class);//获取注解信息
System.out.println(table.tableName());//输出Table注解的tableName参数
}
Field[] fields = userClass.getDeclaredFields();
for(Field field:fields){//遍历属性
if(field.isAnnotationPresent(Column.class)){//具备Column注解
Column column=(Column)field.getAnnotation(Column.class);//获取注解信息
System.out.println(column.columnName());
}
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

运行后输出结果:

User
user_id
user_name
  • 1
  • 2
  • 3

可见通过反射,可以轻易的获取注解的信息。

基于java注解实现自己的orm框架的更多相关文章

  1. Spring框架入门之基于Java注解配置bean

    Spring框架入门之基于Java注解配置bean 一.Spring bean配置常用的注解 常用的有四个注解 Controller: 用于控制器的注解 Service : 用于service的注解 ...

  2. 开源一个基于dotnet standard的轻量级的ORM框架-Light.Data

    还在dotnet framework 2.0的时代,当时还没有EF,而NHibernate之类的又太复杂,并且自己也有一些特殊需求,如查询结果直接入表.水平分表和新增数据默认值等,就试着折腾个轻量点O ...

  3. IDEA+Tomcat+Maven+SpringMVC基于Java注解配置web工程

    1.在IDEA中新建Maven工程,使用archetype. 2.添加Maven依赖 <dependencies> <dependency> <groupId>ju ...

  4. 基于Java+HttpClient+TestNG的接口自动化测试框架(八)------ 针对文件的处理

    在实际的接口测试中,有时需要根据情况进行文件的上传和下载.在文件数量比较小的时候,我们当然可以直接处理(比如若干个接口都用一个文件).但是,如果我们上传的文件需要使用不同文件夹里不同的文件,而且数量又 ...

  5. 基于Java+HttpClient+TestNG的接口自动化测试框架(四)-------参数存取处理

    在真正开始接口测试之前,我们需要对参数的处理进行梳理.这里所说的“参数”,既包含之前在xml中的配置(我们称之为全局参数),也包含在每一条用例中书写的param.全局参数为固定不变的,而根据接口相应获 ...

  6. 手写开源ORM框架介绍

    手写开源ORM框架介绍 简介 前段时间利用空闲时间,参照mybatis的基本思路手写了一个ORM框架.一直没有时间去补充相应的文档,现在正好抽时间去整理下.通过思路历程和代码注释,一方面重温下知识,另 ...

  7. 干掉前端!3分钟纯 Java 注解搭个管理系统

    大家好,我是小富~ 最近接触到个新项目,发现它用了一个比较有意思的框架,可以说实现了我刚入行时候的梦想,所以这里马不停蹄的和大家分享下. 在我刚开始工作接触的项目都还没做前后端分离,经常需要后端来维护 ...

  8. Spring Security基于Java配置

    Maven依赖 <dependencies> <!-- ... other dependency elements ... --> <dependency> < ...

  9. 优于 swagger 的 java markdown 文档自动生成框架-01-入门使用

    设计初衷 节约时间 Java 文档一直是一个大问题. 很多项目不写文档,即使写文档,对于开发人员来说也是非常痛苦的. 不写文档的缺点自不用多少,手动写文档的缺点也显而易见: 非常浪费时间,而且会出错. ...

随机推荐

  1. U32670 小凯的数字 数学

    这是洛谷一个比赛中的一道题,和去年NOIP D1T1挺像.我看了一眼之后想“这不是小学奥数吗?求一个数字和就好了呀”...然后,60,剩下T了,gg. 只好看正解,但是一脸懵逼???然后看了证明,c* ...

  2. B1076 [SCOI2008]奖励关 状压dp&&期望dp

    这个题的n<15,一看就是状压dp.但是状态不是很好想.f[][]存i关的状态j. 这个题另一个关键思想在于倒推,我一开始想的是正推,但是只能记忆化了. 题干: 题目描述 你正在玩你最喜欢的电子 ...

  3. Spring Boot 特性 —— SpringApplication

    转自:https://blog.csdn.net/cqdz_dj/article/details/52910317

  4. 3.朴素贝叶斯和KNN算法的推导和python实现

    前面一个博客我们用Scikit-Learn实现了中文文本分类的全过程,这篇博客,着重分析项目最核心的部分分类算法:朴素贝叶斯算法以及KNN算法的基本原理和简单python实现. 3.1 贝叶斯公式的推 ...

  5. 2015 多校赛 第二场 1006 (hdu 5305)

    Problem Description There are n people and m pairs of friends. For every pair of friends, they can c ...

  6. MTD 门店统计

    DROP TABLE #MTD ' ,@endDate date = cast(getdate() as date) CREATE TABLE #MTD(bydate date) DECLARE @c ...

  7. 【Oracle】DG中物理备库、快照备库的相互转换

    一.物理备库切换快照备库 1. 如果正在运行日志应用,先停止 ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; 2. 确保数据库为MOUN ...

  8. js 事件冒泡、事件捕获、stopPropagation、preventDefault

    转自:http://www.jb51.net/article/42492.htm (1)冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发. IE 5.5: ...

  9. dispatch_sync:As an optimization, this function invokes the block on the current thread when possible

    两件事情: 1.是否是一个线程: 2.queue task 的目标线程是否有未完成的task. 模型:一个线程处理当前的task还有通过gc d派发来的待执行task. 猜测: 如果目标thread上 ...

  10. js-构造数组

    js中,字符串的特性跟数组非常类似.数组是一种很重要的数据结构.在java中,数组声明的时候就要为其指定类型,数组中只能放同一种类型的数据.Js中的数组可以放不同的类型,但是是有序的,类似于java中 ...