欢迎来到皮皮网官网

【如何找到网页视频的源码】【东部联盟源码】【pgsql源码解析】手写handler源码_手写代码

时间:2024-12-23 02:31:41 来源:仿cbt源码

1.?手写?дhandlerԴ??
2.手写Mybatis自动填充插件
3.MyBatis自定义TypeHandler

手写handler源码_手写代码

??дhandlerԴ??

       Gin 和 Gorm,作为 Golang 开发中的码手码明星组合,为 Web 框架和数据库操作提供了强大支持。写代结合使用它们,手写可以简化CRUD操作和自定义查询,码手码快速构建RESTful API服务,写代如何找到网页视频的源码无需大量手写代码。手写

       通过使用Sponge脚手架,码手码开发者能体验到极致的写代便利。这个工具专为高效开发web后端设计,手写能一键生成CRUD API所需代码,码手码无需任何Go代码编写。写代只需访问sponge的手写GitHub地址github.com/zhufuyi/spon...,通过UI界面输入必要参数,码手码即可下载包含Gin和Gorm配置的写代完整项目代码。

       启动服务后,只需解压并运行,东部联盟源码浏览器中的Swagger页面就能进行增删改查测试。若需添加新表的CRUD API,同样通过Sponge生成对应的handler代码,将生成的目录集成进项目即可。

       对于自定义API,虽然不能自动生成,但Sponge提供了一套清晰的步骤:定义参数结构、错误码、pgsql源码解析编写handler、设置路由、实现业务逻辑,以及可能需要的DAO CRUD代码生成。例如,登录接口需通过添加结构体、定义错误码、编写handler等步骤逐步完成。源码原创系统

       总的来说,Sponge通过集成Gin和Gorm,为Golang开发者提供了创建RESTful API的高效解决方案,大大减少了手动编写CRUD代码的工作量,让你的开发过程更加轻松和高效。

手写Mybatis自动填充插件

       Mybatis插件简介

       MyBatis是一款高效、灵活的持久层框架,提供强大的源码分析图片SQL映射功能。其插件功能允许开发者扩展框架,实现自定义功能,如拦截、修改SQL语句或添加新功能。通过插件,可在MyBatis框架的多个阶段进行干预和扩展,适应各种业务需求。

       编写MyBatis插件需实现框架提供的接口,并在配置文件中注册。插件主要针对ParameterHandler、ResultSetHandler、StatementHandler、Executor四种接口。整体而言,MyBatis插件是一种扩展机制,增强框架功能,满足特定业务场景。

       工程创建及前期准备工作

       本部分为工程准备阶段,核心代码实现位于第三部分。

       创建test数据库

       省略Controller和Service实现代码。

       User.java

       自定义注解@FiledFill,具体实现将在后续部分。

       UserDao.java

       UserDao.xml配置文件

       application.yaml配置文件

       mybatis-config.xml配置文件

       插件核心代码实现

       自定义注解@FiledFill

       编写插件核心代码,并在mybatis-config.xml配置文件中注册自定义插件。

       测试

       执行插入操作时,create_time和update_time字段自动填充。

       执行更新操作时,仅update_time字段被填充。

       执行删除操作时,依据硬删除或软删除策略,字段自动填充。

       插件实现自动填充功能,未来可进一步完善。

MyBatis自定义TypeHandler

       MyBatis自定义TypeHandler1什么是TypeHandler

       TypeHandler根据字面意思即为类型处理器

       引用官方文档的描述:MyBatis在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时,都会用类型处理器将获取到的值以合适的方式转换成Java类型

       MyBatis存在一些默认的类型处理器,可参考官方文档

2为什么要使用TypeHandler

       在开发过程中,当默认的TypeHandler无法满足需求时,例如遇到MyBatis不支持的数据类型或需要特殊处理的类型转换,便需要自己定制对应的TypeHandler

       笔者会在下面的代码实现中完成如下几种情况的TypeHandler:

       逗号分隔保存在数据库中的数据,在对应的Java类中为数组

       自定义枚举

3如何自定义TypeHandler

       MyBatis提供了接口org.apache.ibatis.type.TypeHandler和类org.apache.ibatis.type.BaseTypeHandler

       官方文档给出的示例为继承BaseTypeHandler,笔者在这里也使用这种方式

       先来观察一下官方的StringTypeHandler:

publicclassStringTypeHandlerextendsBaseTypeHandler<String>{ @OverridepublicvoidsetNonNullParameter(PreparedStatementps,inti,Stringparameter,JdbcTypejdbcType)throwsSQLException{ ps.setString(i,parameter);}@OverridepublicStringgetNullableResult(ResultSetrs,StringcolumnName)throwsSQLException{ returnrs.getString(columnName);}@OverridepublicStringgetNullableResult(ResultSetrs,intcolumnIndex)throwsSQLException{ returnrs.getString(columnIndex);}@OverridepublicStringgetNullableResult(CallableStatementcs,intcolumnIndex)throwsSQLException{ returncs.getString(columnIndex);}}

       方法名称和代码都简洁明了,观察可知,只需要完成四个方法的覆盖,即可实现自定义TypeHandler

3.1逗号分隔字符串转数组

       假设用户表t_user设计如下:

idusernametags1adminadmin,user

       对应的Java类为:

@Data@NoArgsConstructor@SuperBuilder(toBuilder=true)publicclassUser{ privateStringid;privateStringusername;privateString[]tags;}

       tags属性在数据库中用逗号分隔的字符串保存,但User类对应的属性为String数组

       可以创建StringArrayTypeHandler来解决类型转换的问题:

publicclassStringArrayTypeHandlerextendsBaseTypeHandler<String[]>{ @OverridepublicvoidsetNonNullParameter(PreparedStatementpreparedStatement,inti,String[]strings,JdbcTypejdbcType)throwsSQLException{ preparedStatement.setString(i,StringUtils.join(strings,","));}@OverridepublicString[]getNullableResult(ResultSetresultSet,Strings)throwsSQLException{ returnconvert(resultSet.getString(s));}@OverridepublicString[]getNullableResult(ResultSetresultSet,inti)throwsSQLException{ returnconvert(resultSet.getString(i));}@OverridepublicString[]getNullableResult(CallableStatementcallableStatement,inti)throwsSQLException{ returnconvert(callableStatement.getString(i));}/***将查询值转换为数组**@paramvalue查询值,String*@return转换结果,String[]*/privateString[]convert(Stringvalue){ returnStringUtils.isEmpty(value)?newString[0]:value.split(",");}}3.2自定义枚举

       如何创建包含中文名称的枚举,可以参考MyBatis中使用Java类与枚举

       先创建工具类用于根据code获取枚举实体:

publicclassValueNameEnumUtils{ privateValueNameEnumUtils(){ }publicstatic<EextendsValueNameEnum>EvalueOf(Class<E>enumClass,intvalue){ E[]enumConstants=enumClass.getEnumConstants();for(Ee:enumConstants){ if(e.getValue()==value){ returne;}}returnnull;}}

       和3.1中的情况不同,枚举的具体类型是不确定,所以我们要使用泛型的方式处理TypeHandler

       创建ValueNameEnumTypeHandler:

publicclassValueNameEnumTypeHandler<EextendsValueNameEnum>extendsBaseTypeHandler<ValueNameEnum>{ privatefinalClass<E>type;publicValueNameEnumTypeHandler(Class<E>type){ if(type==null){ thrownewIllegalArgumentException("Typeargumentcannotbenull");}this.type=type;}}

       泛型虽然名之为泛,但在编译过程中实际会发生类型擦除

       总之,对于泛型TypeHandler,我们需要声明一个用来标识具体类型的属性privatefinalClass<E>type和创建对应的构造函数publicValueNameEnumTypeHandler(Class<E>type)

       接下来和3.1中的一致,重写四个方法:

publicclassValueNameEnumTypeHandler<EextendsValueNameEnum>extendsBaseTypeHandler<ValueNameEnum>{ privatefinalClass<E>type;publicValueNameEnumTypeHandler(Class<E>type){ if(type==null){ thrownewIllegalArgumentException("Typeargumentcannotbenull");}this.type=type;}@OverridepublicvoidsetNonNullParameter(PreparedStatementps,inti,ValueNameEnumparameter,JdbcTypejdbcType)throwsSQLException{ ps.setInt(i,parameter.getValue());}@OverridepublicEgetNullableResult(ResultSetrs,StringcolumnName)throwsSQLException{ intcode=rs.getInt(columnName);returnrs.wasNull()?null:valueOf(code);}@OverridepublicEgetNullableResult(ResultSetrs,intcolumnIndex)throwsSQLException{ intcode=rs.getInt(columnIndex);returnrs.wasNull()?null:valueOf(code);}@OverridepublicEgetNullableResult(CallableStatementcs,intcolumnIndex)throwsSQLException{ intcode=cs.getInt(columnIndex);returncs.wasNull()?null:valueOf(code);}/***根据枚举值返回枚举示例**@paramcode枚举值*@return枚举实例*/privateEvalueOf(intcode){ try{ returnValueNameEnumUtils.valueOf(type,code);}catch(Exceptionex){ thrownewIllegalArgumentException("Cannotconvert"+code+"to"+type.getSimpleName()+"bycodevalue.",ex);}}}

       完成上述代码直接启动,会抛出异常:Unabletofindausableconstructorforclasscn.houtaroy.springboot.common.MyBatis.handler.ValueNameEnumTypeHandler

       产生异常的源码如下:

public<T>TypeHandler<T>getInstance(Class<?>javaTypeClass,Class<?>typeHandlerClass){ //未指定JavaType,此处为falseif(javaTypeClass!=null){ try{ Constructor<?>c=typeHandlerClass.getConstructor(Class.class);return(TypeHandler<T>)c.newInstance(javaTypeClass);}catch(NoSuchMethodExceptionignored){ //ignored}catch(Exceptione){ thrownewTypeException("Failedinvokingconstructorforhandler"+typeHandlerClass,e);}}try{ //此处抛出异常Constructor<?>c=typeHandlerClass.getConstructor();return(TypeHandler<T>)c.newInstance();}catch(Exceptione){ thrownewTypeException("Unabletofindausableconstructorfor"+typeHandlerClass,e);}}

       报错的原因直白,没有找到ValueNameEnumTypeHandler的构造函数

       首先我们要了解下Java类构造函数的机制:如果定义了构造函数,则使用定义,否则默认生成空构造函数

       在3.1中的StringArrayTypeHandler,我们没有定义构造函数,自动生成空构造函数,typeHandlerClass.getConstructor()不会抛出异常

       但ValueNameEnumTypeHandler定义了一个构造函数ValueNameEnumTypeHandler(Class<E>type),且没有指定JavaType,typeHandlerClass.getConstructor()自然抛出异常

       解决方法有两种:

       创造空的构造函数

       指定JavaType

       笔者推荐第二种,因为第一种方式枚举类属性type会产生NPE(空指针异常),MyBatis官方也我们提供了注解@MappedTypes用于指定JavaType:

@MappedTypes(ValueNameEnum.class)publicclassValueNameEnumTypeHandler<EextendsValueNameEnum>extendsBaseTypeHandler<ValueNameEnum>{ //...}4如何使用TypeHandler

       在上一章节中,我们完成了编码实现自定义TypeHandler,但完成的TypeHandler还没办法进行使用,需要手动进行配置

       有两种配置方式:局部使用和全局使用

       以StringArrayTypeHandler举例:

4.1局部使用

       在ResultMap中使用:

<resultMapid="UserResultMap"type="cn.houtaroy.springboot.common.system.model.User"><idcolumn="id"property="id"/><resultcolumn="tags"property="tags"typeHandler="cn.houtaroy.springboot.extension.mybatis.handler.StringArrayTypeHandler"/></resultMap>

       在语句中使用:

updatet_usersettags=#{ tags,typeHandler=cn.houtaroy.springboot.extension.mybatis.handler.StringArrayTypeHandler}4.2全局使用

       使用配置文件指定handler包名:

@Data@NoArgsConstructor@SuperBuilder(toBuilder=true)publicclassUser{ privateStringid;privateStringusername;privateString[]tags;}0

       注意,此配置类型为String,只能配置一个包,推荐使用下面的方式

       手写配置类:

@Data@NoArgsConstructor@SuperBuilder(toBuilder=true)publicclassUser{ privateStringid;privateStringusername;privateString[]tags;}1

       StringArrayTypeHandler不适合全局配置,它会在全部JavaType为String[]的属性上使用

5拓展阅读

       MyBatis3官方文档中TypeHandler内容:mybatis–MyBatis3|配置

       网上搜索的在SpringBean声明周期中进行全局配置:Mybatis自定义全局TypeHander_chuobenggu的博客-CSDN博客

copyright © 2016 powered by 皮皮网   sitemap