public class MyBatisSqlUtils
{
/**
* 运行期获取MyBatis执行的SQL及参数
* @param id Mapper xml 文件里的select Id
* @param parameterMap 参数
* @param sqlSessionFactory
* @return
*/
public static MyBatisSql getMyBatisSql(String id, Map<String,Object> parameterMap,SqlSessionFactory sqlSessionFactory) {
MyBatisSql ibatisSql = new MyBatisSql();
MappedStatement ms = sqlSessionFactory.getConfiguration().getMappedStatement(id);
BoundSql boundSql = ms.getBoundSql(parameterMap);
ibatisSql.setSql(boundSql.getSql());
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
if (parameterMappings != null)
{
Object[] parameterArray = new Object[parameterMappings.size()];
ParameterMapping parameterMapping = null;
Object value = null;
Object parameterObject = null;
MetaObject metaObject = null;
PropertyTokenizer prop = null;
String propertyName = null;
String[] names = null;
for (int i = 0; i < parameterMappings.size(); i++)
{
parameterMapping = parameterMappings.get(i);
if (parameterMapping.getMode() != ParameterMode.OUT)
{
propertyName = parameterMapping.getProperty();
names = propertyName.split("\\.");
if(propertyName.indexOf(".") != -1 && names.length == 2)
{
parameterObject = parameterMap.get(names[0]);
propertyName = names[1];
}
else if(propertyName.indexOf(".") != -1 && names.length == 3)
{
parameterObject = parameterMap.get(names[0]); // map
if(parameterObject instanceof Map)
{
parameterObject = ((Map)parameterObject).get(names[1]);
}
propertyName = names[2];
}
else
{
parameterObject = parameterMap.get(propertyName);
}
metaObject = parameterMap == null ? null : MetaObject.forObject(parameterObject);
prop = new PropertyTokenizer(propertyName);
if (parameterObject == null)
{
value = null;
}
else if (ms.getConfiguration().getTypeHandlerRegistry().hasTypeHandler(parameterObject.getClass()))
{
value = parameterObject;
}
else if (boundSql.hasAdditionalParameter(propertyName))
{
value = boundSql.getAdditionalParameter(propertyName);
}
else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX) && boundSql.hasAdditionalParameter(prop.getName()))
{
value = boundSql.getAdditionalParameter(prop.getName());
if (value != null)
{
value = MetaObject.forObject(value).getValue(propertyName.substring(prop.getName().length()));
}
}
else
{
value = metaObject == null ? null : metaObject.getValue(propertyName);
}
parameterArray[i] = value;
}
}
ibatisSql.setParameters(parameterArray);
}
return ibatisSql;
}
public class MyBatisSql
{
/**
* 运行期 sql
*/
private String sql;
/**
* 参数 数组
*/
private Object[] parameters;
public void setSql(String sql) {
this.sql = sql;
}
public String getSql() {
return sql;
}
public void setParameters(Object[] parameters) {
this.parameters = parameters;
}
public Object[] getParameters() {
return parameters;
}
@Override
public String toString() {
if(parameters == null || sql == null)
{
return "";
}
List<Object> parametersArray = Arrays.asList(parameters);
List<Object> list = new ArrayList<Object>(parametersArray);
while(sql.indexOf("?") != -1 && list.size() > 0 && parameters.length > 0)
{
sql = sql.replaceFirst("\\?", list.get(0).toString());
list.remove(0);
}
return sql.replaceAll("(\r?\n(\\s*\r?\n)+)", "\r\n");
}
以上贴的是实现代码,下面贴一段代码演示一下如何使用:
一、Mapper 文件
public interface AlarmMapper {
public List<Alarm> queryAlarmData(@Param(value = "filter") Filter filter,
@Param(value = "alarmStatus") AlarmStatus alarmStatus,
@Param(value = "startDate") Date startDate,
@Param(value = "endDate") Date endDate,
@Param(value = "regionId") String regionId,
@Param(value = "paramter") Map<String, Object> paramter,
@Param(value = "startRow") int startRow,
@Param(value = "endRow") int endRow) throws SQLException;
}
二、Mapper 的xml文件此处就不写了,select 的ID 为 queryAlarmData
三、在service层调用 queryAlarmData方法
public List<Alarm> queryAlarmData(Filter filter, AlarmStatus alarmStatus,
Date start, Date end, String regionId, Map<String, Object> paramter,int startRow, int endRow) {
try {
List<Alarm> alarms = mapper.queryAlarmData(filter,
alarmStatus, start, end, regionId,paramter, startRow, endRow);
Map<String,Object> parameterMap = new HashMap<String,Object>(); //存储参数
// key 要与Mapper中的参数名一致
parameterMap.put("filter", filter);
parameterMap.put("alarmStatus", alarmStatus);
parameterMap.put("startDate", start);
parameterMap.put("endDate", end);
parameterMap.put("regionId", regionId);
parameterMap.put("paramter", paramter);
parameterMap.put("startRow", startRow);
parameterMap.put("endRow", endRow);
logger.info(MyBatisSqlUtils.getMyBatisSql("queryAlarmData", parameterMap, sqlSessionFactory).toString());
return alarms;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
四、其实还可以用log4j来实现,将在下一篇博客贴出具体的实现代码(利用Spring的Aop以及自定义注解,实现系统日志功能)
五、欢迎各位指出本文的不妥之处,欢迎拍砖
分享到:
相关推荐
8. **cglib**:Code Generation Library,是一个强大的高性能的代码生成库,用于在运行期扩展Java类与实现Java接口。MyBatis使用CGLib创建代理对象,以实现对Mapper接口的方法调用。 9. **ant**:Apache Ant是一个...
MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。 标题中...
在执行SQL时,MyBatis支持多种参数映射方式,如简单类型、Map、POJO对象等。使用`@Param`注解可以为参数命名,避免参数顺序错误。 6. **结果映射** 结果映射用于将查询结果转换为Java对象。它可以自动处理一对一...
通过CGLIB创建目标对象的代理,当调用关联属性时,代理对象会检查该属性是否已加载,若未加载则执行SQL获取关联数据。 **与Hibernate的差异**: MyBatis和Hibernate的主要区别在于,Hibernate提供更全面的自动化ORM...
- 为了提供稳定和高效的运行环境,MyBatis包含了几个关键的支撑机制: - **事务管理**:控制数据库事务的开始、提交和回滚。 - **连接池管理**:通过连接池提高数据库连接的复用性,减少创建和关闭连接的开销。 ...
6. **cglib-3.2.4.jar**:CGlib是一个强大的、高性能的代码生成库,用于在运行期扩展Java类与实现Java接口。在MyBatis中,CGlib用于为没有接口的类创建代理,以便于实现MyBatis的动态SQL。 7. **ognl-3.1.12.jar**...
MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。在多数据源环境中,MyBatis可以帮助开发者更加灵活地处理数据库交互。 **多数据源** 多数据源是指在一个应用中同时连接和操作多个不同的数据库。...
这时,Spring会检查是否有缓存策略存在,如果有且数据还在有效期内,直接从Redis中获取;否则,通过MyBatis查询数据库,将结果存储到Redis,并返回给客户端。后续相同请求可以直接从Redis缓存中获取数据,提升响应...
首先,MyBatis Generator (MBG) 是基于Java的,它通过读取数据库元数据,根据用户定义的模板生成MyBatis所需的SQL映射文件(Mapper XML)、Mapper接口和实体类(Entity)。这样,开发者无需手动编写这些基础代码,...
此版本改进了动态SQL的执行效率,增强了对Java 8日期时间API的支持,以及对XML配置和注解的增强。MyBatis 3.4在保持简洁的同时,提升了整体的使用体验和灵活性。 “mysql”代表MySQL数据库,这是一个流行的开源关系...
在本系统中,MyBatis作为数据库操作的接口,允许开发者直接编写SQL,从而提高了查询效率和灵活性,同时减少了因为ORM工具产生的性能损耗。 结合MySQL数据库,我们能有效地存储和管理电信渠道营销支撑系统中的大量...
而CGLIB(Code Generation Library)是在运行期通过字节码技术动态生成子类来实现代理,即使目标对象没有实现接口也能进行代理。CGLIB在Spring框架中被广泛用于那些没有实现接口的类的代理。 Spring整合Mybatis是另...
通过配置Ehcache,我们可以设置缓存策略,如缓存有效期、大小限制等,确保系统的高效运行。 最后,ExtJS是一个强大的JavaScript前端框架,主要用于构建富客户端应用。它提供了一系列组件,如表格、表单、图表等,...
- MyBatis 3.11版本则优化了SQL解析,增加了对Java 8日期时间API的支持,以及更丰富的日志功能。 通过提供的"jar包",开发者可以直接在MyEclipse这样的集成开发环境中导入,快速搭建SSM项目,省去了手动下载和配置...
MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。在本系统...
MyBatis 3.2引入了动态SQL、缓存优化和更好的错误消息,使得开发更加高效且易于调试。 **Spring Security 3.2** Spring Security是Spring生态系统中的安全组件,它提供了一套全面的认证和授权解决方案。Spring ...
CGLIB是一个强大的高性能的代码生成库,它在许多AOP框架中都得到了广泛应用,包括Spring AOP,它可以在运行期扩展Java类与实现Java接口。 CGLIB通过生成子类的方式实现对目标类的代理,而Javassist则可以直接修改...
试题解析:MyBatis 不会在运行期自动生成大量的 SQL 语句。MyBatis 的特点是将 SQL 语句封装在配置文件中,便于统一管理与维护,降低了程序的耦合度。 Spring 3. Spring 中的 @Autowired 和 @Resource 正确的是...
【标题】"ch10_User_MyBatis.rar"是一个关于大三学生期末课程设计的项目,主要涉及用户管理系统。这个系统是用Java语言开发的,前端使用JSP(JavaServer Pages),后端数据库选用MySQL,整个开发环境可能基于...
Mybatis-Plus是Mybatis的增强工具,简化了常见的CRUD操作,如插入、更新、删除等,同时也提供了分页查询、动态SQL等功能,极大地提高了开发效率。在本系统中,Mybatis-Plus作为数据访问层,负责与数据库进行交互,...