文章目录
mybatis
是什么
架构设计
首先建立起Mapper的代理工程和代理
映射器的注册和使用
XML文件解析
数据源解析、创建和使用
SQL执行器(Executor)的定义与实现
SQL解析
参数处理器:策略模式实现
封装处理结果
注解
mybatis
是什么
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。 ——来自官方文档
架构设计
通过XMLConfigBuilder解析xml文件放到Configuration对象中
首先建立起Mapper的代理工程和代理
代理类
package cn.mybatis.binding;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Map;
public class MapperProxy implements InvocationHandler, Serializable {
private static final long serialVersionUID = -6424540398559729838L;
private Map sqlSession;
private final Class mapperInterface;
public MapperProxy(Map sqlSession, Class mapperInterface) {
this.sqlSession = sqlSession;
this.mapperInterface = mapperInterface;
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
if(Object.class.equals(method.getDeclaringClass())){
return method.invoke(this, objects);
}else {
System.out.println("你被代理了");
return sqlSession.get(mapperInterface.getName() + "." + method.getName());
}
}
}
代理工厂
package cn.mybatis.binding;
import java.lang.reflect.Proxy;
import java.util.Map;
public class MapperProxyFactory {
private final Class mapperInterface;
public MapperProxyFactory(Class mapperInterface) {
this.mapperInterface = mapperInterface;
}
public T newInstance(Map sqlSession){
final MapperProxy mapperProxy = new MapperProxy<>(sqlSession,mapperInterface);
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, mapperProxy);
}
}
被代理的接口
package cn.mybatis.dao;
public interface IUserDao {
public String queryUserName(String Id);
}
测试类
@Test
public void test_MapperProxyFactory() {
MapperProxyFactory factory = new MapperProxyFactory<>(IUserDao.class);
Map sqlSession = new HashMap<>();
sqlSession.put("cn.mybatis.dao.IUserDao.queryUserName", "模拟执行 Mapper.xml 中 SQL 语句的操作:查询用户姓名");
IUserDao userDao = factory.newInstance(sqlSession);
String res = userDao.queryUserName("10001");
System.out.println(res);
}
上面代码中sqlSession有所需要执行的sql
映射器的注册和使用
定义一个MapperRegistry,内部定义了一个Map Map, MapperProxyFactory> knownMappers = new HashMap<>(); Class代表着执行sql的接口 MapperProxyFactory是相应的代理工厂 它会扫描所有的接口类,放到这个map中,并且最终会被Configuration调用
SqlSession、DefaultSqlSession 用于定义执行 SQL 标准、获取映射器以及将来管理事务等方面的操作。基本我们平常使用 Mybatis 的 API 接口也都是从这个接口类定义的方法进行使用的。 SqlSessionFactory 是一个简单工厂模式,用于提供 SqlSession 服务,屏蔽创建细节,延迟创建过程。
XML文件解析
需要定义 SqlSessionFactoryBuilder 工厂建造者模式类,通过入口 IO 的方式对 XML 文件进行解析。 文件解析以后会存放到 Configuration 配置类中,接下来你会看到这个配置类会被串联到整个 Mybatis 流程中,所有内容存放和读取都离不开这个类 通过 Configuration 配置类进行存放,包括:添加解析 SQL、注册Mapper映射器。 比较重要的一个是上面提到的MapperRegistry 还定义了一个重要的 protected final Map mappedStatements = new HashMap<>(); 是本章节新添加的 SQL 信息记录对象,包括记录:SQL类型、SQL语句、入参类型、出参类型等 TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry(); 类型别名注册机
这个Configuration最终会放到 DefaultSqlSession里
数据源解析、创建和使用
以事务接口 Transaction 和事务工厂 TransactionFactory 的实现,包装数据源 DruidDataSourceFactory 的功能。 当所有的数据源相关功能准备好后,就是在 XMLConfigBuilder 解析 XML 配置操作中,对数据源的配置进行解析以及创建出相应的服务,存放到 Configuration 的环境配置中。 最后在 DefaultSqlSession#selectOne 方法中完成 SQL 的执行和结果封装,最终就把整个 Mybatis 核心脉络串联出来了。 一次数据库的操作应该具有事务管理能力,而不是通过 JDBC 获取链接后直接执行即可。还应该把控链接、提交、回滚和关闭的操作处理。所以这里我们结合 JDBC 的能力封装事务管理。 通过环境构建 Environment.Builder 存放到 Configuration 配置项中,也就可以通过 Configuration 存在的地方都可以获取到数据源了。
SQL执行器(Executor)的定义与实现
回顾一下流程: DefaultSqlSessionFactor开启operSession,并随着构造参数传递给DefaultSqlSession,并执行DefaultSqlSession#selectOne方法就会调用执行器执行
来看下执行器的操作: 1、定义一个Executor接口,这个接口定义了执行方法、事务获取和相应提交、回滚、关闭 2、在定义BaseExecutor一个抽象工厂进行模板方法的初步定义 3、SimpleExecutor会实现抽像接口进行具体执行,执行实际上是调用StatementHandler接口的具体实现来执行sql的 上面的执行器就完成了 再说下语句处理器:StatementHandler 语句处理器的核心包括了;准备语句、参数化传递参数、执行查询的操作,这里对应的 Mybatis 源码中还包括了 update、批处理、获取参数处理器等。 1、StatementHandler接口定义了具体执行sql的代码基本方法,包括准备语句、参数化传递参数、执行查询的操作 2、BaseStatementHandler 抽象基类实现了StatementHandler,并且增加定义了一系列的抽象方法交给其子类来处理 3、PreparedStatementHandler 预处理语句处理器继承BaseStatementHandler,进行具体的处理,包括 instantiateStatement 预处理 SQL、parameterize 设置参数,以及 query 查询的执行的操作。
SQL解析
解析、绑定、映射、事务、执行、数据源 SQL解析实际是解析XML或者注解中的SQL,并且将绑定的方法中的参数映射到SQL的过程 以XML为例解析: XMLMapperBuilder、XMLStatementBuilder 分别处理映射构建器和语句构建器 1、映射构建器XMLMapperBuilder: parse()方法中会间接调用configuration.addMapper 绑定映射器主要是把 namespace(全路径的接口类) 绑定到 Mapper 上。也就是注册到映射器注册机里。 具体实现是:
mapperRegistry.addMapper(type);
//核如下
knownMappers.put(type, new MapperProxyFactory<>(type)); type是具体的全路径接口类
2、映射构建器:XMLStatementBuilder XMLStatementBuilder 语句构建器主要解析 XML 中 select|insert|update|delete 中的语句 parseStatementNode方法会解析各个参数 包括了语句的ID、参数类型、结果类型、命令(select|insert|update|delete),以及使用语言驱动器处理和封装SQL信息,当解析完成后写入到 Configuration 配置文件中的 Map 映射语句存放中。
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
resultSetTypeEnum, flushCache, useCache, resultOrdered,
keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
3、XML脚本构建器解析:XMLScriptBuilder XMLScriptBuilder#parseScriptNode 解析SQL节点的处理其实没有太多复杂的内容,主要是对 RawSqlSource 的包装处理。 4、SQL源码构建器:SqlSourceBuilder
public SqlSource parse(String originalSql, Class parameterType, Map additionalParameters) {
ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(configuration, parameterType, additionalParameters);
GenericTokenParser parser = new GenericTokenParser("#{", "}", handler);
String sql;
//获取sql
if (configuration.isShrinkWhitespacesInSql()) {
sql = parser.parse(removeExtraWhitespaces(originalSql));
} else {
sql = parser.parse(originalSql);
}
return new StaticSqlSource(configuration, sql, handler.getParameterMappings());
}
参数处理器:策略模式实现
上面实现了解析 XML 中的所需要处理的 Mapper 信息,包括;SQL、入参、出参、类型,并对这些信息进行记录到 ParameterMapping 参数映射处理类中 这里将会使用一个接口实现ps.setXxx(i, parameter);对于所有的类型的支持 关于参数的处理,因为有很多的类型(Long\String\Object…),所以这里最重要的体现则是策略模式的使用 核心处理主要分为三块:类型处理、参数设置、参数使用; 1、以定义 TypeHandler 类型处理器策略接口,实现不同的处理策略,包括;Long、String、Integer 等 定义接口:
public interface TypeHandler {
/**
* 设置参数
*/
void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
}
定义模板
public abstract class BaseTypeHandler implements TypeHandler {
f (parameter == null) {
ps.setNull(i, jdbcType.TYPE_CODE);
} else {
setNonNullParameter(ps, i, parameter, jdbcType);
}
protected abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
}
这里把一些异常处理都给去掉了,保留基本的逻辑。 当传入的参数不为空的时候,可以直接 ps.setNull(i, jdbcType.TYPE_CODE);,当为空的时候就交给具体的子类来处理 子类实现:
public class StringTypeHandler extends BaseTypeHandler {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
throws SQLException {
ps.setString(i, parameter);
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
return cs.getString(columnIndex);
}
}
Mybatis 源码中还有很多其他类型 2、类型策略处理器实现完成后,需要注册到处理器注册机(TypeHandlerRegistry )中,其他模块参数的设置还是使用都是从 Configuration 中获取到 TypeHandlerRegistry 进行使用。
public final class TypeHandlerRegistry {
private final Map> JDBC_TYPE_HANDLER_MAP = new EnumMap<>(JdbcType.class);
private final Map>> TYPE_HANDLER_MAP = new HashMap<>();
private final Map, 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 两种类型的注册器。 3、了这样的策略处理器以后,在进行操作解析 SQL 的时候,就可以按照不同的类型把对应的策略处理器设置到 BoundSql#parameterMappings 参数里 这里主要通过反射的方式获取参数类型,然后 if 判断对应的参数类型是否在 TypeHandlerRegistry 注册器中,如果不在则拆解对象,按属性进行获取 propertyType 的操作。
4、参数使用 那么这里的链路关系;Executor#query - > SimpleExecutor#doQuery -> StatementHandler#parameterize -> PreparedStatementHandler#parameterize -> ParameterHandler#setParameters 到了 ParameterHandler#setParameters 就可以看到了根据参数的不同处理器循环设置参数。 每一个循环的参数设置,都是从 BoundSql 中获取 ParameterMapping 集合进行循环操作 设置参数时根据参数的 parameterObject 入参的信息,判断是否基本类型,如果不是则从对象中进行拆解获取(也就是一个对象A中包括属性b),处理完成后就可以准确拿到对应的入参值了。 基本信息获取完成后,则根据参数类型获取到对应的 TypeHandler 类型处理器,也就是找到 LongTypeHandler、StringTypeHandler 等,确定找到以后,则可以进行对应的参数设置了 typeHandler.setParameter(ps, i + 1, value, jdbcType) 通过这样的方式把我们之前硬编码的操作进行解耦。
封装处理结果
主要是针对JDBC查出来结果映射到标签resultType中去。 我们拿到了 Mapper XML 中所配置的返回类型,解析后把从数据库查询到的结果,反射到类型实例化的对象上。 MapperBuilderAssistant 映射器的助手类,方便我们对参数的统一包装处理,按照职责归属的方式进行细分解耦。 在执行完成sql后得到一个结果会在 DefaultResultSetHandler 进行信息封装 1、对象创建 调用链路:handleResultSet->handleRowValuesForSimpleResultMap->getRowValue->createResultObject 关键代码
private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, List> constructorArgTypes, List constructorArgs, String columnPrefix) throws SQLException {
final Class resultType = resultMap.getType();
final MetaClass metaType = MetaClass.forClass(resultType);
if (resultType.isInterface() || metaType.hasDefaultConstructor()) {
// 普通的Bean对象类型
return objectFactory.create(resultType);
}
throw new RuntimeException("Do not know how to create an instance of " + resultType);
}
2、属性填充 对象实例化完成后,就是根据 ResultSet 获取出对应的值填充到对象的属性中,但这里需要注意,这个结果的获取来自于 TypeHandler#getResult 接口新增的方法,由不同的类型处理器实现,通过这样的策略模式设计方式就可以巧妙的避免 if···else 的判断处理。 columnName 是属性名称,根据属性名称,按照反射工具类从对象中获取对应的 properyType 属性类型,之后再根据类型获取到 TypeHandler 类型处理器。有了具体的类型处理器,在获取每一个类型处理器下的结果内容就更加方便了。 获取属性值后,再使用 MetaObject 反射工具类设置属性值,一次循环设置完成以后,这样一个完整的结果信息 Bean 对象就可以返回了。返回后写入到 DefaultResultContext#nextResultObject 上下文中
注解
MapperAnnotationBuilder中处理注解,这个类在构造函数中配置需要解析的注解,并提供解析方法处理语句的解析。 整个类基本基于Method来获取参数类型、返回类型和注解类型,并完成整个解析过程。
你可能感兴趣的:(Mybatis,mybatis,xml)
clickhouse集群搭建
fusugongzi
clickhouse 服务器 linux
准备三台机器,192.168.20.7,192.168.20.8,192.168.20.10用于搭建clickhouse集群。本次搭建的集群,为三副本的,即一份数据会在三台机器上分别存储,搭建集群只是为了容灾。1.在192.168.20.7上操作在clickhouseconfig.d目录下新建cluster.xml,内容如下91811/data/clickhouse/coordination/lo
KindEditor 实现ctrl+v粘贴图片并上传、word粘贴带图片
Mr_Zang666
word图片一键粘贴 word servlet java
这种方法是servlet,编写好在web.xml里配置servlet-class和servlet-mapping即可使用后台(服务端)java服务代码:(上传至ROOT/lqxcPics文件夹下)配置web.xmlindex.jsp前端(页面)测试代码:WordPaster-jsp-ueditor-1.2.6.0这里写你的初始化内容varpasterMgr=newWordPasterManager
Mybatis 9种动态 sql 标签使用
《小书生》
Mybatis mybatis sql java
MyBatis提供了9种动态SQL标签:trim、where、set、foreach、if、choose、when、otherwise、bind;1.if标签select*fromUserandage>#{age}andnamelikeconcat(#{name},'%')2.choose标签、when标签、otherwise标签select*fromUserandage>#{age}andnam
Mybatis中 #{} 和 ${} 的区别是什么?
《小书生》
Mybatis mybatis
${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于原样文本替换,可以替换任意内容示例:根据参数按任意字段排序select*fromusersorderby${orderCols}#{}是sql的参数占位符,MyBatis会将sql中的#{}替换为?号,在sql执行前会使用PreparedStatement的参数设置方法,按序给sql的?号占位符设置参数值,比如p
BeautifulSoup、lxml/XPath和正则表达式在数据爬取中的适用场景
程序员小王꧔ꦿ
beautifulsoup 正则表达式
在数据爬取中,BeautifulSoup、lxml/XPath和正则表达式的适用场景各有侧重,具体选择需根据数据特征和需求权衡:1.BeautifulSoup(结合CSS选择器)适用场景简单结构页面:标签层级清晰、属性固定的HTML页面(如博客文章标题、商品价格)快速开发需求:适合新手或需要快速实现的原型项目,因其语法直观易读动态内容处理:与requests或Selenium配合时,能处理Java
全面掌握XML:初学者必备手册
Salton Z
本文还有配套的精品资源,点击获取简介:XML是一种用于数据标记的语言,广泛应用于互联网数据交换和应用程序间的数据共享。本手册将引导初学者学习XML的基础知识、命名规则、文档类型定义(DTD)、XMLSchema、命名空间、处理指令、实体、解析方法、XPath、XSLT以及XML在Web服务中的应用和验证过程。通过理论知识和实践练习相结合的方式,初学者能够快速入门并理解XML的结构和应用,为在网页开
使用spring-ai-alibaba本地集成ollama+deepseek
deepseek
序本文主要研究一下如何使用spring-ai-alibaba本地集成ollama+deepseek步骤pom.xml4.0.0com.exampleollama-deepseek-chatpom1.0.0-SNAPSHOTSpringAIAlibabaOllamaDeepSeekChatExampleSpringAIAlibabaOllamaDeepSeekChatExamplesUTF-8UTF
BeautifulSoup、lxml/XPath和正则表达式在数据爬取中的核心差异及适用场景
程序员小王꧔ꦿ
beautifulsoup 正则表达式
一、性能与效率对比工具/方法解析速度(万次耗时)内存占用适用数据规模lxml/XPath0.5秒低10万+级数据正则表达式(regex)1.1秒中非结构化文本BeautifulSoup5.5秒高小规模复杂结构*注:测试环境为Python3.6.5二、功能特性对比1.BeautifulSoup(需配合解析器)优势✅容错性强,能处理残缺HTML(如未闭合标签)✅支持CSS选择器和find_all链式调
MFC中CString的Format、与XML中的XML_SETTEXT格式化注意
云中飞鸿--**峰
MFC XML mfc xml c++
1、在MFC中导入"msxml6.dll",并使用其中的XML_SETTEXT函数,此调用在进行格式化的时候,调用的还是CString.Format()函数!2、用double类型的数据,格式化整形数%d之前,必须将double强转为int,如下图所示:否则,结果将全部变为0,无法获取到真实的数据。3、保存double数据的时候,必须使用%lf进行格式化,如果使用%d进行格式化,结果也会全部变成0
深入了解XML:初学者的全面指南
时雨h
JAVA 面试 java 大数据 开发语言
深入了解XML:初学者的全面指南在当今数字化的世界中,数据的存储和传输至关重要。XML,即可扩展标记语言(eXtensibleMarkupLanguage),作为一种强大的工具,在这方面发挥着重要作用。本文将为初学者全面讲解XML的相关知识,帮助你轻松入门。一、XML的基本概念XML就像是一种通用的语言,用于在不同的计算机系统和应用程序之间存储和传输数据。与我们熟悉的用于展示网页内容的HTML不同
Springboot 集成 netty-socketio + Vue前端分离
Synologs过客
Java java ajax socket websocket spring
Springboot集成netty-socketionetty-socketio:仿`node.js`实现的socket.io服务端1.将WebSocket、AJAX和其它的通信方式全部封装成了统一的通信接口2.使用时,不用担心兼容问题,底层会自动选用最佳的通信方式3.适合进行服务端和客户端双向数据通信pom.xmlcom.corundumstudio.socketionetty-socketio
微信小程序开屏广告实现
m0_49558200
微信小程序 小程序
微信小程序开屏广告即打开微信小程序后全屏展示的广告图片。用户可点击“跳过”按钮跳过广告,或者广告展示一段时间过后进入微信小程序。并可以显示广告的剩余时间。效果图如下(背景图是网图,界面用了colorui组件库):点击“跳过广告”,会直接进入小程序,否则将等按钮上的倒计时结束后再进入小程序。一、页面设计这里使用了微信小程序中的,。后的内容为开屏界面的内容,后的内容为微信小程序首页的内容。wxml文件
@Param
是小傲雨呀^_^
mybatis java
简介:MyBatis中的@Param是一种用于标记方法参数的注解,主要用于指定参数的名称和类型,以便在MapperXML文件中引用该参数。注意:当Mapper方法有多个参数时,使用@Param注解是非常必要的。不使用@Param时,在MapperXML文件中只能通过位置来识别参数,而使用@Param则可以通过名称来访问基本用法单个参数:当方法只有一个参数时,可以直接使用@Param注解为
【云原生】SpringCloud-Spring Boot Starter使用测试
egekm_sefg
面试 学习路线 阿里巴巴 spring boot 云原生 spring cloud
目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现:?创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。?在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringB
【MyBatis】处理数据库字段名和Java实体类的属性名不一致的5种方法
卡文迪许的引力常量
MyBatis mybatis 数据库 java
在MyBatis中,数据库表中的字段名和实体类的属性名可能不一致,下面是常见的几种方法来处理这种不一致的命名规则。方法1:SQL别名AS在SELECT语句中设置列别名(这是一个基本的SQL特性)可以强行使之匹配。selectuser_idas"id",user_nameas"userName",hashed_passwordas"hashedPassword"fromsome_tablewhere
Python 抽象基类 ABC :从实践到优雅
python
今天我们来聊聊Python中的抽象基类(AbstractBaseClass,简称ABC)。虽然这个概念在Python中已经存在很久了,但在日常开发中,很多人可能用得并不多,或者用得不够优雅。让我们从一个实际场景开始:假设你正在开发一个文件处理系统,需要支持不同格式的文件读写,比如JSON、CSV、XML等。初始版本:简单但不够严谨我们先来看看最简单的实现方式:classFileHandler:de
使用UnstructuredXMLLoader加载和解析XML文件
bBADAS
xml 服务器 运维 python
在AI技术与文本解析领域中,解析XML文件是一项非常基础的任务。XML格式常用于数据交换,而在某些情况下,我们需要将XML中的内容转换为结构化的数据,以便于进一步处理。在这篇文章中,我将向大家介绍如何使用UnstructuredXMLLoader来加载和解析XML文件。1.技术背景介绍XML(可扩展标记语言)是一种标记语言,设计用于数据的存储和传输。由于其结构化和可读性强的特性,在网络和软件开发中
【MyBatis】@Results注解的使用
卡文迪许的引力常量
MyBatis mybatis
@Results注解详解在MyBatis中,@Results注解用于将数据库的字段和Java实体类的属性进行映射,特别是在字段名与属性名不一致的情况下。MyBatis默认会使用自动映射,但如果数据库字段使用snake_case(下划线命名法),而Java类使用camelCase(驼峰命名法),就可能需要手动指定映射关系。这时可以使用@Results注解。(或者也可以在配置文件中设置)1.@Resu
【SpringBoot3】Spring Boot 3.0 集成 Mybatis Plus
m0_74824661
面试 学习路线 阿里巴巴 spring boot mybatis 后端
文章目录一、什么是MybatisPlus特性二、SpringBoot3.0集成MybatisPlus三、MybatisPlus查询示例1、普通查询2、分页查询参考一、什么是MybatisPlusMyBatis-Plus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。特性无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
Java 开发中用于打印完整 SQL 语句的插件(嘎嘎有用)
一口酥Hac
java java sql 开发语言
文章目录背景MybatisLogFree插件使用背景在java开发中,sql日志常以问号(?)作为参数占位符,这使得调试时需要手动将问号替换为实际的参数值。对于参数较少的情况,手动替换相对简单;但当参数较多时,这一过程不仅繁琐,还容易出现错误。有对应的插件为我们解决了这个问题。MybatisLogFree插件一款IDEA插件,它能够自动将问号占位符替换为相应的参数值。打印出完整的sql语句。安装插
MyBatis-Plus结合Spring Boot实现数据权限
一、场景介绍在开发过程中很多时候我们需要根据某些条件去做数据权限,比如:A组织只能看见A组织及其下属组织的数据,B部门只能看见自己的数据、等等,此时如果每次都去自己写SQL进行校验就会显得代码非常臃肿,因为就产生了自己去定义一套全局公用的数据权限过滤方式。二、实现思路借助于Spring的拦截器或过滤器,当请求进入到Controller时,将该用户的数据权限信息存入数据权限上下文中,在MyBatis
技术分享:MyBatis SQL 日志解析脚本
£漫步 云端彡
运维趣分享 sql java mybatis 日志解析
技术分享:MyBatisSQL日志解析脚本1.脚本功能概述2.实现细节2.1HTML结构2.2JavaScript逻辑3.脚本代码4.使用方法4.1示例5.总结在日常开发中,使用MyBatis作为持久层框架时,我们经常需要查看SQL日志以调试和优化查询。然而,MyBatis的日志输出通常包含占位符和参数信息,这使得直接执行这些SQL语句变得困难。为了解决这个问题,我们开发了一个简单的HTML和Ja
Spring Bean 生命周期的执行流程
涛粒子
spring 数据库 java
1.Bean定义阶段在Spring应用启动时,会读取配置文件(如XML配置、Java注解配置等)或者扫描带有特定注解(如@Component、@Service、@Repository等)的类,将这些Bean的定义信息加载到Spring的BeanFactory或ApplicationContext中。这些定义信息包括Bean的类名、作用域、依赖关系等。2.Bean实例化阶段调用构造函数:Spring
Spring Bean 生命周期的执行流程
涛粒子
spring java 后端
1.Bean定义阶段解析配置元数据:Spring容器会读取配置信息,这些配置信息可以是XML文件、Java注解或者Java配置类。容器根据这些配置信息解析出Bean的定义,包括Bean的类名、作用域、依赖关系等。注册Bean定义:解析完成后,Spring会将Bean定义信息注册到BeanDefinitionRegistry中,BeanDefinitionRegistry是一个存储Bean定义的注册
@AllArgsConstructor等lombok注解不生效以及idea的plugins加载不出来的解决方案
CodeYello
Java idea maven java spring boot
@AllArgsConstructor等lombok注解不生效的特点:被这个注解修饰的类并没有被准备好的无参构造器、有参构造器(不是指没有相关的代码,而是没有这些功能)不生效原因:idea里没有配备或配备完全lombox在网上搜了很多解决方案,但有些只适合老版本的idea,还有些根本解决不了。在这里给出亲身解决的方案。解决方式:一开始我们需要在pom.xml里引入lombox的依赖(引入后别忘了刷
AJAX使用和固定格式
乐多_L
ajax 前端 javascript
ajax的全称AsynchronousJavaScriptandXML(异步JavaScript和XML)。ajax是一种创建交互式网页应用的网页开发技术。其中最核心的依赖是浏览器提供的XMLHttpRequest对象,是这个对象使得浏览器可以发出HTTP请求与接收HTTP响应。实现了在页面不刷新的情况下和服务器进行交互。方法描述newXMLHttpRequest()生成一个XMLHttpRequ
详细介绍:封装简易的 Axios 函数获取省份列表
还是鼠鼠
javascript vscode ajax 前端 前端框架
目录关键步骤:完整代码(html):代码解析:程序运行结果:本示例展示了如何通过封装一个简易的myAxios函数来模拟axios的功能,使用原生的XMLHttpRequest(XHR)对象来发起HTTP请求。我们将实现一个简单的功能,通过该封装函数从服务器获取省份列表数据,并在网页上显示这些省份。关键步骤:封装myAxios函数:myAxios函数接收一个配置对象(如请求的URL和方法),并返回一
快速提升网站收录率的10个步骤
百度网站快速收录
百度网站快速收录 百度快速收录 网站快速收录 百度收录 网站收录
快速提升网站收录率需要综合考虑多个方面,以下是10个具体步骤,旨在帮助网站更快地获得搜索引擎的收录:1.提交网站地图制作并提交XML站点地图:站点地图是一个包含网站所有页面链接的文件,有助于搜索引擎快速发现和抓取网站内容。通过提交站点地图给搜索引擎,可以显著提高网站的收录速度。2.保持内容更新定期发布高质量内容:搜索引擎喜欢更新频繁的网站,因此保持网站内容的定期更新是提高收录率的关键。确保内容原创
欧*雅WCS项目总结
十五001
项目归档 后端 java 程序人生
项目介绍使用系统APRISO下发任务与wcs交互,wcs包含与海康agv对接,以及APRISO不纳入管理的库位(包括线边库位、码头库位、暂存区库位、空栈板库位)。wcs的主要定位就是高度定制化贴合生产业务,可以说wcs成为了agv和APRISO之间的桥梁。APRISO下发任务时候,通过生成xml文件实现的,这时候wcs会监听该文件目录新建的xml文件来生成任务。刚开始部署后不到一周出现了监听失效问
深度学习之目标检测的常用标注工具
铭瑾熙
人工智能 机器学习 深度学习 深度学习 目标检测 目标跟踪
1LabelImgLabelImg是一款开源的图像标注工具,标签可用于分类和目标检测,它是用Python编写的,并使用Qt作为其图形界面,简单好用。注释以PASCALVOC格式保存为XML文件,这是ImageNet使用的格式。此外,它还支持COCO数据集格式。2labelmelabelme是一款开源的图像/视频标注工具,标签可用于目标检测、分割和分类。灵感是来自于MIT开源的一款标注工具Label
基本数据类型和引用类型的初始值
3213213333332132
java基础
package com.array;
/**
* @Description 测试初始值
* @author FuJianyong
* 2015-1-22上午10:31:53
*/
public class ArrayTest {
ArrayTest at;
String str;
byte bt;
short s;
int i;
long
摘抄笔记--《编写高质量代码:改善Java程序的151个建议》
白糖_
高质量代码
记得3年前刚到公司,同桌同事见我无事可做就借我看《编写高质量代码:改善Java程序的151个建议》这本书,当时看了几页没上心就没研究了。到上个月在公司偶然看到,于是乎又找来看看,我的天,真是非常多的干货,对于我这种静不下心的人真是帮助莫大呀。
看完整本书,也记了不少笔记
【备忘】Django 常用命令及最佳实践
dongwei_6688
django
注意:本文基于 Django 1.8.2 版本
生成数据库迁移脚本(python 脚本)
python manage.py makemigrations polls
说明:polls 是你的应用名字,运行该命令时需要根据你的应用名字进行调整
查看该次迁移需要执行的 SQL 语句(只查看语句,并不应用到数据库上):
python manage.p
阶乘算法之一N! 末尾有多少个零
周凡杨
java 算法 阶乘 面试 效率
&n
spring注入servlet
g21121
Spring注入
传统的配置方法是无法将bean或属性直接注入到servlet中的,配置代理servlet亦比较麻烦,这里其实有比较简单的方法,其实就是在servlet的init()方法中加入要注入的内容:
ServletContext application = getServletContext();
WebApplicationContext wac = WebApplicationContextUtil
Jenkins 命令行操作说明文档
510888780
centos
假设Jenkins的URL为http://22.11.140.38:9080/jenkins/
基本的格式为
java
基本的格式为
java -jar jenkins-cli.jar [-s JENKINS_URL] command [options][args]
下面具体介绍各个命令的作用及基本使用方法
1. &nb
UnicodeBlock检测中文用法
布衣凌宇
UnicodeBlock
/** * 判断输入的是汉字 */ public static boolean isChinese(char c) { Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
java下实现调用oracle的存储过程和函数
aijuans
java orale
1.创建表:STOCK_PRICES
2.插入测试数据:
3.建立一个返回游标:
PKG_PUB_UTILS
4.创建和存储过程:P_GET_PRICE
5.创建函数:
6.JAVA调用存储过程返回结果集
JDBCoracle10G_INVO
Velocity Toolbox
antlove
模板 tool box velocity
velocity.VelocityUtil
package velocity;
import org.apache.velocity.Template;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.c
JAVA正则表达式匹配基础
百合不是茶
java 正则表达式的匹配
正则表达式;提高程序的性能,简化代码,提高代码的可读性,简化对字符串的操作
正则表达式的用途;
字符串的匹配
字符串的分割
字符串的查找
字符串的替换
正则表达式的验证语法
[a] //[]表示这个字符只出现一次 ,[a] 表示a只出现一
是否使用EL表达式的配置
bijian1013
jsp web.xml EL EasyTemplate
今天在开发过程中发现一个细节问题,由于前端采用EasyTemplate模板方法实现数据展示,但老是不能正常显示出来。后来发现竟是EL将我的EasyTemplate的${...}解释执行了,导致我的模板不能正常展示后台数据。
网
精通Oracle10编程SQL(1-3)PLSQL基础
bijian1013
oracle 数据库 plsql
--只包含执行部分的PL/SQL块
--set serveroutput off
begin
dbms_output.put_line('Hello,everyone!');
end;
select * from emp;
--包含定义部分和执行部分的PL/SQL块
declare
v_ename varchar2(5);
begin
select
【Nginx三】Nginx作为反向代理服务器
bit1129
nginx
Nginx一个常用的功能是作为代理服务器。代理服务器通常完成如下的功能:
接受客户端请求
将请求转发给被代理的服务器
从被代理的服务器获得响应结果
把响应结果返回给客户端
实例
本文把Nginx配置成一个简单的代理服务器
对于静态的html和图片,直接从Nginx获取
对于动态的页面,例如JSP或者Servlet,Nginx则将请求转发给Res
Plugin execution not covered by lifecycle configuration: org.apache.maven.plugin
blackproof
maven 报错
转:http://stackoverflow.com/questions/6352208/how-to-solve-plugin-execution-not-covered-by-lifecycle-configuration-for-sprin
maven报错:
Plugin execution not covered by lifecycle configuration:
发布docker程序到marathon
ronin47
docker 发布应用
1 发布docker程序到marathon 1.1 搭建私有docker registry 1.1.1 安装docker regisry
docker pull docker-registry
docker run -t -p 5000:5000 docker-registry
下载docker镜像并发布到私有registry
docker pull consol/tomcat-8.0
java-57-用两个栈实现队列&&用两个队列实现一个栈
bylijinnan
java
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/*
* Q 57 用两个栈实现队列
*/
public class QueueImplementByTwoStacks {
private Stack<Integer> stack1;
pr
Nginx配置性能优化
cfyme
nginx
转载地址:http://blog.csdn.net/xifeijian/article/details/20956605
大多数的Nginx安装指南告诉你如下基础知识——通过apt-get安装,修改这里或那里的几行配置,好了,你已经有了一个Web服务器了。而且,在大多数情况下,一个常规安装的nginx对你的网站来说已经能很好地工作了。然而,如果你真的想挤压出Nginx的性能,你必
[JAVA图形图像]JAVA体系需要稳扎稳打,逐步推进图像图形处理技术
comsci
java
对图形图像进行精确处理,需要大量的数学工具,即使是从底层硬件模拟层开始设计,也离不开大量的数学工具包,因为我认为,JAVA语言体系在图形图像处理模块上面的研发工作,需要从开发一些基础的,类似实时数学函数构造器和解析器的软件包入手,而不是急于利用第三方代码工具来实现一个不严格的图形图像处理软件......
&nb
MonkeyRunner的使用
dai_lm
android MonkeyRunner
要使用MonkeyRunner,就要学习使用Python,哎
先抄一段官方doc里的代码
作用是启动一个程序(应该是启动程序默认的Activity),然后按MENU键,并截屏
# Imports the monkeyrunner modules used by this program
from com.android.monkeyrunner import MonkeyRun
Hadoop-- 海量文件的分布式计算处理方案
datamachine
mapreduce hadoop 分布式计算
csdn的一个关于hadoop的分布式处理方案,存档。
原帖:http://blog.csdn.net/calvinxiu/article/details/1506112。
Hadoop 是Google MapReduce的一个Java实现。MapReduce是一种简化的分布式编程模式,让程序自动分布到一个由普通机器组成的超大集群上并发执行。就如同ja
以資料庫驗證登入
dcj3sjt126com
yii
以資料庫驗證登入
由於 Yii 內定的原始框架程式, 採用綁定在UserIdentity.php 的 demo 與 admin 帳號密碼: public function authenticate() { $users=array( &nbs
github做webhooks:[2]php版本自动触发更新
dcj3sjt126com
github git webhooks
上次已经说过了如何在github控制面板做查看url的返回信息了。这次就到了直接贴钩子代码的时候了。
工具/原料
git
github
方法/步骤
在github的setting里面的webhooks里把我们的url地址填进去。
钩子更新的代码如下: error_reportin
Eos开发常用表达式
蕃薯耀
Eos开发 Eos入门 Eos开发常用表达式
Eos开发常用表达式
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
蕃薯耀 2014年8月18日 15:03:35 星期一
&
SpringSecurity3.X--SpEL 表达式
hanqunfeng
SpringSecurity
使用 Spring 表达式语言配置访问控制,要实现这一功能的直接方式是在<http>配置元素上添加 use-expressions 属性:
<http auto-config="true" use-expressions="true">
这样就会在投票器中自动增加一个投票器:org.springframework
Redis vs Memcache
IXHONG
redis
1. Redis中,并不是所有的数据都一直存储在内存中的,这是和Memcached相比一个最大的区别。
2. Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。
3. Redis支持数据的备份,即master-slave模式的数据备份。
4. Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
Red
Python - 装饰器使用过程中的误区解读
kvhur
JavaScript jquery html5 css
大家都知道装饰器是一个很著名的设计模式,经常被用于AOP(面向切面编程)的场景,较为经典的有插入日志,性能测试,事务处理,Web权限校验, Cache等。
原文链接:http://www.gbtags.com/gb/share/5563.htm
Python语言本身提供了装饰器语法(@),典型的装饰器实现如下:
@function_wrapper
de
架构师之mybatis-----update 带case when 针对多种情况更新
nannan408
case when
1.前言.
如题.
2. 代码.
<update id="batchUpdate" parameterType="java.util.List">
<foreach collection="list" item="list" index=&
Algorithm算法视频教程
栏目记者
Algorithm 算法
课程:Algorithm算法视频教程
百度网盘下载地址: http://pan.baidu.com/s/1qWFjjQW 密码: 2mji
程序写的好不好,还得看算法屌不屌!Algorithm算法博大精深。
一、课程内容:
课时1、算法的基本概念 + Sequential search
课时2、Binary search
课时3、Hash table
课时4、Algor
C语言算法之冒泡排序
qiufeihu
c 算法
任意输入10个数字由小到大进行排序。
代码:
#include <stdio.h>
int main()
{
int i,j,t,a[11]; /*定义变量及数组为基本类型*/
for(i = 1;i < 11;i++){
scanf("%d",&a[i]); /*从键盘中输入10个数*/
}
for
JSP异常处理
wyzuomumu
Web jsp
1.在可能发生异常的网页中通过指令将HTTP请求转发给另一个专门处理异常的网页中:
<%@ page errorPage="errors.jsp"%>
2.在处理异常的网页中做如下声明:
errors.jsp:
<%@ page isErrorPage="true"%>,这样设置完后就可以在网页中直接访问exc