`
pesome
  • 浏览: 68007 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

自己实现ORM

阅读更多

这篇文章源自刚开发的一个小项目。项目中并未使用hibernate,但我还是要把它放在hibernate栏下。理由很简单,技术是死的,而人是活的,能熟练的使用一项技术不算什么,但能恰当的选择相应的技术,甚至自己想出办法来优雅的解决实际问题,就需要一定的积累了。而这种积累就来源自项目实践和对各种技术其实质的理解。我记得在某个论坛上某人(名字忘了)说过一句话:如果学习hibernate只是学会了怎么mapping,怎么写DAO,就只是学了皮毛,学hibernate就要从中了解到很多持久层的最佳实践。我深以为然!

项目很简单,页面也不多,但页面字段较多(100多个),相互间还有一定关联。而且存入数据库类型多样,有varchar, integerdate几种。我是很希望用hibernate来实现的,但考虑到项目时间较紧,而我对hibernate的了解还是停留在理论和学习阶段(有点落后啊!),采用不熟悉的技术项目风险较大,所以还是使用普通JDBC作为持久层方案。面对这么多字段,一个个去拼SQL语句,代码臃肿,而且容易出错,也难以维护。我得对这几种类型的字段,在插入、更新和读取时分别处理,写一个private方法,传入类型和字段名,读取相应的ResultSet,是不错的方法,至少是比较优雅的实现。

什么是优雅?动态设置,避免hardcode,就是优雅;层次清晰,层次间耦合最低,就是优雅;只写一处,处处引用,就是优雅;代码精炼,避免过度设计,就是优雅;接口明确,调用简单,就是优雅;调试容易,便于测试,就是优雅。。。。。。而优雅的设计和实现,在可扩展性、可维护性、开发效率、开发成本等方面都是最好的。

Hibernate就是优雅的设计,它通过配置文件,建立实体与数据库的映射,动态的生成SQL语句,避免了对属性字段的hardcode,这就是它最本质的思想。我不使用hibernate,但一样可以借鉴它的思想,我不需要对象容器、分页查询等等高级功能,因此可以简单的实现类似ORM的功能。

首先,定义一个配置类,将数据库字段和类型定义下来。按照常规的做法,从页面字段到对象属性到数据库都应该建立映射,这样需要生成相应的映射类。为简单起见,我不使用POJO,而是使用Map作为数据的载体,key就是数据库字段名,在页面端我也用数据库字段名作为域的名称。这样我直接通过名称建立映射,牺牲了扩展性和灵活性,但简化了操作,也无需映射类,只要一个映射Mapkey是数据库字段名,value是我自己定义的字段类型。以后动态生成SQLMap传输对象,以及从页面request动态生成Map都是基于这个配置。

接下来,就很简单了。先处理DAO的动态生成SQL代码,下面是生成insertSQL的方法,

private static String generateInsertScoreSQL(Map m, String studentId) {

              StringBuffer sb 
= new StringBuffer();

              StringBuffer sb2 
= new StringBuffer();

 

              sb.append(
"insert into STUDENT_SCORE (id,");

              sb2.append(
" values('");

              sb2.append(studentId);

              sb2.append(
"',");

              
for (Iterator iter = m.keySet().iterator(); iter.hasNext();) {

                     String name 
= (String) iter.next();

                     String value 
= (String) m.get(name);

                     sb.append(name);

                     sb.append(
",");

 

                     String type 
= (String) ScoreColumnMapping.scoreItemMap().get(name);

                     
if (ScoreColumnMapping.INT.equalsIgnoreCase(type)) {

                            
if (value == null || value.length() == 0{

                                   sb2.append(
"null,");

                            }
 else {

                                   sb2.append(Integer.parseInt(value));

                                   sb2.append(
",");

                            }


                     }
 else if (ScoreColumnMapping.STRING.equalsIgnoreCase(type)) {

                            sb2.append(
"'");

                            sb2.append(value);

                            sb2.append(
"',");

                     }


              }


              sb.replace(sb.length() 
- 1, sb.length(), ")");

              sb2.replace(sb2.length() 
- 1, sb2.length(), ")");

              log.info(sb.toString() 
+ sb2.toString());

              
return sb.toString() + sb2.toString();

       }

生成updateSQL的代码:

     

  private static String generateUpdateScoreSQL(Map m, String studentId) {

              StringBuffer sb 
= new StringBuffer();

 

              sb.append(
"update STUDENT_SCORE set ");

 

              
for (Iterator iter = m.keySet().iterator(); iter.hasNext();) {

                     String name 
= (String) iter.next();

                     String value 
= (String) m.get(name);

                     sb.append(name);

                     sb.append(
"=");

 

                     String type 
= (String) ScoreColumnMapping.scoreItemMap().get(name);

                     
if (ScoreColumnMapping.INT.equalsIgnoreCase(type)) {

                            
if (value == null || value.length() == 0{

                                   sb.append(
"null,");

                            }
 else {

                                   sb.append(Integer.parseInt(value));

                                   sb.append(
",");

                            }


                     }
 else if (ScoreColumnMapping.STRING.equalsIgnoreCase(type)) {

                            sb.append(
"'");

                            sb.append(value);

                            sb.append(
"',");

                     }


              }


              sb.replace(sb.length() 
- 1, sb.length(), "");

 

              sb.append(
" where id='");

              sb.append(studentId);

              sb.append(
"'");

 

              log.info(sb.toString());

              
return sb.toString();

       }

ResultSet中生成Map对象的代码:

private static void getScoreFromRs(ResultSet rs, Map m) throws SQLException {

              String name;

              String type;

              
for (Iterator iter = ScoreColumnMapping.scoreItemMap().keySet()

                            .iterator(); iter.hasNext();) 
{

                     name 
= (String) iter.next();

                     type 
= (String) ScoreColumnMapping.scoreItemMap().get(name);

                     
if (ScoreColumnMapping.INT.equalsIgnoreCase(type)) {

                            Object value 
= rs.getObject(name);

                            m.put(name, String.valueOf(value 
== null ? "" : value));

                     }
 else if (ScoreColumnMapping.STRING.equalsIgnoreCase(type)) {

                            String value 
= rs.getString(name);

                            m.put(name, value);

                     }


              }


 

       }

因为只有一个DAO采用这种方式,所以我用private方法,这可以通过重构,将其抽取到Util类中,供所有DAO使用。页面端也很简单,我做个Façade类,它获取request,并将其处理成一个Map,然后交给数据层处理(因为比较简单,省去了业务层),代码如下:

<!----><o:p>

Map m = new HashMap();

        
for (Iterator iter = ScoreColumnMapping.scoreItemMap().keySet()

                .iterator(); iter.hasNext();) 
{

            String name 
= (String) iter.next();

            String value 
= request.getParameter(name);

                     ……

m.put(name, value);

……

 </o:p>

所有方法中未出现一个字段名称,全部是从配置类中动态生成。这样带来了很多好处:

u       扩展容易,如果需增加字段,无需更改核心代码,只要修改配置文件和数据库表定义,然后页面上加加域

分享到:
评论

相关推荐

    自己实现orm框架

    ### 自己实现ORM框架 #### 一、概述 在软件开发过程中,ORM(Object-Relational Mapping,对象关系映射)是一种重要的技术手段,用于在面向对象编程语言中表示数据库记录,使程序开发者能够像使用对象一样操作...

    手写orm

    【描述】:虽然没有具体的描述,但可以推测这篇博客可能探讨了作者自己实现ORM框架的过程,可能涉及了以下内容:理解ORM的基本原理,设计数据模型与数据库表之间的映射,如何处理对象的持久化,以及事务管理等核心...

    python实现orm

    标题“python实现orm”指的是使用Python语言来创建自己的ORM框架,或者是学习和理解ORM在Python中的应用。ORM框架如SQLAlchemy和Peewee等,为Python开发者提供了方便的数据访问接口,使得他们能够在不直接操作SQL的...

    [反射机制]简单实现ORM

    在本案例中,"简单实现ORM"是指通过反射机制来实现对象关系映射(Object-Relational Mapping),这是一种将数据库中的数据与Java对象之间建立映射关系的技术,使得开发者可以更方便地操作数据库。 ORM的主要目的是...

    自己写的ORM

    ORM,全称Object-Relational Mapping,即对象关系映射,是一种编程技术,用于将关系数据库的数据模型映射到面向对象的编程语言中。...同时,通过分享和评估自定义ORM,可以从社区获取反馈,进一步提升自己的编程能力。

    自定义Orm框架的实现

    本项目旨在实现一个基于JDK5.0注解的小型ORM框架,模拟Hibernate的部分功能。 首先,我们要理解ORM的基本原理。ORM的核心思想是将数据库中的表映射为Java对象,将表中的记录映射为对象的实例,这样就可以通过操作...

    .net 简单实现orm实例

    本实例将通过反射机制简单实现一个ORM功能,帮助理解其工作原理。 首先,我们要了解反射在.NET中的作用。反射允许程序在运行时检查自身的信息,如类型、属性、方法等,并且能够动态地创建和执行代码。在ORM中,反射...

    实现自己的ORM系列源码 - MiniORM

    这是我Blog(http://blog.csdn.net/RonoTian)中的系列文章《实现自己的ORM》系列的配套资源,如果你需要详细的了解MiniORM的相关实现,那请自己查看我Blog中相关文章。

    python利用元类和描述器实现ORM模型(csdn)————程序.pdf

    在 Python 中实现 ORM 模型,通常涉及两个关键概念:元类(Metaclass)和描述器(Descriptor)。下面我们将详细探讨这两个概念以及它们在 ORM 实现中的应用。 1. 元类(Metaclass): 元类是创建类的类,即元类是...

    基于Java动态代理和反射机制实现ORM

    在Java中,基于动态代理和反射机制实现ORM可以提高代码的可维护性和灵活性。本篇文章将深入探讨如何在Java环境下,结合MySQL数据库,利用动态代理和反射技术来实现简单的ORM框架。 首先,我们需要了解动态代理和...

    利用java反射、注解及泛型模拟ORM实现

    在Java编程中,反射、注解(Annotation)和泛型是三个非常重要的特性,它们各自...在实际项目中,成熟的ORM框架如Hibernate、MyBatis等已经实现了这些功能,但理解其工作原理对于优化和定制自己的ORM解决方案至关重要。

    C#实现自己的ORM系列源码(MiniORM).rar

    在.NET框架中,C#语言提供了丰富的库来实现ORM,如Entity Framework、NHibernate等。然而,理解ORM的工作原理并亲手实现一个简单的ORM框架,对于提升开发者的数据库操作技能和对数据库设计的理解非常有帮助。 本...

    Hibernate orm 实现原理

    Hibernate orm 实现原理 主要讲解了关于hibernate 的一些知识

    Hibernate框架ORM的实现原理

    为了实现ORM的功能,需要能够正确地解析上述三种文件。 1. **XML文件解析**: - XML文件解析可以使用两种主流的技术:SAX和DOM。 - SAX(Simple API for XML)是一种基于事件驱动的解析方式,适用于大型文档的...

    NHibernate实现ORM

    ### NHibernate实现ORM详解 NHibernate作为一款强大的对象关系映射(ORM)框架,为.NET开发者提供了一种优雅的方式,将面向对象的编程模型与关系型数据库的数据存储模型相桥接。通过NHibernate,开发人员可以更加专注...

    巧用工具封装属于自己的ORM框架【XutilsDbUtil】分装

    博客文章“http://blog.csdn.net/god_chance/article/details/47364293”应该会深入讲解如何利用XUtils框架来封装自己的ORM工具,包括具体的代码示例和实践过程,建议详细阅读以获取更全面的理解。 总的来说,封装...

    ORM框架ORM框架ORM框架ORM框架

    "自己写的ORM很好用"这个标签可能指的是开发者或者团队自行开发了一个ORM框架,并且在实际项目中表现良好。这样的ORM框架可以根据具体需求进行定制,更好地适应项目的特性和业务逻辑。自定义ORM的优势在于可以更紧密...

    一个自己写的ORM原理的映射实例

    通过查看和分析这些代码,我们可以学习到如何设计和实现ORM的各个组件,以及它们如何协同工作以完成数据库操作。此外,实例还可能涉及到事务管理、性能优化、异常处理等实际开发中的重要问题。 总的来说,理解并...

    基于java 简易ORM 框架实现(一)

    在本篇讨论中,我们将深入探讨“基于Java的简易ORM框架实现”。ORM,全称Object-Relational Mapping,是将数据库中的数据与程序中的对象进行映射的技术,它简化了数据库操作,使得开发者可以像操作对象一样操作...

    轻松实现Grove.ORM

    "Grove.ORM"是一个基于C#实现的ORM框架,它简化了数据库访问,通过提供一种直观的面向对象的方式来操作数据库。 Grove.ORM的核心思想是将数据库表与C#类关联,数据库记录与类实例对应,表字段与类属性对应。这样,...

Global site tag (gtag.js) - Google Analytics