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

柳市网站优化sae 网站备案

柳市网站优化,sae 网站备案,网站首页被k还有救吗,保洁公司用哪些网站做推广🥂(❁◡❁)您的点赞👍➕评论📝➕收藏⭐是作者创作的最大动力🤞 💖📕🎉🔥 支持我:点赞👍收藏⭐️留言📝欢迎留言讨论 🔥🔥&…

🥂(❁´◡`❁)您的点赞👍➕评论📝➕收藏⭐是作者创作的最大动力🤞

💖📕🎉🔥 支持我:点赞👍+收藏⭐️+留言📝欢迎留言讨论

🔥🔥🔥(源码 + 调试运行 + 问题答疑)

🔥🔥🔥  有兴趣可以联系我。

我们常常在当下感到时间慢,觉得未来遥远,但一旦回头看,时间已经悄然流逝。对于未来,尽管如此,也应该保持一种从容的态度,相信未来仍有许多可能性等待着我们。 

目录

一、问题根源:JDBC执行结果与Java方法签名的鸿沟

二、解决方案:在MapperProxy.invoke中实现返回值适配

三、深入思考:这种灵活性的价值与延伸

四、总结与启示


  1. MyBatis动态代理黑魔法:MapperProxy如何智能处理增删改的返回值?

  2. 手写MyBatis(五):MapperProxy的返回值适配策略,让接口设计更灵活

  3. 从void到boolean:深度解析MyBatis Mapper接口返回值类型的兼容性设计

  4. 不只是查询!MapperProxy如何处理增删改操作的多种返回值类型?


在前面的系列文章中,我们成功实现了MyBatis的Mapper动态代理,让一个简单的Java接口能够神奇地执行SQL查询。然而,细心的读者可能会发现,我们之前的实现主要聚焦于SELECT查询操作。当我们转向INSERTUPDATEDELETE等写操作时,一个新的挑战出现了:如何让Mapper接口中的增删改方法支持不同的返回值类型?

在MyBatis的实际使用中,我们经常会看到这样灵活的写法:

public interface UserMapper {void insertUser(User user); // 不关心返回值int updateUser(User user);  // 想要知道影响了多少行boolean deleteUser(Long id); // 只关心是否成功Integer insertUserAndReturnCount(User user); // 包装类型也可以}

这种设计给予了开发者极大的便利。今天,我们就来深入剖析MapperProxy如何通过巧妙的返回值类型适配策略,实现这种灵活性。

一、问题根源:JDBC执行结果与Java方法签名的鸿沟

要理解这个问题的本质,我们需要回到最基础的JDBC层面。无论是Statement还是PreparedStatement,执行增删改操作的方法都是executeUpdate(),它的返回值是一个int类型,表示受影响的行数(affected rows)

然而,在Java接口设计中,开发者可能有着不同的意图:

  • 不关心结果:只想执行操作,不需要知道结果,适合返回void

  • 想知道具体影响:需要确切知道修改了多少行数据,适合返回int

  • 只关心成败:只想知道操作是否成功(通常认为影响行数大于0就成功),适合返回boolean

MapperProxy的核心任务,就是架起一座桥梁,将JDBC返回的统一的int类型,智能地转换适配成Mapper接口方法所声明的各种返回类型

二、解决方案:在MapperProxy.invoke中实现返回值适配

我们的改造主要在MapperProxyinvoke方法中进行。我们需要在执行SQL之后,根据方法返回类型的不同,对SqlSession返回的原始int值进行二次加工。

步骤一:判断SQL命令类型

首先,我们需要确定当前调用的方法是增删改还是查询。这可以通过MappedStatement中的信息获取(通常SQL命令类型保存在其中)。

 public class MapperProxy implements InvocationHandler {// ... 其他字段private final SqlSession sqlSession;private final Configuration configuration;​@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// ... 获取MappedStatement的逻辑MappedStatement ms = configuration.getMappedStatement(statementId);SqlCommandType sqlCommandType = ms.getSqlCommandType();​// 根据SQL命令类型分支处理if (sqlCommandType == SqlCommandType.INSERT || sqlCommandType == SqlCommandType.UPDATE || sqlCommandType == SqlCommandType.DELETE) {// 处理增删改return handleUpdate(method, ms, args);} else {// 处理查询(原有逻辑)return handleQuery(method, ms, args);}}}

步骤二:执行并转换返回值(核心)

handleUpdate方法是实现灵活性的关键。在这里,我们执行操作并完成类型转换。

private Object handleUpdate(Method method, MappedStatement ms, Object[] args) {// 1. 执行原始的增删改操作,获取受影响行数int affectedRows = sqlSession.update(ms.getId(), args[0]); // 简化处理,假设只有一个参数​// 2. 获取Mapper接口方法的实际返回类型Class<?> returnType = method.getReturnType();​// 3. 根据返回类型进行适配转换if (returnType == void.class || returnType == Void.class) {return null; // 返回void的方法,直接忽略返回值} else if (returnType == int.class || returnType == Integer.class) {return affectedRows; // 返回int或Integer,直接返回行数} else if (returnType == boolean.class || returnType == Boolean.class) {return affectedRows > 0; // 返回boolean,判断是否有影响} else if (returnType == long.class || returnType == Long.class) {return (long) affectedRows; // 支持Long类型} else {// 其他不支持的类型,可以抛出异常或进行其他处理throw new RuntimeException("Unsupported return type for update operation: " + returnType);}}

通过这段代码,我们可以看到MyBatis如何优雅地解决了返回值适配的问题。这种设计体现了框架设计的用户友好性原则:框架应该去适应开发者的习惯,而不是让开发者来适应框架的限制。

三、深入思考:这种灵活性的价值与延伸

1. 为什么MyBatis要提供这种灵活性?

这背后是深刻的API设计哲学:

  • 意图导向:方法的返回值应该清晰表达开发者的意图。void insert(...)表示“执行插入,我不关心结果”;boolean delete(...)表示“执行删除,告诉我成功与否”;int update(...)表示“执行更新,告诉我具体影响了多少行”。这让代码更具可读性。

  • 减少冗余代码:如果没有这种适配,开发者需要在业务代码中手动进行判断和转换,例如int rows = sqlSession.update(...); return rows > 0;。MapperProxy将这步操作内置,消除了模板代码。

  • 保持接口简洁性:Mapper接口本身非常干净,不需要任何额外的注解来指定返回值处理方式,框架通过方法签名自动推断。

2. 如何获取自增主键?@Options注解的机制

返回值适配解决了“影响行数”的问题,但增删改操作还有一个常见需求:获取数据库自动生成的主键(如MySQL的AUTO_INCREMENT)。

这在MyBatis中是通过@Options注解或<insert>标签的useGeneratedKeyskeyProperty属性实现的。它的原理是:

  1. 框架层面:MyBatis在执行PreparedStatement时,会通过Statement.RETURN_GENERATED_KEYS参数告知JDBC驱动:“请返回生成的主键”。

  2. JDBC驱动:驱动在执行插入后,会通过statement.getGeneratedKeys()方法返回一个包含生成主键的ResultSet。

  3. 结果处理:MyBatis拿到这个ResultSet后,会使用ResultSetHandler将值解析出来。

  4. 属性注入:最关键的一步,MyBatis通过反射,将解析出的主键值,设置到参数对象的keyProperty指定的属性中。

 // 示例用法@Options(useGeneratedKeys = true, keyProperty = "id")int insertUser(User user);​// 调用后,user对象的id属性会被自动赋值为数据库生成的主键userMapper.insertUser(user);System.out.println("Generated ID: " + user.getId()); // 这里可以取到值

值得注意的是,获取自增主键与Mapper方法的返回值是两个独立的过程。方法返回值仍然是受影响行数(适配后的值),而生成的主键被直接回填到了参数对象中。这种设计非常巧妙,同时满足了获取行数和获取主键两个需求。

四、总结与启示

通过对MapperProxy返回值适配机制的深入剖析,我们看到了一个优秀框架在细节处的深思熟虑。它不仅仅是将JDBC操作简单封装,更是从开发者体验出发,提供了高度灵活和直观的API设计。

这种设计模式的精髓在于:在统一的底层实现(JDBC返回int)之上,构建一个能够理解用户意图并进行智能适配的中间层。这为我们设计自己的API和框架提供了宝贵的经验:

  1. 面向接口设计:从用户的使用场景和意图出发,设计最自然的接口。

  2. 提供适配层:在内部实现中,通过适配器模式消化底层差异,向用户提供一致的体验。

  3. 保持灵活性:通过反射等机制,实现运行时的动态决策,而不是在编译时写死逻辑。

现在,我们的手写MyBatis框架不仅能够执行CRUD,更能以多种形式向用户反馈结果,向着更加成熟和完善的方向迈进了一步。


💖学习知识需费心,
📕整理归纳更费神。
🎉源码免费人人喜,
🔥码农福利等你领!

💖常来我家多看看,
📕我是程序员扣棣,
🎉感谢支持常陪伴,
🔥点赞关注别忘记!

💖山高路远坑又深,
📕大军纵横任驰奔,
🎉谁敢横刀立马行?
🔥唯有点赞+关注成!

http://www.dtcms.com/a/535594.html

相关文章:

  • 电子商务网站建设试卷品牌建设公司网站
  • 湖南建设工程信息网站apm搭建 wordpress
  • 建设个人网页登陆网站地方网站怎么做挣钱
  • 搭建自己的个人网站第五届中国国际进口博览会开幕
  • 泰州企业做网站模板网站建设咨询
  • 网站投放广告费用南昌网站建设工作
  • 企业网站策划应该怎么做jsp网站开发四库
  • 软件开发还是网站开发好广州金山大厦 网站建设
  • 眼镜 商城 网站建设推广方法策略
  • app开发和网站开发浙江建设银行网站
  • 广州网站建设360网站优化宝安最好的网站建设
  • 关于文化建设网站wordpress小工具没有
  • 成都网站建设 推广行网站首页建设方案
  • 建设校园门户网站方案网站开发专家
  • 伊春网络建站公司医院网站设计怎么做
  • 洛阳网站推广公司北京网站建设116net
  • 低价网站建设推广优化广州冼村房价
  • 甘孜建设机械网站首页网页编辑软件免费版
  • asp程序设计做网站wordpress 插件 打不开
  • 自己服务器可以做网站saas建站 cms
  • 做网站的类型定西地网站建设
  • 学习网站建设最简单的书响应式网站无法做百度联盟
  • 中国住房和城乡建设部查询网站6做公益网站有什么要求
  • 简单网站设计模板搜狗推广找谁
  • 英文网站注册装饰公司做网站怎么收费
  • 用wordpress搭建网站现在北京能不能去
  • 建设银行u盾用网站打不开重庆做个网站多少钱
  • HTML网站制作设计制作网页焦点图
  • 网站建设实例建设一个网站最低消费
  • 网站建设服务8票付通app下载