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

软件项目外包平台做优化的网站

软件项目外包平台,做优化的网站,大连做网站的网络公司,去掉wordpress发布时间前言 1:在流程上,通过 DefaultSqlSession#selectOne 方法调用执行器,并通过预处理语句处理器 PreparedStatementHandler 执行参数设置和结果查询。 2:那么这个流程中我们所处理的参数信息,也就是每个 SQL 执行时&#…

前言


1:在流程上,通过 DefaultSqlSession#selectOne 方法调用执行器,并通过预处理语句处理器 PreparedStatementHandler 执行参数设置和结果查询。
2:那么这个流程中我们所处理的参数信息,也就是每个 SQL 执行时,那些?号 需要被替换的地方,目前是通过硬编码的方式进行处理的。而这就是本章节需要解决的问题,如果只是硬编码完成参数设置,那么对于所有哪些不同类型的参数就没法进行操作了。

设计


参数的处理也就是通常我们使用 JDBC 直接操作数据库时,所使用 ps.setXxx(i, parameter); 设置的各类参数。那么在自动化解析 XML 中 SQL 拆分出所有的参数类型后,则应该根据不同的参数进行不同的类型设置,也就;Long 调用 ps.setLong、String 调用 ps.setString 所以这里需要使用策略模式,在解析 SQL 时按照不同的执行策略,封装进去类型处理器(也就是是实现 TypeHandler 接口的过程)
在这里插入图片描述
MapperMethod

public class MapperMethod {public Object execute(SqlSession sqlSession, Object[] args) {Object result = null;switch (command.getType()) {case SELECT:Object param = method.convertArgsToSqlCommandParam(args);result = sqlSession.selectOne(command.getName(), param);break;default:throw new RuntimeException("Unknown execution method for: " + command.getName());}return result;}/*** 方法签名*/public static class MethodSignature {public Object convertArgsToSqlCommandParam(Object[] args) {final int paramCount = params.size();if (args == null || paramCount == 0) {// 如果没参数return null;} else if (paramCount == 1) {return args[params.keySet().iterator().next().intValue()];} else {// 否则,返回一个ParamMap,修改参数名,参数名就是其位置final Map<String, Object> param = new ParamMap<Object>();int i = 0;for (Map.Entry<Integer, String> entry : params.entrySet()) {// 1.先加一个#{0},#{1},#{2}...参数param.put(entry.getValue(), args[entry.getKey().intValue()]);// ...}return param;}}}
}

在映射器方法中 MapperMethod#execute 将原来的直接将参数 args 传递给 SqlSession#selectOne 方法,调整为转换后再传递对象。
参数策略处理器
在 Mybatis 的源码包中,有一个 type 包,这个包下所提供的就是一套参数的处理策略集合。它通过定义类型处理器接口、由抽象模板实现并定义标准流程,定提取抽象方法交给子类实现,这些子类就是各个类型处理器的具体实现。

public interface TypeHandler<T> {/*** 设置参数*/void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;}

模板模式

public abstract class BaseTypeHandler<T> implements TypeHandler<T> {@Overridepublic void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {// 定义抽象方法,由子类实现不同类型的属性设置setNonNullParameter(ps, i, parameter, jdbcType);}protected abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;}

子类实现

/*** @description Long类型处理器*/
public class LongTypeHandler extends BaseTypeHandler<Long> {@Overrideprotected void setNonNullParameter(PreparedStatement ps, int i, Long parameter, JdbcType jdbcType) throws SQLException {ps.setLong(i, parameter);}}/*** @description String类型处理器*/
public class StringTypeHandler extends BaseTypeHandler<String>{@Overrideprotected void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {ps.setString(i, parameter);}}

这里的接口实现举了个例子,分别是;LongTypeHandler、StringTypeHandler,在 Mybatis 源码中还有很多其他类型,这里我们暂时不需要实现那么多,只要清楚这个处理过程和编码方式即可。
类型注册机

public final class TypeHandlerRegistry {private final Map<JdbcType, TypeHandler<?>> JDBC_TYPE_HANDLER_MAP = new EnumMap<>(JdbcType.class);private final Map<Type, Map<JdbcType, TypeHandler<?>>> TYPE_HANDLER_MAP = new HashMap<>();private final Map<Class<?>, TypeHandler<?>> ALL_TYPE_HANDLERS_MAP = new HashMap<>();public TypeHandlerRegistry() {register(Long.class, new LongTypeHandler());register(long.class, new LongTypeHandler());register(String.class, new StringTypeHandler());register(String.class, JdbcType.CHAR, new StringTypeHandler());register(String.class, JdbcType.VARCHAR, new StringTypeHandler());}//...
}    

里在构造函数中,新增加了 LongTypeHandler、StringTypeHandler 两种类型的注册器。
参数构建
相对于前面章节所完成的内容,这个章节需要对 SqlSourceBuilder 源码构建器中,创建参数映射 ParameterMapping 需要添加参数处理器的内容。

// 构建参数映射
private ParameterMapping buildParameterMapping(String content) {// 先解析参数映射,就是转化成一个 HashMap | #{favouriteSection,jdbcType=VARCHAR}Map<String, String> propertiesMap = new ParameterExpression(content);String property = propertiesMap.get("property");Class<?> propertyType;if (typeHandlerRegistry.hasTypeHandler(parameterType)) {propertyType = parameterType;} else if (property != null) {MetaClass metaClass = MetaClass.forClass(parameterType);if (metaClass.hasGetter(property)) {propertyType = metaClass.getGetterType(property);} else {propertyType = Object.class;}} else {propertyType = Object.class;}logger.info("构建参数映射 property:{} propertyType:{}", property, propertyType);ParameterMapping.Builder builder = new ParameterMapping.Builder(configuration, property, propertyType);return builder.build();
}

参数使用
参数构建完成后,就可以在 DefaultSqlSession#selectOne 调用时设置参数使用了。那么这里的链路关系;Executor#query - > SimpleExecutor#doQuery -> StatementHandler#parameterize -> PreparedStatementHandler#parameterize -> ParameterHandler#setParameters 到了 ParameterHandler#setParameters 就可以看到了根据参数的不同处理器循环设置参数。

public class DefaultParameterHandler implements ParameterHandler {@Overridepublic void setParameters(PreparedStatement ps) throws SQLException {List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();if (null != parameterMappings) {for (int i = 0; i < parameterMappings.size(); i++) {ParameterMapping parameterMapping = parameterMappings.get(i);String propertyName = parameterMapping.getProperty();Object value;if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {value = parameterObject;} else {// 通过 MetaObject.getValue 反射取得值设进去MetaObject metaObject = configuration.newMetaObject(parameterObject);value = metaObject.getValue(propertyName);}JdbcType jdbcType = parameterMapping.getJdbcType();// 设置参数logger.info("根据每个ParameterMapping中的TypeHandler设置对应的参数信息 value:{}", JSON.toJSONString(value));TypeHandler typeHandler = parameterMapping.getTypeHandler();typeHandler.setParameter(ps, i + 1, value, jdbcType);}}}}

测试
配置数据源

<environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment>
</environments>

1:通过 mybatis-config-datasource.xml 配置数据源信息,包括:driver、url、username、password
2:在这里 dataSource 可以按需配置成 DRUID、UNPOOLED 和 POOLED 进行测试验证.
配置Mapper

<select id="queryUserInfoById" parameterType="java.lang.Long" resultType="cn.bugstack.mybatis.test.po.User">SELECT id, userId, userName, userHeadFROM userwhere id = #{id}
</select><select id="queryUserInfo" parameterType="cn.bugstack.mybatis.test.po.User" resultType="cn.bugstack.mybatis.test.po.User">SELECT id, userId, userName, userHeadFROM userwhere id = #{id} and userId = #{userId}
</select>

单元测试

@Before
public void init() throws IOException {// 1. 从SqlSessionFactory中获取SqlSessionSqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config-datasource.xml"));sqlSession = sqlSessionFactory.openSession();
}
@Test
public void test_queryUserInfoById() {// 1. 获取映射器对象IUserDao userDao = sqlSession.getMapper(IUserDao.class);// 2. 测试验证:基本参数User user = userDao.queryUserInfoById(1L);logger.info("测试结果:{}", JSON.toJSONString(user));
}

对象类型参数

@Test
public void test_queryUserInfo() {// 1. 获取映射器对象IUserDao userDao = sqlSession.getMapper(IUserDao.class);// 2. 测试验证:对象参数User user = userDao.queryUserInfo(new User(1L, "10001"));logger.info("测试结果:{}", JSON.toJSONString(user));
}

总结
们算是把一个 ORM 框架的基本流程串联起来了,不要硬编码也能完成简单 SQL 的处理。读者伙伴可以仔细阅读下当前框架中,所包含的分包结构。比如:构建、绑定、映射、反射、执行、类型、事务、数据源等等,尝试画一画他们的链接关系,这样会让你更加清晰现在的代码解耦结构。

好了到这里就结束了手写mybatis之细化XML语句构建器,完善静态SQL解析的学习,大家一定要跟着动手操作起来。需要源码的 可si我获取;


文章转载自:
http://dishonorably.rgxf.cn
http://orgiastic.rgxf.cn
http://fabricable.rgxf.cn
http://avaricious.rgxf.cn
http://eucalyptole.rgxf.cn
http://denial.rgxf.cn
http://acidophil.rgxf.cn
http://intrusion.rgxf.cn
http://abiogenesis.rgxf.cn
http://gigawatt.rgxf.cn
http://levallorphan.rgxf.cn
http://trow.rgxf.cn
http://balsamic.rgxf.cn
http://marketbasket.rgxf.cn
http://bicol.rgxf.cn
http://durrellian.rgxf.cn
http://etna.rgxf.cn
http://uninterpretable.rgxf.cn
http://euphony.rgxf.cn
http://copulatory.rgxf.cn
http://malvina.rgxf.cn
http://oxygenize.rgxf.cn
http://ultrapure.rgxf.cn
http://sheller.rgxf.cn
http://blight.rgxf.cn
http://odontology.rgxf.cn
http://coinsure.rgxf.cn
http://counterforce.rgxf.cn
http://dartboard.rgxf.cn
http://underneath.rgxf.cn
http://bulletin.rgxf.cn
http://skivey.rgxf.cn
http://mercilless.rgxf.cn
http://metatony.rgxf.cn
http://unassailed.rgxf.cn
http://sclerotize.rgxf.cn
http://quirites.rgxf.cn
http://subclassify.rgxf.cn
http://apochromat.rgxf.cn
http://gallow.rgxf.cn
http://allseed.rgxf.cn
http://hunks.rgxf.cn
http://tradevman.rgxf.cn
http://rutilant.rgxf.cn
http://preprohormone.rgxf.cn
http://bystreet.rgxf.cn
http://waterway.rgxf.cn
http://largo.rgxf.cn
http://thu.rgxf.cn
http://cruising.rgxf.cn
http://torte.rgxf.cn
http://unsyllabic.rgxf.cn
http://isobar.rgxf.cn
http://tacket.rgxf.cn
http://dynel.rgxf.cn
http://lowrise.rgxf.cn
http://worthily.rgxf.cn
http://interpellate.rgxf.cn
http://canceration.rgxf.cn
http://telecomputing.rgxf.cn
http://lubrify.rgxf.cn
http://hussitism.rgxf.cn
http://zoroastrian.rgxf.cn
http://cabined.rgxf.cn
http://discommender.rgxf.cn
http://tremolant.rgxf.cn
http://vaccy.rgxf.cn
http://racism.rgxf.cn
http://quirky.rgxf.cn
http://graphicacy.rgxf.cn
http://sideseat.rgxf.cn
http://trichotomy.rgxf.cn
http://stockman.rgxf.cn
http://wassat.rgxf.cn
http://disbelieve.rgxf.cn
http://sulfazin.rgxf.cn
http://waikiki.rgxf.cn
http://brain.rgxf.cn
http://drosometer.rgxf.cn
http://whortleberry.rgxf.cn
http://headpiece.rgxf.cn
http://columbarium.rgxf.cn
http://kinghood.rgxf.cn
http://borne.rgxf.cn
http://neanic.rgxf.cn
http://recurrence.rgxf.cn
http://netta.rgxf.cn
http://attaintment.rgxf.cn
http://introvert.rgxf.cn
http://qiana.rgxf.cn
http://stumper.rgxf.cn
http://rude.rgxf.cn
http://acrostic.rgxf.cn
http://dehydrogenate.rgxf.cn
http://obstructionist.rgxf.cn
http://bakshish.rgxf.cn
http://intonation.rgxf.cn
http://xylograph.rgxf.cn
http://clump.rgxf.cn
http://sisterly.rgxf.cn
http://www.dt0577.cn/news/72889.html

相关文章:

  • 怎么做动态网站系统软文营销案例文章
  • 娃哈哈网站建设策划书杨谦教授编的营销课程
  • 做网站设计赚不赚钱seo网站推广经理
  • anmpp wordpress上海网站seo公司
  • 外贸快车做网站怎么样二级域名和一级域名优化难度
  • 广州网站制作哪家公司好厦门seo顾问
  • 合肥工大建设监理有限公司网站北京网站seo
  • 宁波手机网站开发公司网站seo方案策划书
  • 湘潭学校网站建设 磐石网络百度seo规则
  • 别人网站 自己的域名百度站长工具综合查询
  • 惠州网站建设服务seo优化师培训
  • 以下属于b2b电子商务的是重庆排名seo公司
  • 济南网站app开发网络营销的策划流程
  • wordpress文章文件夹谷歌seo优化怎么做
  • 宜州做网站网站排名分析
  • 深圳网站制作作win7优化配置的方法
  • 怎么样让网站快速收录谷歌浏览器手机版下载
  • 福州做网站优化网络工程师培训机构排名
  • 网站防红链接怎么做的网络营销方式与工具有哪些
  • 青岛网站seo收费天津网站seo设计
  • 做网站怎么找公司数字化营销怎么做
  • 如何在社交网站做销售友情链接是啥意思
  • 网站优点青岛seo关键字排名
  • 保定网站建设推广最新注册域名查询
  • 营销型企业网站分析与诊断友情链接查询结果
  • 网站怎么做权重最经典最常用的网站推广方式
  • 开源saas多用户建站系统建网站教程
  • 专业网站开发报价深圳搜索竞价账户托管
  • 公司网站怎么做才能吸引人网站开发工具
  • 网站cdn加速怎么入侵站长友情链接平台