14.POJO与Bean类的区别

文章介绍了POJO(PlainOldJavaObject)和JavaBean的概念、区别以及各自的特点。POJO是一个简单的Java对象,没有特定框架的限制,主要用于数据封装;而JavaBean遵循特定规范,如需有无参构造器、属性需通过getter/setter访问,并实现Serializable接口,常用于数据传输和存储。两者的主要区别在于定义方式、用途和依赖性。

目录

一、POJO与Bean类。

(1)POJO类:

(2)Bean类:

(3)POJO和Java Bean是两个不同的概念:

(4)二者的主要区别在于:


一、POJO与Bean类。

(1)POJO类:

POJO(Plain Old Java Object)是一个简单的Java对象,没有任何限制、约束或继承关系。通常用于表示一些简单的数据模型或对象。

一个标准的POJO需要满足以下条件:

  1. 公共构造函数:POJO需要有公共的无参构造函数。

  2. 私有属性:POJO中的所有属性都应该使用私有(private)修饰符,以确保数据的封装性和安全性。

  3. 公共方法:POJO应该提供一些公共的getter和setter方法,以便访问和修改属性的值。

  4. 无业务逻辑:POJO不应该包含复杂的业务逻辑或其他与数据模型无关的功能。

  5. 不依赖特定框架:POJO不应该直接或间接地依赖于任何特定的框架或库。

总之,一个标准的POJO应该是一个纯粹的Java对象,只包含数据和对数据的访问和修改方法,不包含任何业务逻辑和特定框架的依赖。这样可以使POJO更加灵活、可重用和易于维护。


POJO (Plain Old Java Object) 是指一个普通的 Java 对象,它没有遵循任何特定的框架规则,是非侵入性的。

POJO 需要满足以下条件:

  1. 遵循 Java Bean 的命名规则(getter 和 setter 方法);
  2. 没有实现任何框架相关的接口或类;
  3. 没有继承框架相关的类。

这些条件是为了使 POJO 简单和独立,提高了它的可读性和可维护性。

1. 创建POJO类
java
public class Person {
    private String name;
    private int age;
    
    public Person() {}
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
}
上述代码中,Person类是一个简单的POJO类,它包含了两个属性(name和age)
和对应的getter/setter方法。

(2)Bean类:

Java Bean需要满足如下条件:

  • 类必须是公共的,并且具有一个公共的无参数构造函数,因为Java反射机制在创建Bean时需要使用无参构造函数。
  • 所有属性都应该是私有的,并且通过公共的getter/setter方法来访问和修改属性的值。
  • 属性名必须遵循标准的命名规范,即以小写字母开头,后面的每个单词首字母大写,例如firstName、lastName。
  • 应该实现序列化接口(Serializable),这样Bean对象才能在网络中进行传输或者被存储到文件中。
  • 根据需要可以实现其他接口,比如多线程接口(Runnable)等。
2. 创建JavaBean类
java
public class Customer implements Serializable {
    private long id;
    private String firstName;
    private String lastName;
    private String email;

    public Customer() {}

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
上述代码中,Customer类是一个JavaBean类,它包含了四个属性(id、firstName、lastName
和email)和对应的getter/setter方法。此外,它还实现了Serializable接口,以支持序列化操作。

(3)POJO和Java Bean是两个不同的概念:

POJO和Java Bean(或简称为Bean)是两个不同的概念。虽然它们都是Java类,但是在定义和使用上存在一些差异。

POJO指的是普通的Java对象,它是一种轻量级的、独立于任何框架或技术的Java类。在定义上,POJO不需要继承或实现任何接口,并且不依赖于特定的技术或中间件。它通常包含一些属性和setter/getter方法,用于封装数据,是一种用于业务逻辑编写的简单Java对象。

Java Bean则是一种可重用的Java组件,是Java语言中的一个重要概念。它具有特殊的属性和方法规范,并且必须实现Serializable接口。Bean通常用于在模块之间传递数据和存储数据。在定义上,Bean通常包含一些私有属性(private)、公共的setter/getter方法和无参构造方法等。

在Java中,POJO和Java Bean是两个独立的概念,它们彼此之间没有继承或者实现关系,也没有包含或者被包含的关系。POJO是一个更加通用的概念,可以是任意的Java类,而Java Bean是一种符合特定规范的POJO,在Java程序中通常作为数据载体来使用。因此,Java Bean是POJO的一种特殊形式。

(4)二者的主要区别在于:

1、定义方式:POJO定义时没有规范要求,可以灵活自由地定义其属性和方法;Java Bean则要求遵循特定的属性和方法规范,需要实现特定的接口和构造方法等。

2、用途:POJO通常用于业务逻辑编写,用于封装数据并进行业务处理;Java Bean则通常用于数据传输和存储,例如在Web开发中,可以将从Servlet传递给JSP的数据封装成Bean对象进行传输。

3、依赖性:POJO不依赖于任何第三方类库或框架,是一种独立的Java对象;Java Bean则通常需要使用特定的框架或技术进行创建和使用,例如Spring框架。

总之,二者有明显的区别,而Java Bean可以看作是POJO的一种特殊实现,符合特定规范的POJO对象。

<think>好的,我现在需要解决用户的问题,即在使用MyBatis运行测试时,返回的是对象地址而不是数据库中的数据。首先,我要分析可能的原因。用户提到返回的是对象的哈希码,这通常是因为在打印对象时没有正确重写toString()方法,导致默认使用Object的toString(),显示名和哈希值。因此,第一个可能的原因是实体没有正确实现toString()方法。 接下来,我需要确认其他可能的原因。比如,MyBatis的配置是否正确,特别是结果映射部分。如果结果映射(resultMap或resultType)配置错误,可能导致数据无法正确注入到对象中,返回的对象属性为空,而用户可能只看到默认的toString()输出。例如,如果数据库字段名和实体属性名不一致,但没有使用正确的映射策略(如开启驼峰命名转换或显式使用resultMap),可能导致数据无法正确填充。 另外,日志配置也可能影响用户看到的信息。如果MyBatis的日志级别设置不当,用户可能无法看到实际的SQL执行情况,从而难以判断数据是否被正确查询到。例如,没有开启DEBUG级别日志,用户可能不知道查询是否返回了结果,或者结果是否正确映射。 还有一个可能性是数据库查询确实没有返回数据。例如,传入的查询参数(如id)在数据库中不存在,导致返回的实体对象为null,或者在集合的情况下返回空集合。此时,用户可能误认为对象地址的问题,而实际上是数据不存在。 此外,MyBatis的配置中有一个设置是callSettersOnNulls,默认情况下,如果查询结果的列值为null,MyBatis不会调用对应的setter方法。如果用户希望即使字段为null也生成对应的属性,可能需要调整这个配置,不过这种情况更多影响的是对象属性的存在性,而不是toString()的表现。 现在需要根据这些可能的原因,逐步指导用户进行排查。首先建议用户检查实体的toString()方法是否重写,确保输出所有关键属性。然后检查MyBatis的结果映射配置,确认字段名和属性名是否匹配,必要时使用resultMap或开启驼峰命名。接着,建议开启MyBatis的日志,查看实际执行的SQL和返回结果,确认是否有数据返回。最后,验证数据库中的数据是否存在,确保查询条件正确。 同时,根据用户提供的引用内容,引用[1]提到MyBatis在返回全NULL行时的行为,如果用户的数据中存在全NULL的情况,可能会影响返回对象的实例状态。不过结合用户的问题,更可能的是数据未正确映射或toString()未实现。引用[4]中的示例XML配置显示了一个基本的Mapper配置,用户需要确认自己的Mapper文件是否正确,特别是resultType是否正确指向实体,SQL语句是否正确。 总结解决方案步骤:检查toString()方法、验证结果映射、开启日志调试、确认数据库查询结果。每个步骤都需要用户逐一检查,以定位问题根源。</think>### 解决MyBatis返回对象地址而非数据库数据的问题 当MyBatis测试返回对象地址(如`Employee@5f184fc`)而非实际数据时,通常是因为未正确实现实体的`toString()`方法或MyBatis结果映射配置问题。以下是逐步排查和解决方法: --- #### 1. **检查实体的`toString()`方法** 默认情况下,Java对象调用`toString()`会返回名+哈希码。需在实体中重写`toString()`以显示属性值: ```java public class Employee { private Integer id; private String lastName; // 其他属性及getter/setter... @Override public String toString() { return "Employee{" + "id=" + id + ", lastName='" + lastName + '\'' + '}'; } } ``` **验证**:直接打印对象应显示属性值而非地址。 --- #### 2. **确认MyBatis结果映射配置** - **情况1:使用`resultType`但字段名属性名不匹配** 若数据库字段为`last_name`,而实体属性为`lastName`,需开启驼峰命名映射: ```yaml # application.yml mybatis: configuration: map-underscore-to-camel-case: true ``` 或显式定义`<resultMap>`: ```xml <resultMap id="employeeMap" type="demo.yangxu.springboot.bean.Employee"> <result column="last_name" property="lastName"/> <!-- 其他字段映射 --> </resultMap> <select id="getEmpById" resultMap="employeeMap"> SELECT * FROM employee WHERE id=#{id} </select> ``` - **情况2:查询结果为空** 检查数据库是否存在符合条件的数据,例如`id=#{id}`是否有效[^4]。 --- #### 3. **开启MyBatis日志调试** 在`application.yml`中启用SQL日志,确认查询是否执行成功并返回数据: ```yaml logging: level: demo.yangxu.springboot.mapper: DEBUG # Mapper接口所在包的日志级别设为DEBUG ``` 观察控制台输出,确认: - SQL语句是否正确拼接 - 返回结果是否包含预期字段 --- #### 4. **验证数据库连接事务** - **事务未提交** 若测试中未添加`@Transactional`或未手动提交事务,可能导致查询结果未持久化。确保插入操作已提交。 - **数据库连接配置错误** 检查数据源配置(如URL、用户名、密码),确保连接正确的数据库。 --- #### 5. **其他可能原因** - **延迟加载(Lazy Loading)** 如果实体包含关联对象(如`association`或`collection`),且未正确初始化,可能导致部分属性为空。可通过设置`aggressiveLazyLoading=false`或手动初始化关联对象解决。 - **MyBatis版本兼容性** 确保使用的MyBatis版本配置语法兼容(例如`callSettersOnNulls`在低版本中可能无效)。 --- ### 示例修正后的代码 **实体**: ```java public class Employee { private Integer id; private String lastName; // 其他属性、getter/setter及toString() } ``` **Mapper XML**: ```xml <select id="getEmpById" resultType="demo.yangxu.springboot.bean.Employee"> SELECT id, last_name AS lastName FROM employee WHERE id=#{id} </select> ``` **测试**: ```java @SpringBootTest public class EmployeeMapperTest { @Autowired private EmployeeMapper employeeMapper; @Test void testGetEmpById() { Employee emp = employeeMapper.getEmpById(1); System.out.println(emp); // 应输出属性值而非地址 } } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值