当前位置: 首页 > news >正文

可别再用BeanUtils了(性能拉胯),试试这款转换神器

老铁们是不是经常为写一些实体转换的原始代码感到头疼,尤其是实体字段特别多的时候。有的人会说,我直接使用get/set方法。没错,get/set方法的确可以解决,而且也是性能较高的处理方法,但是大家有没有想过,要是转换的实体字段比较多,那么get/set方法的代码量是非常恐怖的;有人会说,用自带的BeanUtils工具类,但在属性拷贝的过程中,会遇到类型转换异常,或是影响性能等等问题。所以,我把自己项目中使用的这款转换神器分享出来。BeanUtils属性复制

之前对各种属性映射工具的性能进行了简单的对比,结果如下:

先贴下官网地址吧:https://mapstruct.org/

一、pom 配置

    <!-- 属性设置 --><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><mybatisPlus.version>3.5.3.1</mybatisPlus.version><lombok.version>1.18.26</lombok.version><mysql.version>8.0.30</mysql.version><alibaba.druid.version>1.2.4</alibaba.druid.version><thymeleaf.version>3.0.15.RELEASE</thymeleaf.version><spring4.version>3.0.12.RELEASE</spring4.version><mapstruct.version>1.5.3.Final</mapstruct.version></properties><!-- 依赖关系 --><dependencies><!-- springmvc --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 测试test --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- jpa(持久层) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!--mybatis-plus依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatisPlus.version}</version></dependency><!--lombok依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency><!-- mysql(数据库) --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!-- alibaba数据库连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${alibaba.druid.version}</version></dependency><dependency><groupId>org.thymeleaf</groupId><artifactId>thymeleaf</artifactId><version>${thymeleaf.version}</version></dependency><!-- Spring 4集成包(这可能是Spring应用程序所需的一切)--><dependency><groupId>org.thymeleaf</groupId><artifactId>thymeleaf-spring4</artifactId><version>${spring4.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><!-- 属性转换 --><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>${mapstruct.version}</version></dependency><!-- idea 2018.1.1 之前的版本需要添加下面的配置,后期的版本就不需要了,可以注释掉,我自己用的2022.2.3 --><!--  <dependency>--><!--     <groupId>org.mapstruct</groupId>--><!--     <artifactId>mapstruct-processor</artifactId>--><!--     <version>${org.mapstruct.version}</version>--><!--     <scope>provided</scope>--><!--  </dependency>--></dependencies><!-- 编译插件 --><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><includeSystemScope>true</includeSystemScope></configuration></plugin><!-- 原有工具自带的编译器时无法生成实现类,需要maven 的方式来进行编译,才会生成属性转换的实现类。需添加以下依赖 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>${java.version}</source><target>${java.version}</target><annotationProcessorPaths><!-- lombok的依赖位置一定放在mapstruct之前 否则转换后的对象获取不到属性值 --><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></path><path><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${mapstruct.version}</version></path></annotationProcessorPaths></configuration></plugin></plugins></build>
</project>

PS:lombok和mapstruct的版本兼容问题(可以直接使用上面pom里的版本)

1、maven插件要使用3.6.0版本以上;

2、lombok使用1.16.16版本以上;

3、另外编译的lombok和mapstruct的插件不要忘了加上。否则会出现下面的错误:No property named "aaa" exists in source parameter(s). Did you mean "null"?

二、转换实体类

⑴.源实体1:

package com.***;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;/*** 学生*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {/*** ID*/private Long userId;/*** 姓名*/private String name;/*** 年龄*/private Integer age;/*** 手机号*/private String phone;/*** 性别(1男 2女)*/private Integer sex;/*** 生日*/private String birthday;/*** 创建时间*/private Date createTime;}

⑵.源实体2:

package com.***;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;/*** 课程*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Course {/*** 课程ID*/private Long courseId;/*** 课程名称*/private String courseName;/*** 序号*/private Integer sortNo;}

⑶.目标实体1:

package com.***;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;/*** 学生Vo*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StudentVo {/***用户ID */private Long userId;/*** 姓名*/private String name;/*** 年龄*/private Integer age;/*** 手机号*/private String phone;/*** 性别(1男 2女)*/private Integer gender;/*** 生日*/private String birthday;/*** 创建时间*/private Date createTime;}

⑷.目标实体2:

package com.***;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;/*** 学生课程Vo*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StudentCourseVo {/*** 学生姓名*/private String name;/*** 年龄*/private Integer age;/*** 性别(1男 2女)*/private String gender;/*** 生日*/private String birthday;/*** 课程名称*/private String course;}

⑸.转换Mapper接口:(编译完成后会自动生成相应的实现类)

package com.***;import com.test.java.domain.entity.Course;
import com.test.java.domain.entity.Student;
import com.test.java.domain.vo.StudentCourseVo;
import com.test.java.domain.vo.StudentVo;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;import java.util.ArrayList;
import java.util.Date;
import java.util.List;/*** 转换mapper*/
@Mapper
public interface StudentWrapper {StudentWrapper INSTANCE = Mappers.getMapper(StudentWrapper.class);// 转换一:实体转实体@Mapping(target = "userId", ignore = true)@Mapping(source = "sex", target = "gender")@Mapping(target = "createTime", expression = "java(new java.util.Date())")@Mapping(source = "name", target = "name", defaultValue = "张三")StudentVo convertVo(Student student);// 转换二:list转listList<StudentVo> convertList(List<Student> list);// 转换三:多对象转换一个对象@Mapping(source = "student.sex", target = "gender")@Mapping(source = "course.courseName", target = "course")StudentCourseVo convertTo(Student student, Course course);}

现在就可以直接使用mapper接口进行属性转换了,以下举例有三种转换用法:

1、转换一:对象转对象

2、转换二:集合转集合

3、转换三:多个对象转单一对象

    public static void main(String[] args) {// 转换一Student student = Student.builder().userId(100L).age(18).phone("13012345678").sex(1).birthday("01-01").build();StudentVo convertVo = StudentWrapper.INSTANCE.convertVo(student);System.out.println("转换一、实体转实体:" + convertVo);// 转换二Student student1 = Student.builder().userId(1L).name("张三").age(18).phone("13012345678").sex(1).birthday("01-01").createTime(new Date()).build();Student student2 = Student.builder().userId(2L).name("李四").age(20).phone("15026668652").sex(2).birthday("05-01").createTime(new Date()).build();List<Student> list = new ArrayList<>();list.add(student1);list.add(student2);List<StudentVo> convertList = StudentWrapper.INSTANCE.convertList(list);System.out.println("转换二、list转list:" + convertList);// 转换三Student student3 = Student.builder().name("小明").age(18).phone("13512365568").sex(1).birthday("05-06").createTime(new Date()).build();Course course = Course.builder().courseName("《Java从入门到放弃》").sortNo(1).build();StudentCourseVo convertTo = StudentWrapper.INSTANCE.convertTo(student3, course);System.out.println("转换三、多对象转换一个对象:" + convertTo);}

转换结果:

三、特殊处理

mapper转换接口中,还可以进行字段映射,改变字段类型,指定格式化、赋予默认值、过滤不需要转换的字段、自定义转换等方式,包括一些日期的默认处理,只需在@Mapping注解中添加相应参数即可,如下:

  • 字段映射
    @Mapping(source = "sex", target = "gender")StudentVo convertVo(Student student);
source:代表源字段;
target:代表目标字段;
  • 日期格式化
    @Mapping(source = "createTime",target = "createTime",dateFormat = "yyyy-MM-dd HH:mm:ss")StudentVo convertVo(Student student);
  • 默认值
    @Mapping(source = "name", target = "name", defaultValue = "张三")StudentVo convertVo(Student student);

 defaultValue:转换时,赋予默认值;

  • 过滤不需要转换的字段
    @Mapping(target = "userId", ignore = true)StudentVo convertVo(Student student);

ignore:默认为false,不过滤;

  • 自定义转换
    @Mapping(target = "createTime", expression = "java(new java.util.Date())")StudentVo convertVo(Student student);

expression:自定义转换规则,当前案例是createTime字段获取当前系统时间

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、评论、收藏➕关注,您的支持是我坚持写作最大的动力。

相关文章:

可别再用BeanUtils了(性能拉胯),试试这款转换神器

老铁们是不是经常为写一些实体转换的原始代码感到头疼&#xff0c;尤其是实体字段特别多的时候。有的人会说&#xff0c;我直接使用get/set方法。没错&#xff0c;get/set方法的确可以解决&#xff0c;而且也是性能较高的处理方法&#xff0c;但是大家有没有想过&#xff0c;要…...

Transformer 杂记

Transformer输入的是token,来自语言序列的启发。卷积神经网络&#xff08;CNN&#xff09;是如何进行物种分类的.它实际是直接对特征进行识别&#xff0c;也就是卷积神经网络最基本的作用&#xff1a;提取图像的特征。例如&#xff1a;卷积神经网络判断一只狗的时候&#xff0c…...

实现异步的8种方式

前言异步执行对于开发者来说并不陌生&#xff0c;在实际的开发过程中&#xff0c;很多场景多会使用到异步&#xff0c;相比同步执行&#xff0c;异步可以大大缩短请求链路耗时时间&#xff0c;比如&#xff1a;「发送短信、邮件、异步更新等」&#xff0c;这些都是典型的可以通…...

Github隐藏功能显示自己的README,个人化你的Github主页

Github隐藏功能&#xff1a;显示自己的README 你可能还不知道&#xff0c;GitHub 悄悄上线了一个全新的个人页功能&#xff0c;显示一个自定义的 README.MD 在个人首页。要激活此功能&#xff0c;需要新建一个与自己 ID 同名的 Repository&#xff0c;新 Repo 里的README.MD将…...

单片机 | 51单片机原理

【金善愚】 单片机应用原理篇 笔记整理 课程视频 &#xff1a;https://space.bilibili.com/483942191/channel/collectiondetail?sid51090 文章目录一、引脚分布介绍1.分类2.电源引脚3.时钟引脚(2根)4.控制引脚(4根)5.端口引脚(32根)二、存储器结构及空间分布介绍1.存储器的划…...

(只需五步)注册谷歌账号详细步骤,解决“此电话号码无法验证”问题

目录 第一步&#xff1a;打开google浏览器 第二步&#xff1a;设置语言为英语&#xff08;美国&#xff09; 第三步&#xff1a;点击重新启动&#xff0c;重启浏览器 第四步&#xff1a;开始注册 第五步&#xff0c;成功登录google账号&#xff01; 如果出现这样的原因&…...

ChatGPT使用介绍、ChatGPT+编程、相关组件和插件记录

文章目录介绍认识ChatGPT是通过英汉互译来实现中文回答的吗同一个问题&#xff0c;为什么中英文回答不同ChatGPT的使用对话组OpenAI APIAI智能绘图DALLE 2ChatGPT for Google插件ChatGPT编程编写代码代码错误修正与功能解读代码评审与优化推荐技术方案编写和优化SQL语句在代码编…...

linux系统中复制粘贴和头文件问题解决方案

各位开发者大家好&#xff0c;好久不见&#xff0c;为了更好的服务大家&#xff0c;将平常所见所闻&#xff0c;以及遇到的问题和解决办法进行记录和总结。大家在学习过程中&#xff0c;有任何问题欢迎交流学习&#xff01;&#xff01;&#xff01;。 第一&#xff1a;如何将w…...

Vue项目实战 —— 后台管理系统( pc端 ) —— Pro最终版本

前期回顾 开源项目 —— 原生JS实现斗地主游戏 ——代码极少、功能都有、直接粘贴即用_js斗地主_0.活在风浪里的博客-CSDN博客JS 实现 斗地主网页游戏https://blog.csdn.net/m0_57904695/article/details/128982118?spm1001.2014.3001.5501 通用版后台管理系统&#xff0c;如果…...

Springboot+vue开发的图书借阅管理系统项目源码下载-P0029

前言图书借阅管理系统项目是基于SpringBootVue技术开发而来&#xff0c;功能相对比较简单&#xff0c;分为两个角色即管理员和学生用户&#xff0c;核心业务功能就是图书的发布、借阅与归还&#xff0c;相比于一些复杂的系统&#xff0c;该项目具备简单易入手&#xff0c;便于二…...

学习 Python 之 Pygame 开发魂斗罗(十三)

学习 Python 之 Pygame 开发魂斗罗&#xff08;十三&#xff09;继续编写魂斗罗1. 创建敌人2类2. 编写敌人2类的draw()函数3. 编写敌人越界消失函数4. 编写敌人开火函数5. 把敌人2加入地图进行测试继续编写魂斗罗 在上次的博客学习 Python 之 Pygame 开发魂斗罗&#xff08;十…...

指针进阶(中)

提示&#xff1a; 上集内容小复习&#x1f970;&#x1f970; int my_strlen(const char* str) {return 1; } int main() {//指针数组char* arr[10];//数组指针int arr2[5] { 0 };int(*p)[5] &arr2; //p是一个指向数组的指针变量//函数指针int (*pf)(const char*)&m…...

C/C++获取文件名的方法(__FILE__,__builtin_FILE(),__BASE_FILE__)

目录标题C/C获取文件名的方法__FILE__宏避免__FILE__宏的错误慎用$(subst $(dir $<),,$<)\"")来重定义__BASE_FILE__宏__builtin_FILE()函数Windows API函数GetModuleFileName()getenv()使用cmake中的变量重定义__FILE__宏的CMake示例C/C获取文件名的方法 使用…...

线程池的讲解和实现

&#x1f680;&#x1f680;&#x1f680;&#x1f680;&#x1f680;&#x1f680;&#x1f680;大家好,今天为大家带来线程池相关知识的讲解,并且实现一个线程池 &#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;&#x1f338;…...

linux编程──gcc和clang

实验链接 编译原理实验-GCC/Clang工具链在ARM架构上的使用 实验报告 第1关&#xff1a;理解程序的不同表示形式 ##问题1-1&#xff1a; 如果在命令行下执行 gcc -DNEG -E sample.c -o sample.i生成的sample.i 与之前的有何区别&#xff1f; 根据定义NEG,而选择了M定义为-4…...

字节跳动测试岗面试记:二面被按地上血虐,所幸Offer已到手...

在互联网做了几年之后&#xff0c;去大厂“镀镀金”是大部分人的首选。大厂不仅待遇高、福利好&#xff0c;更重要的是&#xff0c;它是对你专业能力的背书&#xff0c;大厂工作背景多少会给你的简历增加几分竞争力。 但说实话&#xff0c;想进大厂还真没那么容易。最近面试字…...

5.多线程学习

作者&#xff1a;爱塔居 专栏&#xff1a;JavaEE 作者简介&#xff1a;大三学生&#xff0c;喜欢总结与分享~ 文章目录 目录 文章目录 章节回顾 一、wait 和notify 二、设计模式 2.1 单例模式 章节回顾 线程安全 1.一个线程不安全的案例&#xff08;两个线程各自自增5w次&…...

数据结构中的堆

一、树的重要知识点 节点的度&#xff1a;一个节点含有的子树的个数称为该节点的度&#xff08;有几个孩子&#xff09;叶节点或终端节点:度为0的节点称为叶节点&#xff1b;如上图&#xff1a;B、C、H、I...等节点为叶节点&#xff08;0个孩子&#xff09;非终端节点或分支节点…...

Linux内核设备信息集合

本文结合设备信息集合的详细讲解来认识一下设备和驱动是如何绑定的。所谓设备信息集合&#xff0c;就是根据不同的外设寻找各自的外设信息&#xff0c;我们知道一个完整的开发板有 CPU 和各种控制器&#xff08;如 I2C 控制器、SPI 控制器、DMA 控制器等&#xff09;&#xff0…...

若依框架---权限管理设计

前言 若依权限管理包含两个部分&#xff1a;菜单权限 和 数据权限。菜单权限控制着我们可以执行哪些操作。数据权限控制着我们可以看到哪些数据。 菜单是一个概括性名称&#xff0c;可以细分为目录、菜单和按钮&#xff0c;以若依自身为例&#xff1a; 目录&#xff0c;就是页…...

Java设计模式(二)——工厂模式

当用户需要一个类的子类实例&#xff0c;且不希望与该类的子类形成耦合或者不知道该类有哪些子类可用时&#xff0c;可采用工厂模式&#xff1b;当用户需要系统提供多个对象&#xff0c;且希望和创建对象的类解耦时&#xff0c;可采用抽象工厂模式。 工厂模式一般分为简单工厂、…...

【Maven】

MavenMaven简介仓库坐标Maven项目构建依赖管理生命周期及插件插件模块拆分与开发聚合继承属性版本管理资源配置多环境开发配置跳过测试私服Maven简介 Maven的本质时一个项目管理工具&#xff0c;将项目开发和管理过程抽象成一个项目对象模型(POM) POM(Project Object Model)&a…...

[JAVA]继承

目录 1.继承的概念 2.继承的语法 3.父类成员访问 3.1子类中访问父类成员变量 3.2子类中访问父类成员方法 4.super关键字 5.子类构造方法 6.继承方式 7.final关键字和类的关系 面向对象思想中提出了继承的概念&#xff0c;专门用来进行共性抽取&#xff0c;实现代码复…...

Vue3 pinia持久化存储(组合式Api案例演示)

pinia-plugin-persist&#xff08; pinia持久化插件&#xff09; 本文采用的是 组合式Api的方式来做Pinia的持久化存储演示 如果对pinia的持久化还是不是很了解的&#x1f468;‍&#x1f393;&#xff5c;&#x1f469;‍&#x1f393;&#xff0c;可以看一下笔者的上一篇文章…...

8个你一看就觉得很棒的Vue开发技巧

1.路由参数解耦 通常在组件中使用路由参数&#xff0c;大多数人会做以下事情。 export default {methods: {getParamsId() {return this.$route.params.id}} }在组件中使用 $route 会导致与其相应路由的高度耦合&#xff0c;通过将其限制为某些 URL 来限制组件的灵活性。 正…...

vue3+ts 开发效率提升

1、vite pnpm项目初始化 pnpm&#xff1a; 比npm或yarn快10倍 pnpm与其他包管理器&#xff08;如npm和Yarn&#xff09;的不同之处在于它使用一种称为“硬链接”的独特安装方法。当你使用PNPM安装一个包时&#xff0c;它并不会将包的文件复制到每个项目的node_modules目录中&a…...

【数据结构与算法】队列和栈的相互实现以及循环队列

目录&#x1f314;一.用队列实现栈&#x1f319;1.题目描述&#x1f319;2.思路分析&#x1f319;3.代码实现⛈二.用栈实现队列☔1.题目描述☔2.思路分析☔3.代码实现&#x1f308;三.实现循环队列&#x1f314;一.用队列实现栈 &#x1f319;1.题目描述 我们先看一下题目链接…...

mysql连接不上问题解决

公司新搭内网测试环境&#xff0c;mysql远程登录问题解决 远程登录: 1 修改host, mysql> select user,host,plugin from user; ---------------------------------------------------- | user | host | plugin | ------------------------…...

利用nginx实现动静分离的负载均衡集群实战

前言 大家好&#xff0c;我是沐风晓月&#xff0c;今天我们利用nginx来作为负载&#xff0c;实现两台apache服务器的动静分离集群实战&#xff1b; 本文收录于沐风晓月的专栏《linux基本功-系统服务实战》&#xff0c;更多内容可以关注我的博客&#xff1a; https://blog.csd…...

与chatGPT神聊,引领你深入浅出系统调用

在操作系统的教学中&#xff0c;系统调用的作用不言而喻&#xff0c;但是&#xff0c;对系统调用常常是雾里看花&#xff0c;似乎明白&#xff0c;又难以真正的触及&#xff0c;即使在代码中调用了系统调用&#xff0c;比如调用fork&#xff08;&#xff09;创建进程&#xff0…...

没网站怎样做cpa/学电商哪个培训学校好

刚开始的时候一直不知道怎么回事&#xff0c;不过幸好我有在每个class 的析构时都打印一条信息。 这个时候发现我的一个tcp_connection (就是自定义的一个连接类) 在最后才被析构。 所以感觉这里可能出了问题。 由于tcp_connection 是派生自boost::enable_shared_from_this<…...

做网站需要哪些硬件软件/上海b2b网络推广外包

由于网上曾经流传过一段时间来自ASTGO官方的ASTGO体验版(下载地址&#xff1a;http://www.51voip.org/post/33.html)&#xff0c;这个版本有个特色就是安装后不需要激活码激活即可打通电话&#xff0c;但是会随机显示4-30线内并发&#xff0c;基本上不会超过10线并发&#xff0…...

专业的美容网站建设/百度旧版本下载

慕仰8121524Go语言操作数据库非常的简单&#xff0c;他也有一个类似JDBC的东西"database/sql"实现类是"github.com/go-sql-driver/mysql"使用过JDBC的人应该一看就懂对日期的处理比较晦涩,没有JAVA流畅:复制代码代码如下:package mainimport ( "da…...

wordpress 带分页的主题/网络优化培训

1.使用django-admin startproject show创建项目,并使用python manage.py startapp team_show创建应用 2.进行相关的配置 3.代码的实现 转载于:https://www.cnblogs.com/sjzsjzsjz/p/8807221.html...

php网站开发技术要点/baidu百度首页

Arch-Linux-pacman-pkg 1. 软件包基础搜索及安装卸载2. 包的查询及清理3. 软件包和文件的查询4. 查询包详细信息5. 卸载不再被需要的软件包6. 清除多余的安装包缓存(pkg包)更新日志&#xff1a;20190422地球日&#xff0c;增加$ sudo pacman -Qo20190619, 增加$ sudo paccache …...

我想做微商怎么加入/seo和sem分别是什么

唐代灵州的葬俗 杨森翔 2003年春天&#xff0c;在吴忠金星村绿地苑基建工程中出土的大唐吕氏夫人墓志铭上&#xff0c;有如下一段文字&#xff1a;夫人“以太和四年&#xff08;830年&#xff09;七月六日終於靈州私第&#xff0c;享年五十有七……其年十月十四日殯於回樂縣東原…...