获取mybatis可执行sql

我是通过spring和mybatis结合做的这个事情,通过spring去管理SqlHelper工具类

1:建立一个SqlHelper工具类,

2:类里面必须有一个属性SqlSessionFactory。

3:在你业务类里面,直接注入SqlHelper类,这样你就可以直接在你的业务类里面调用工具类,(工具类里面有好几个接口,自己可以根据实际情况适用)

4:在代码的最后我会贴一部分实例代码来给出结果

5:不多说了,下面贴SqlHelper工具类代码

package com.heygam.common.util;

import java.lang.reflect.Method;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import org.apache.ibatis.annotations.Param;

import org.apache.ibatis.mapping.BoundSql;

import org.apache.ibatis.mapping.MappedStatement;

import org.apache.ibatis.mapping.ParameterMapping;

import org.apache.ibatis.mapping.ParameterMode;

import org.apache.ibatis.reflection.MetaObject;

import org.apache.ibatis.reflection.factory.DefaultObjectFactory;

import org.apache.ibatis.reflection.factory.ObjectFactory;

import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;

import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;

import org.apache.ibatis.session.Configuration;

import org.apache.ibatis.session.ResultHandler;

import org.apache.ibatis.session.RowBounds;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.type.JdbcType;

import org.apache.ibatis.type.TypeHandlerRegistry;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

@Component

public class SqlHelper {

@Autowired

private  SqlSessionFactory sqlSessionFactory;

private  final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();

private  final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();

/**

* 反射对象,增加对低版本Mybatis的支持

*

* @param object 反射对象

* @return

*/

public  MetaObject forObject(Object object) {

return MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);

}

/**

* 通过接口获取sql

*

* @param mapper

* @param methodName

* @param args

* @return

*/

public  String getMapperSql(Object mapper, String methodName, Object... args) {

MetaObject metaObject = forObject(mapper);

SqlSession session = (SqlSession) metaObject.getValue("h.sqlSession");

Class mapperInterface = (Class) metaObject.getValue("h.mapperInterface");

String fullMethodName = mapperInterface.getCanonicalName() + "." + methodName;

if (args == null || args.length == 0) {

return getNamespaceSql(fullMethodName, null);

} else {

return getMapperSql(mapperInterface, methodName, args);

}

}

/**

* 通过Mapper方法名获取sql

*

* @param session

* @param fullMapperMethodName

* @param args

* @return

*/

public  String getMapperSql(String fullMapperMethodName, Object... args) {

if (args == null || args.length == 0) {

return getNamespaceSql(fullMapperMethodName, null);

}

String methodName = fullMapperMethodName.substring(fullMapperMethodName.lastIndexOf(‘.‘) + 1);

Class mapperInterface = null;

try {

mapperInterface = Class.forName(fullMapperMethodName.substring(0, fullMapperMethodName.lastIndexOf(‘.‘)));

return getMapperSql(mapperInterface, methodName, args);

} catch (ClassNotFoundException e) {

throw new IllegalArgumentException("参数" + fullMapperMethodName + "无效!");

}

}

/**

* 通过Mapper接口和方法名

*

* @param session

* @param mapperInterface

* @param methodName

* @param args

* @return

*/

public  String getMapperSql(Class mapperInterface, String methodName, Object... args) {

String fullMapperMethodName = mapperInterface.getCanonicalName() + "." + methodName;

if (args == null || args.length == 0) {

return getNamespaceSql(fullMapperMethodName, null);

}

Method method = getDeclaredMethods(mapperInterface, methodName);

Map params = new HashMap();

final Class<?>[] argTypes = method.getParameterTypes();

for (int i = 0; i < argTypes.length; i++) {

if (!RowBounds.class.isAssignableFrom(argTypes[i]) && !ResultHandler.class.isAssignableFrom(argTypes[i])) {

String paramName = "param" + String.valueOf(params.size() + 1);

paramName = getParamNameFromAnnotation(method, i, paramName);

params.put(paramName, i >= args.length ? null : args[i]);

}

}

if (args != null && args.length == 1) {

Object _params = wrapCollection(args[0]);

if (_params instanceof Map) {

params.putAll((Map) _params);

}

}

return getNamespaceSql(fullMapperMethodName, params);

}

/**

* 通过命名空间方式获取sql

*

* @param session

* @param namespace

* @return

*/

public  String getNamespaceSql(SqlSession session, String namespace) {

return getNamespaceSql(namespace, null);

}

/**

* 通过命名空间方式获取sql

*

* @param session

* @param namespace

* @param params

* @return

*/

public  String getNamespaceSql(String namespace, Object params) {

params = wrapCollection(params);

Configuration configuration = sqlSessionFactory.openSession().getConfiguration();

MappedStatement mappedStatement = configuration.getMappedStatement(namespace);

TypeHandlerRegistry typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();

BoundSql boundSql = mappedStatement.getBoundSql(params);

List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();

String sql = boundSql.getSql();

if (parameterMappings != null) {

for (int i = 0; i < parameterMappings.size(); i++) {

ParameterMapping parameterMapping = parameterMappings.get(i);

if (parameterMapping.getMode() != ParameterMode.OUT) {

Object value;

String propertyName = parameterMapping.getProperty();

if (boundSql.hasAdditionalParameter(propertyName)) {

value = boundSql.getAdditionalParameter(propertyName);

} else if (params == null) {

value = null;

} else if (typeHandlerRegistry.hasTypeHandler(params.getClass())) {

value = params;

} else {

MetaObject metaObject = configuration.newMetaObject(params);

value = metaObject.getValue(propertyName);

}

JdbcType jdbcType = parameterMapping.getJdbcType();

if (value == null && jdbcType == null)

jdbcType = configuration.getJdbcTypeForNull();

sql = replaceParameter(sql, value, jdbcType, parameterMapping.getJavaType());

}

}

}

return sql;

}

/**

* 根据类型替换参数

* 仅作为数字和字符串两种类型进行处理,需要特殊处理的可以继续完善这里

*

* @param sql

* @param value

* @param jdbcType

* @param javaType

* @return

*/

private  String replaceParameter(String sql, Object value, JdbcType jdbcType, Class javaType) {

String strValue = String.valueOf(value);

if (jdbcType != null) {

switch (jdbcType) {

// 数字

case BIT:

case TINYINT:

case SMALLINT:

case INTEGER:

case BIGINT:

case FLOAT:

case REAL:

case DOUBLE:

case NUMERIC:

case DECIMAL:

break;

// 日期

case DATE:

case TIME:

case TIMESTAMP:

// 其他,包含字符串和其他特殊类型

default:

strValue = "‘" + strValue + "‘";

}

} else if (Number.class.isAssignableFrom(javaType)) {

// 不加单引号

} else {

strValue = "‘" + strValue + "‘";

}

return sql.replaceFirst("\\?", strValue);

}

/**

* 获取指定的方法

*

* @param clazz

* @param methodName

* @return

*/

private  Method getDeclaredMethods(Class clazz, String methodName) {

Method[] methods = clazz.getDeclaredMethods();

for (Method method : methods) {

if (method.getName().equals(methodName)) {

return method;

}

}

throw new IllegalArgumentException("方法" + methodName + "不存在!");

}

/**

* 获取参数注解名

*

* @param method

* @param i

* @param paramName

* @return

*/

private  String getParamNameFromAnnotation(Method method, int i, String paramName) {

final Object[] paramAnnos = method.getParameterAnnotations()[i];

for (Object paramAnno : paramAnnos) {

if (paramAnno instanceof Param) {

paramName = ((Param) paramAnno).value();

}

}

return paramName;

}

/**

* 简单包装参数

*

* @param object

* @return

*/

private  Object wrapCollection(final Object object) {

if (object instanceof List) {

Map<String, Object> map = new HashMap<String, Object>();

map.put("list", object);

return map;

} else if (object != null && object.getClass().isArray()) {

Map<String, Object> map = new HashMap<String, Object>();

map.put("array", object);

return map;

}

return object;

}

public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {

this.sqlSessionFactory = sqlSessionFactory;

}

}

注:下面的是示例代码  (必须在类中注入了SqlHelper才能使用)

String sql = sqlHelper.getNamespaceSql("com.heygam.business.dao.UserMapper.selectUserByUserName", userName);

log.debug("================通过sql辅助工具拿到的sql=====================");

log.debug(sql);

log.debug("================通过sql辅助工具拿到的sql=====================");

打印的结果:

================通过sql辅助工具拿到的sql=====================

2014-12-26 16:05:42.183 [queue-disruptor-0-1] DEBUG com.heygam.business.service.UserService-select * from p_user where userName=‘15647‘ and   isBan != 1

2014-12-26 16:05:42.183 [queue-disruptor-0-1] DEBUG com.heygam.business.service.UserService-

================通过sql辅助工具拿到的sql=====================

时间: 2024-10-10 07:46:52

获取mybatis可执行sql的相关文章

MyBatis直接执行SQL的工具SqlMapper

可能有些人也有过类似需求,一般都会选择使用其他的方式如Spring-JDBC等方式解决. 能否通过MyBatis实现这样的功能呢? 为了让通用Mapper更彻底的支持多表操作以及更灵活的操作,在2.2.0版本增加了一个可以直接执行SQL的新类SqlMapper. 通过这篇博客,我们来了解一下SqlMapper. SqlMapper提供的方法 SqlMapper提供了以下这些公共方法: Map<String,Object> selectOne(String sql) Map<String,

MyBatis直接执行SQL查询及批量插入数据

MyBatis直接执行SQL查询及批量插入数据 一.直接执行SQL查询: 1.mappers文件节选 <resultMap id="AcModelResultMap" type="com.izumi.InstanceModel">  <result column="instanceid" property="instanceID" jdbcType="VARCHAR" />  <

MyBatis直接执行sql语句mapper

<select id="queryBySql" resultType="HashMap"> <![CDATA[ ${sql} ]]> </select> <![CDATA[]]>这个标记所包含的内容将表示为纯文本 原文地址:https://www.cnblogs.com/jagng951014/p/9462591.html

在mybatis执行SQL语句之前进行拦击处理

比较适用于在分页时候进行拦截.对分页的SQL语句通过封装处理,处理成不同的分页sql. 实用性比较强. import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Properties; import org.apache.ibatis.e

Mbatis的直接执行SQL

mybatis直接执行SQL实际就是在mapper里面加个String mapper.xml <select id="selectBySql" parameterType="String"> ${value} </select> 对于同结构的表可以统一处理 <insert id="insertTraject" parameterType="com.piccapp.dto.entity.TrajectoryD

Mybatis之拦截器--获取执行SQL实现多客户端数据同步

最近的一个项目是将J2EE环境打包安装在客户端(使用 nwjs + NSIS 制作安装包)运行, 所有的业务操作在客户端完成, 数据存储在客户端数据库中. 服务器端数据库汇总各客户端的数据进行分析. 其中客户端ORM使用Mybatis. 通过Mybatis拦截器获取所有在执行的SQL语句, 定期同步至服务器. 本文通过在客户端拦截SQL的操作介绍Mybatis拦截器的使用方法. 1. 项目需求 客户分店较多且比较分散, 部分店内网络不稳定, 客户要求每个分店在无网络的情况下也能正常使用系统, 同

mybatis 学习四 源码分析 mybatis如何执行的一条sql

总体三部分,创建sessionfactory,创建session,执行sql获取结果 1,创建sessionfactory 这里其实主要做的事情就是将xml的所有配置信息转换成一个Configuration对象,然后用这个对象组装成factory返回. //mybatis配置文件 String resource = "conf.xml"; InputStream is = TestMybatis.class.getClassLoader().getResourceAsStream(re

灵动标签的用法 ecms通过执行sql获取需要的记录

1引言 你点击了桌面上的Chrome图标,一个浏览器窗口出现了,输入网址就可以在Internet世界愉快玩耍.这一切是怎么实现的呢?Chromium这个多进程的程序是如何启动各个进程的呢?浏览器主进程(界面进程)启动了哪些线程?如何启动的呢?这些问题一直萦绕在心头,一起来看看源代码吧.本文主要针对Chromium for Mac的源代码,其它操作系统大同小异. 2背景知识 浏览器作为一个应用程序,是以进程的形式运行在操作系统上的.首先,Chromium是一个多进程的应用程序,我们需要了解Chro

Mybatis之执行自定义SQL举例

本文说明如何使用Mybatis执行我自定义输入的SQL语句. 需要的mybaits文件包括:配置文件(mybatis-config-dao.xml 和 jdbc.properties).接口文件(ISqlMapper.class).xml文件 (sqlMapper.xml).工具类(MybatisUtils.class). 依赖包: 1 <dependency> 2 <groupId>org.mybatis</groupId> 3 <artifactId>m