`
CodingMouse
  • 浏览: 7398 次
  • 性别: Icon_minigender_1
  • 来自: 内江
文章分类
社区版块
存档分类
最新评论

自己实现了一个较实用的Pojo(实体)基类

阅读更多
自己实现了一个较实用的Pojo(实体)基类

也许你会觉得就单单重写了Object根类的equals、hashCode、toString这三个方法有什么意义?

实质上,如果你封装过泛型集合基类,并在泛型集合基类中玩过根据自定义属性排序的话,那么你会发现实现这样的一个Pojo基类很有必要!


package com.china.codingmouse.cmsdk4j.pojo;   
  
import java.io.Serializable;   
import java.lang.reflect.InvocationTargetException;   
import java.lang.reflect.Method;   
import java.util.List;   
import java.util.Vector;   
  
/**  
 * BasePojo Pojo(实体)基类  
 * @author CodingMouse  
 * @version 1.0.0.1 2009-4-10  
 */  
public class BasePojo implements Serializable {   
  
    private static final long serialVersionUID = -5520682886492533483L;  // 版本序列号   
       
    /**  
     * 指示其他某个对象是否与此对象“相等”  
     */  
    @Override  
    public boolean equals(Object obj) {   
        // 自身比较   
        if (obj == this) {   
            return true;   
        }   
        // 类型相同   
        if (obj.getClass() == this.getClass()) {   
            // 当前类反射方法组   
            Method[] thisMethodGroup = this.getClass().getMethods();   
               
            try {   
                // 遍历反射方法组并提取当前类属性的getter方法   
                for (Method method : thisMethodGroup) {   
                    // 过滤与当前类属性无关的get方法   
                    if (method.getName().startsWith("get")   
                        && !method.getName().equals("getClass")) {   
                        // 将当前类属性的getter方法与比较类属性的getter方法值作比较   
                        Method currentMethod = obj.getClass().getMethod(method.getName());   
                        // 执行方法以获取返回值比较(关键点:注意参数不相同)   
                        Object objReturnValue = currentMethod.invoke(obj);   
                        Object thisReturnValue = method.invoke(this);   
                        // 空值报异   
                        /*if (objReturnValue == null) {   
                            System.err.println("异常信息:类" + obj.getClass().getName()    
                                + "中的" + currentMethod.getName() + "方法为null值!无法进行对象比较!");   
                        }   
                        if (thisReturnValue == null) {   
                            System.err.println("异常信息:类" + this.getClass().getName()    
                                + "中的" + method.getName() + "方法为null值!无法进行对象比较!");   
                        }*/   
                        // 返回值不相等则返回逻辑假   
                        if (!objReturnValue.equals(thisReturnValue)) {   
                            return false;   
                        }   
                    }   
                }                      
            } catch (SecurityException ex) {   
                System.err.println("异常信息:参数错误,安全管理器检测到安全侵犯!\r\n" + ex.getMessage());   
            } catch (NoSuchMethodException ex) {   
                System.err.println("异常信息:参数错误,无法找到某一特定的方法!\r\n" + ex.getMessage());   
            } catch (IllegalArgumentException ex) {   
                System.err.println("异常信息:参数错误,向方法传递了一个不合法或不正确的参数!\r\n" + ex.getMessage());   
            } catch (IllegalAccessException ex) {   
                System.err.println("异常信息:参数错误,对象定义无法访问,无法反射性地创建一个实例!\r\n" + ex.getMessage());   
            } catch (InvocationTargetException ex) {   
                System.err.println("异常信息:参数错误,由调用方法或构造方法所抛出异常的经过检查的异常!\r\n" + ex.getMessage());   
            }   
        }   
           
        // 通过不相等比较则返回逻辑真   
        return true;   
           
    }   
  
    /**  
     * 返回该对象的哈希码值  
     */  
    @Override  
    public int hashCode() {   
  
        // 生成简单的位运算hash散列码   
        String key = this.toString();   
        int prime = key.hashCode();   
        int hash = prime;   
        for (int i = 0; i < key.length(); i++) {   
             hash ^= (hash << 23 >> 17) ^ key.charAt(i) * 13131;   
        }   
        // 返回结果   
        return (hash % prime) * 33;   
           
    }   
  
    /**  
     * 返回该对象的字符串表示(类似数组的toString方法输出结果)  
     */  
    @Override  
    public String toString() {   
           
        // 当前类反射方法组   
        Method[] methodGroup = this.getClass().getMethods();   
        // 保存内容   
        StringBuffer content = new StringBuffer("[");   
        // 保存属性的getter方法组   
        List<Method> getMethodGroup = new Vector<Method>();   
           
        try {   
            // 遍历反射方法组并提取属性的getter方法   
            for (Method method : methodGroup) {   
                // 过滤与属性无关的get方法   
                if (method.getName().startsWith("get")   
                    && !method.getName().equals("getClass")) {   
                    // 保存属性的getter方法   
                    getMethodGroup.add(method);   
                }   
            }   
            // 处理仅包含属性的getter方法   
            for (int i = 0; i < getMethodGroup.size(); i++) {   
                // 执行get方法并拼接获取到的返回值(如果底层方法返回类型为 void,则该调用返回 null)   
                content.append(getMethodGroup.get(i).invoke(this)    
                    + ((i < getMethodGroup.size() - 1) ? ",\u0020" : "]"));   
            }   
        } catch (IllegalAccessException ex) {   
            System.err.println("异常信息:参数错误,对象定义无法访问,无法反射性地创建一个实例!\r\n" + ex.getMessage());   
        } catch (IllegalArgumentException ex) {   
            System.err.println("异常信息:参数错误,向方法传递了一个不合法或不正确的参数!\r\n" + ex.getMessage());   
        } catch (InvocationTargetException ex) {   
            System.err.println("异常信息:参数错误,由调用方法或构造方法所抛出异常的经过检查的异常!\r\n" + ex.getMessage());   
        }   
           
        // 返回结果   
        return content.toString();   
           
    }   
       
}  




以下是此基类的一段测试代码:


package com.china.codingmouse.cmsdk4j.example.pojo;   
  
import java.io.Serializable;   
import java.sql.Timestamp;   
  
import com.china.codingmouse.cmsdk4j.pojo.BasePojo;   
  
/**  
 * UserPojo 用户信息实体类  
 * @author CodingMouse  
 * @version 1.0.0.1 2009-4-10  
 */  
public class UserPojo extends BasePojo implements Serializable {   
  
    private static final long serialVersionUID = -2214074259397104603L;  // 版本序列号   
    private int id;             // 用户ID   
    private String name;        // 用户姓名   
    private boolean sex;        // 用户性别   
    private int age;            // 用户年龄   
    private String address;     // 用户住址   
    private Timestamp regTime;  // 用户注册时间   
       
    /**  
     * 默认构造器  
     */  
    public UserPojo() {   
        super();   
    }   
    /**  
     * 参数化构造器  
     * @param id       用户ID  
     * @param name     用户姓名  
     * @param sex      用户性别  
     * @param age      用户年龄  
     * @param address  用户住址  
     * @param regTime  用户注册时间  
     */  
    public UserPojo(int id, String name, boolean sex, int age, String address, Timestamp regTime) {   
        super();   
        this.setId(id);   
        this.setName(name);   
        this.setSex(sex);   
        this.setAge(age);   
        this.setAddress(address);   
        this.setRegTime(regTime);   
    }   
    /**  
     * 用户ID取值方法  
     * @return 用户ID  
     */  
    public int getId() {   
        return id;   
    }   
    /**  
     * 用户ID赋值方法  
     * @param id 用户ID  
     */  
    public void setId(int id) {   
        this.id = id;   
    }   
    /**  
     * 用户姓名取值方法  
     * @return 用户姓名  
     */  
    public String getName() {   
        return name;   
    }   
    /**  
     * 用户姓名赋值方法  
     * @param name 用户姓名  
     */  
    public void setName(String name) {   
        this.name = name;   
    }   
    /**  
     * 用户性别取值方法  
     * @return 用户性别  
     */  
    public boolean getSex() {   
        return sex;   
    }   
    /**  
     * 用户性别赋值方法  
     * @param sex 用户性别  
     */  
    public void setSex(boolean sex) {   
        this.sex = sex;   
    }   
    /**  
     * 用户年龄取值方法  
     * @return 用户年龄  
     */  
    public int getAge() {   
        return age;   
    }   
    /**  
     * 用户年龄赋值方法  
     * @param age 用户年龄  
     */  
    public void setAge(int age) {   
        this.age = age;   
    }   
    /**  
     * 用户住址取值方法  
     * @return 用户住址  
     */  
    public String getAddress() {   
        return address;   
    }   
    /**  
     * 用户住址赋值方法  
     * @param address 用户住址  
     */  
    public void setAddress(String address) {   
        this.address = address;   
    }   
    /**  
     * 用户注册时间取值方法  
     * @return 用户注册时间  
     */  
    public Timestamp getRegTime() {   
        return regTime;   
    }   
    /**  
     * 用户注册时间赋值方法  
     * @param regTime 用户注册时间  
     */  
    public void setRegTime(Timestamp regTime) {   
        this.regTime = regTime;   
    }   
       
}  





package com.china.codingmouse.cmsdk4j.example.pojo.test;   
  
import java.sql.Timestamp;   
  
import com.china.codingmouse.cmsdk4j.example.pojo.UserPojo;   
  
/**  
 * 用户信息实体类Equals与HashCode方法测试类  
 * @author CodingMouse  
 * @version 1.0.0.1 2009-4-10  
 */  
public class UserPojoEqualsAndHashCodeTest {   
  
    /**  
     * 测试类主方法  
     * @param args  
     */  
    public static void main(String[] args) {   
  
        UserPojo up1 = new UserPojo(3, "邓超", true, 25, "四川隆昌", new Timestamp(System.currentTimeMillis()));   
        UserPojo up2 = new UserPojo(3, "邓超", true, 25, "四川隆昌", new Timestamp(System.currentTimeMillis()));   
        System.out.println("User1的内容:" + up1);   
        System.out.println("User2的内容:" + up2);   
        System.err.println("User1的散列码:" + up1.hashCode());   
        System.err.println("User2的散列码:" +up2.hashCode());   
        System.out.println("测试User1与User2地址(==)相等:" + (up1 == up2));   
        System.out.println("测试User1与User2内容(equals)相等:" + up1.equals(up2));   
        UserPojo up3 = new UserPojo(6, "CodingMouse", false, 22, "中华人民共和国四川成都", new Timestamp(System.currentTimeMillis()));   
        UserPojo up4 = new UserPojo(13, "Michael Jackson", false, 53, "美利坚合众国纽约市唐人街", new Timestamp(System.currentTimeMillis()));   
        System.out.println("User3的内容:" + up3);   
        System.out.println("User4的内容:" + up4);   
        System.err.println("User3的散列码:" +up3.hashCode());   
        System.err.println("User4的散列码:" +up4.hashCode());   
        System.out.println("测试User3与User4地址(==)相等:" + (up3 == up4));   
        System.out.println("测试User3与User4内容(equals)相等:" + up3.equals(up4));   
           
    }   
  
}




跑出来的结果:

---------------------------------------------------------------------

User1的内容:[true, 25, 2009-04-10 18:39:54.557, 四川隆昌, 邓超, 3]
User2的内容:[true, 25, 2009-04-10 18:39:54.557, 四川隆昌, 邓超, 3]
User1的散列码:524379269
User2的散列码:524379269

测试User1与User2地址(==)相等:false
测试User1与User2内容(equals)相等:true
User3的内容:[false, 22, 2009-04-10 18:39:54.563, 中华人民共和国四川成都, CodingMouse, 6]
User4的内容:[false, 53, 2009-04-10 18:39:54.563, 美利坚合众国纽约市唐人街, Michael Jackson, 13]
User3的散列码:-715569909
User4的散列码:956891732

测试User3与User4地址(==)相等:false
测试User3与User4内容(equals)相等:false

---------------------------------------------------------------------


重写equals与hashCode方法是从所周知的事情,所以不多作说明。

至于为什么我要重写toString方法,有两点理由:

1、作为hashCode生成算法的一部分,与其内容直接相关,有更好的散列效果。

2、便于获取其子类更详细的内容描述,便于调试,而不是得到诸如“java.lang.Object@757aef”这样让人难以理解的文字内容。


正在写一个泛型BasePojoCollection(实体集合基类),想达到在基类中实现反射性地对子类自定义属性排序的功能。有了这样一个BasePojo为基础,就可以较容易地实现了!当然,还需要为这个BasePojo实现Comparable接口。


原来没有看到过别人做这样的尝试,如果你有更好的思路,还烦请指正为感!
分享到:
评论
23 楼 CodingMouse 2010-02-06  
nisen 写道
先评论一下你的方法:使用了反射,但是没有考虑到互相引用的情况.比如A指向B,B指向A.等实际存在的对象关系.用这个栈一定会溢出,因为你没有考虑这个因素.

这个实现有如下方法
  • Apache Commons Lang ,这个2.0版也有lz同样的问题,因为都是使用的反射
  • XStream 用这个实现toString方法,可以生成XML,其他的两个函数可以根据xxx自己写.
  • 使用Eclipse的辅助工具,右键->source中找找就可以了.


当然实现这个有两种可选,
  • 就是楼主的继承方式.优点是非常方便.缺点:所有的类必须从这个类继承,感觉太依赖这个类了.以前我们的项目中就用这个.
  • 每个类单写,方便.当然需要封装一下,这样每个类都是同样的三行.我有一个项目中就用的这个.在使用继承以前,后来习惯使用继承了.当然不用每次copy,使用eclipse的Java模板.


commons lang的书在这
http://oreilly.com.cn/book.php?bn=7-302-13964-4



感谢指点!
22 楼 nisen 2010-02-06  
先评论一下你的方法:使用了反射,但是没有考虑到互相引用的情况.比如A指向B,B指向A.等实际存在的对象关系.用这个栈一定会溢出,因为你没有考虑这个因素.

这个实现有如下方法
  • Apache Commons Lang ,这个2.0版也有lz同样的问题,因为都是使用的反射
  • XStream 用这个实现toString方法,可以生成XML,其他的两个函数可以根据xxx自己写.
  • 使用Eclipse的辅助工具,右键->source中找找就可以了.


当然实现这个有两种可选,
  • 就是楼主的继承方式.优点是非常方便.缺点:所有的类必须从这个类继承,感觉太依赖这个类了.以前我们的项目中就用这个.
  • 每个类单写,方便.当然需要封装一下,这样每个类都是同样的三行.我有一个项目中就用的这个.在使用继承以前,后来习惯使用继承了.当然不用每次copy,使用eclipse的Java模板.


commons lang的书在这
http://oreilly.com.cn/book.php?bn=7-302-13964-4
21 楼 CodingMouse 2009-05-05  
非常感谢大家的回复,特别是 VonNeumann 、presses 、treblesoftware ,让我看到了这段自己揣摩出来的代码有许多不足的地方和鼓励。

像我这样的初学者发帖到网上肯定是很容易被拍的,只要大家能帮忙指正问题所在,被拍死也值得。
20 楼 wendong007 2009-04-28  
<div class="quote_title">treblesoftware 写道</div>
<div class="quote_div">JE上许多人太不厚道了。<br><br>看投新手帖的那么多。LZ至少做了些什么,而有些人只是点了点鼠标。<br>而有些人更可恶,<span style="color: #ff0000;">先COPY,之后在点下鼠标</span>---&gt; 新手帖。<br><br><br>别拍我。我知道这年头说实话容易被拍!<img src="/images/smiles/icon_sad.gif" alt="">
</div>
<p> </p>
<p>COPY什么?</p>
19 楼 treblesoftware 2009-04-28  
JE上许多人太不厚道了。

看投新手帖的那么多。LZ至少做了些什么,而有些人只是点了点鼠标。
而有些人更可恶,先COPY,之后在点下鼠标---> 新手帖。


别拍我。我知道这年头说实话容易被拍!
18 楼 presses 2009-04-28  
反射方面不说,就继承的用法上感觉就不对。一般来说是在is a的关系上才继承。而想要得到某功能而去继承,这样的做法不好。可以考虑用工具类的方式提供你的功能。例如你的功能,可以这样实现:
/**
 * 
 */
package com.humanmonth.flow;

import java.util.List;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 调试的打印工具类
 * 
 * @author presses
 * 
 */
public class PrintUtil {
	private static Log log = LogFactory.getLog(PrintUtil.class);

	/**
	 * 打印List集合,集合中装的是原型或它的包装类
	 */
	@SuppressWarnings("unchecked")
	public static void printRawList(List rawList, String... descripts) {
		if (descripts != null && descripts.length > 0) {
			for (String str : descripts) {
				log.info(str);
			}
		}
		if (null == rawList) {
			log.info("集合中没有元素");
			return;
		}
		for (Object obj : rawList) {
			PrintUtil.printObject(obj);
		}
	}

	@SuppressWarnings("unchecked")
	public static void printRawListWithNoReflection(List rawList, String... descripts) {
		if (descripts != null && descripts.length > 0) {
			for (String str : descripts) {
				log.info(str);
			}
		}
		if (null == rawList) {
			log.info("集合中没有元素");
			return;
		}
		for (Object obj : rawList) {
			log.info(obj);
		}
	}

	/**
	 * 反射打印对像
	 */
	public static void printObject(Object obj, String... descripts) {
		if (descripts.length == 1) {
			log.info(descripts[0]);
		}
		log.info(ToStringBuilder.reflectionToString(obj));
	}
}


补充一句,上面这工具类的log的用法不对。
17 楼 云中苍月 2009-04-28  
这种代码意义确实不大,不过作为初学者练手的作品要求也不能太苛刻了。
16 楼 nbkangta 2009-04-27  
反射机制是把双刃剑,不好滥用,我宁可我的实体类是POJO
15 楼 mikab 2009-04-27  
来个循环引用的对象,ls的方法就死翘翘了。

^_^
14 楼 VonNeumann 2009-04-27  
碧海山城 写道
对于投隐藏贴的,不记名,怎么说也得给个理由吧,javaeye应该给这个功能

好吧 我投了隐藏贴
我来说说 刚看了几行就忍不住点了

注意重写的equals方法

1 对obj判定null了吗……
在equals方法里抛NullpointerException是不好的

2 说说其它几个方面吧
说到重写equals方法的几条规则
自反性 对称性 传递性 幂等性
都能满足吗……(真没细看 看到第一个方法没几行就冲动的点了)

当然 lz的探索精神还是很好的 值得鼓励 比我强多了 潜水多年从没发过这样自己思考的帖子
13 楼 Xorcerer 2009-04-27  
正好给新手反射的示例代码。
不过我一般单独重载ToString(),毕竟这个跟需求有关。
12 楼 gembler 2009-04-25  
例如:
用List的contains的时候
用Map的containsKey/containsValue的时候
SortedMap...
SortedSet...
.
.
.
等等

在一个集合里动一下就基本上要用到equals或hashCode了,你自己应该要好好对比对比衡量衡量
11 楼 laitaogood 2009-04-25  
这样的东西感觉没有什么价值,恕我草率!
因为很多东西原本就是这样用就可以了,非得画蛇添足啊,我还是看不出有什么优势啊,呵呵
我就是看看而已,当然还是支持楼主的实践精神
10 楼 neora 2009-04-25  
mccxj 写道
不支持这样用,这么用反射没什么好处

我也投个隐藏



投人家隐藏贴应该给个有说服力的理由先,光是一句“没什么好处”,实在是草率了。
9 楼 mccxj 2009-04-25  
不支持这样用,这么用反射没什么好处

我也投个隐藏
8 楼 43385607 2009-04-25  
还是不错
7 楼 luckaway 2009-04-24  
有必要搞的这么复杂吗!

反射是要降低性能的!
慎用!
6 楼 碧海山城 2009-04-13  
对于投隐藏贴的,不记名,怎么说也得给个理由吧,javaeye应该给这个功能
5 楼 CodingMouse 2009-04-13  
herowzz 写道
请问楼主的与apache commons lang比较有何优势?

谢谢各位的建议!

我只是一个初学者,也算是一个学生吧,只是凭空想象用来实现一些封装,以便于给伙伴使用,简化他们的代码编写。也许,我写的代码不地道。

对于apache commons lang,我没有去看过它的相关代码。也许各位的提醒得让我去注意一下了。



4 楼 herowzz 2009-04-12  
请问楼主的与apache commons lang比较有何优势?

相关推荐

    JDBCTemplate+JavaPOJO实现通用DAO

    3. **编写通用DAO接口**:定义一个基类,如`BaseDAO&lt;T&gt;`,T代表POJO类型,接口中包含增删改查的基本方法。 4. **实现通用DAO接口**:实现`BaseDAO&lt;T&gt;`接口,使用JDBCTemplate的方法来执行SQL。例如,实现插入操作:...

    JavaWeb网上商城的设计与实现文档.docx

    UpLoad类是一个具体的Servlet实现,它继承自HttpServlet基类,并重写了doPost方法来处理POST请求。这段代码展示了如何使用Apache Commons FileUpload库来处理文件上传的功能。 ### 总结 通过对以上内容的分析,我们...

    HIBERNATE - 符合Java习惯的关系数据库持久化

    1. **POJO基类**:实体类应是普通的Java对象(POJO),不依赖于任何框架或容器。 2. **访问器方法**:实体类应提供getter和setter方法,以便Hibernate通过反射机制读取和更新属性值。 3. **默认构造器**:实体类需...

    Spring Security应用实例

    在本篇"Spring Security...总结来说,构建Spring Security用户登录模块涉及数据库设计、Pojo实体、安全配置和接口实现等多个方面。通过这些步骤,我们可以创建一个安全、可靠的登录系统,为用户提供认证和授权服务。

    EJB3持久化

    POJO是一个非正式术语,用于描述那些没有特殊框架或库依赖的简单Java类,它们仅包含一些私有属性、getter和setter方法。在EJB3.0中,这些POJO类被用作持久化实体,通过简单的注解(Annotations)来定义实体之间的...

    EJB3.0的学习文档

    - **无容器依赖的实体Bean**:EJB3.0的实体Bean可以作为POJO(Plain Old Java Object)存在,不再强制需要继承特定的基类或实现接口。 - **自动事务管理**:EJB3.0 提供了更强大的事务管理,开发者无需手动处理事务...

    基于java的ejbCreate函数用于初始化一个EJB实例.zip

    `ejbCreate`方法在EJB容器创建一个新的实体Bean实例时被调用,通常在这个方法中进行Bean对象的初始化工作,如设置默认值、打开数据库连接等。值得注意的是,`ejbCreate`不是Java语言内置的方法,而是EJB规范定义的...

    ibatis与Spring整合例子

    接着,我们创建POJO类,例如这里的`Student`类,它代表了数据库中的一个实体。这个类包含了一些基本属性,如`id`、`firstname`和`lastname`,并提供了对应的getter和setter方法。这使得Spring和iBATIS能够通过...

    JAVA代码生成器源码-基于SSM架构

    【JAVA代码生成器源码-基于SSM架构】是一个实用工具,它可以帮助开发者快速构建Java Web应用程序的基础结构。SSM架构是由Spring、Spring MVC和MyBatis三个框架组成的,是目前广泛使用的Java后端开发技术栈。这个工具...

    深入浅出Hibernate

    例如,可以定义一个基类 `Product` 来表示所有类型的货物,然后根据具体的货物类型(如书籍、电子产品等)创建不同的子类。每个子类继承自 `Product` 类,并根据需要添加额外的属性。 这种方式不仅使得代码结构更加...

    hibernate_reference-annotation

    - **@Entity**:标记一个 POJO 类为持久化实体类。 - **@Table**:指定实体类对应的数据库表名。 - **@Id**:标识主键属性。 - **@Column**:指定列名及其他属性,如是否可空等。 ##### 3.2 属性映射 - **简单属性...

    struts2_demo

    Struts2是一个强大的Java web开发框架,用于构建可维护、可扩展且结构良好的应用程序。它在MVC(Model-View-Controller)设计模式的基础上提供了一种简化开发的方式,使得开发者可以更加专注于业务逻辑,而不是繁琐...

    CRUD代码编写.pdf

    例如,对于User类,只需要在类上添加@Entity注解,表示这是一个实体类;在ID字段上添加@Id和@GeneratedValue注解,表明它是主键,并指定了自动增长策略。 - **一对多关系配置**:如果涉及更复杂的关系,如一对多或...

    机试考试步骤完整版.docx

    在进行Web开发的机试考试时,我们需要遵循一系列的步骤来构建一个完整的项目。以下是一些关键知识点: 1. **环境搭建** - **数据库创建**:首先,你需要根据试卷指示创建数据库。数据库的名称、表名、字段名以及表...

    JBoss4.2.3GA + EJB3.0 + JAAS

    2. POJO(Plain Old Java Object):EJB 3.0允许开发者使用普通的Java对象作为业务组件,无需继承特定的基类或实现接口,增强了代码的可读性和可维护性。 3. JPA(Java Persistence API):这是EJB 3.0中的一个重要...

    Java Persistence API

    - **注解示例**:通过使用`@Entity`注解来声明一个类为实体类,使用`@Id`注解指定主键字段,使用`@Column`等注解来定义字段与数据库列的映射关系。 ```java @Entity @Table(name = "customer") public class ...

    ejb3.0 实例教程

    - **POJO支持**:EJB 3.0 支持Plain Old Java Objects (POJOs),这意味着EJB组件不再需要继承特定的基类或实现接口,降低了学习曲线。 - **实体管理**:实体Bean(Entity Beans)的API被简化,使用JPA(Java ...

    Hibernate参考文档

    Hibernate支持使用普通的Java对象(POJO)作为持久化对象,无需继承特定的基类或实现接口。对象的状态(瞬时、持久、脱管)由Hibernate自动管理。 5. **会话与事务** Session是Hibernate的主要工作接口,用于执行...

    Struts_Hibernate和Spring的轻型J2EE架构的研究.pdf

    例如,为基类`User`创建一个表,并在表中添加一个字段来区分不同的子类类型,如`type`字段。然后,在Hibernate的映射文件中,可以通过`&lt;subclass&gt;`元素指定具体的子类类型及其对应的字段值。 通过以上步骤,我们...

    E J B 3 . 0 文档

    在EJB 3.0中,实体bean(Entity Bean)采用了POJO(Plain Old Java Object)模式,不再需要实现特定接口或继承特定基类。通过`@Entity`注解,普通Java类可以被声明为数据库映射的对象,JPA(Java Persistence API)...

Global site tag (gtag.js) - Google Analytics