p6使用教程_pwdump7使用

p6使用教程_pwdump7使用hibernate打印sql

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

     在之前的hibernate的总结中,遇到一个小问题,那就是打印sql语句的问题.在上个hibernate项目的基础上(spring+hibernate),继续p6spy的学习(p6spy相关文件下载)

hibernate控制sql语句的参数配置:

				<!--开发调试使用 -->
				<!--控制台打印sql语句 -->
				<prop key="hibernate.show_sql">false</prop>
				<!--格式化语句 -->
				<prop key="hibernate.format_sql">false</prop>
				<!--如果开启, Hibernate将在SQL中生成有助于调试的注释信息, 默认值为false -->
				<prop key="hibernate.use_sql_comments">false</prop>

      但是这样有个问题,那就是hibernate中打印的参数都是一些?,实际上hibernate打印都是一些预编译的sql,无法打印真正的sql.回顾一些jdbc(java使用连接数据的api,
Java DataBase Connectivity)直连数据库

		Connection conn = null;
		try {
			// 第一步,注册驱动程序 以mysql驱动为例
			Class.forName("com.mysql.jdbc.Driver");
			// 第二步,获取一个数据库的连接
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123");
			conn.setAutoCommit(false);
			
			
			// 第三步,创建一个会话
			//Statement stmt = conn.createStatement();	
			String sql = "select * from school s where s.id=?";
			PreparedStatement stmt = conn.prepareStatement(sql);
			stmt.setInt(1, 1);
			
			
			// 第四步,执行SQL语句,增加,删除,修改记录 或者查询记录
			// stmt.executeUpdate();
			ResultSet rs = stmt.executeQuery();
			ResultSetMetaData m = rs.getMetaData();

			// 第五步,对查询的结果进行处理
			int columns = m.getColumnCount();
			// 显示列,表格的表头
			for (int i = 1; i <= columns; i++) {
				System.out.print(m.getColumnName(i));
				System.out.print("\t\t");
			}
			System.out.println();
			// 显示表格内容
			while (rs.next()) {
				for (int i = 1; i <= columns; i++) {
					System.out.print(rs.getString(i));
					System.out.print("\t\t");
				}
				System.out.println();
			}
			// 第六步,关闭连接
			conn.commit();
			rs.close();
			stmt.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("进行回滚操作");
			conn.rollback();
		} finally {
			conn.close();
		}
	

       而我们通常配置的数据库驱动实现了与数据库的交互的前提,数据库连接池如druid,dbcp,c3p0,jboss datasource,bonecp,proxool等则管理通数据具体操作的连接connection,

通过一个个connection完成对具体数据的操作.

      从上例中可知,使用connection进行操作时摒弃了statement,而使用PreparedStatement,statement采用硬编码,每次执行sql都会进行编译,效率低,同时还能带来sql注入等不安全因素,而PreparedStatement相当于动态sql,对于相同的sql只会编译一次,参数通过注入的方式,有效阻止的sql注入,因此,项目中大多时候选择的是PreparedStatement,但对于那些一次性操作的,比如批量插入,删除等,可以直接使用statement.

hibernate默认使用的PreparedStatement,其取格式的sql是预编译的sql(参数没有被完全注入进来),从而会有一系列的?,要显示思路一种就是改变取sql的时机,等参数全部注入完成再取(p6spy),一种就是利用log,将传入的参数打印出来(这样sql,与参数分离),显然后一种没有前一种方便(hibernate打印sql)

p6spy使用com.p6spy.engine.spy.P6SpyDriver作为数据库驱动,P6SpyDriver是对原生原生驱动(此处以com.mysql.jdbc.Driver为例)的封装,其对数据的操作还是调用原生驱动的方法,只是多了sql监控的功能.

paspy基本使用.

配置驱动

		<!--设置数据库连接 -->
		<property name="driverClass" value="com.p6spy.engine.spy.P6SpyDriver" />

数据库连接(多了一个p6spy):

db.jdbcUrl  = jdbc:p6spy:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true

spy.propertie

#配置输出方式
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
#appender=com.p6spy.engine.spy.appender.FileLogger
appender=com.p6spy.engine.spy.appender.StdoutLogger

#配置输出内容格式(此处自定义)
#默认 com.p6spy.engine.spy.appender.SingleLineFormat
logMessageFormat=spring.redis.test.util.MySingleLineFormat

#输出内容选择
#list of categories to exclude: error, info, batch, debug, statement,
#commit, rollback and result are valid values
# (default is info,debug,result,resultset,batch)
excludecategories=info,batch,debug,commit,rollback,result,resultset

此处为了测试方便,使用控制台打印,自定义输出格式,输出内容选择statement

自定义输出内容格式:

package spring.redis.test.util;

import org.hibernate.engine.jdbc.internal.BasicFormatterImpl;

import com.p6spy.engine.spy.appender.SingleLineFormat;

public class MySingleLineFormat extends SingleLineFormat {
	private final static BasicFormatterImpl sqlformat = new BasicFormatterImpl();
	  /**
	   * Formats a log message for the logging module
	   *
	   * @param connectionId the id of the connection
	   * @param now          the current ime expressing in milliseconds
	   * @param elapsed      the time in milliseconds that the operation took to complete
	   * @param category     the category of the operation
	   * @param prepared     the SQL statement with all bind variables replaced with actual values
	   * @param sql          the sql statement executed
	   * @return the formatted log message
	   */
	  @Override
	  public String formatMessage(final int connectionId, final String now, final long elapsed, final String category, final String prepared, final String sql) {
	   return "#token time:" + elapsed + "ms | category:" + category + " | connectionId: " + connectionId + "\n" + "预编译语句"+sqlformat.format(prepared) + "\nread sql" + sqlformat.format(sql)
	  }
}

这是使用了hibernate格式化类,BasicFormatterImpl,以上展示的参数都是可以展示,测试打印

		//执行打印sql
		hibernateTemplate.get(School.class, 1);
/*		#token time:3ms | category:statement | connectionId: 2
		预编译语句
		    select
		        school0_.id as id1_1_0_,
		        school0_.create_time as create_t2_1_0_,
		        school0_.des as des3_1_0_,
		        school0_.name as name4_1_0_,
		        school0_.update_time as update_t5_1_0_ 
		    from
		        school school0_ 
		    where
		        school0_.id=?
		read sql
		    select
		        school0_.id as id1_1_0_,
		        school0_.create_time as create_t2_1_0_,
		        school0_.des as des3_1_0_,
		        school0_.name as name4_1_0_,
		        school0_.update_time as update_t5_1_0_ 
		    from
		        school school0_ 
		    where
		        school0_.id=1*/
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/185430.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 极具参考价值的Python面试题!从创业公司到一线大厂的所有面经汇总

    极具参考价值的Python面试题!从创业公司到一线大厂的所有面经汇总全网极具参考价值的Python面试题,从创业公司到一线大厂的面经汇总整理。作者会持续维护更新!

    2022年5月31日
    37
  • sql2012安装错误代码0x84b10001_sql2008配置系统未能初始化

    sql2012安装错误代码0x84b10001_sql2008配置系统未能初始化【错误描述】Sql2008安装启动失败,弹出 配置系统未能初始化0x84B10001【解决方法】先安装sql2008sp3补丁.然后再安装Sql2008,最后再装一次sp3补丁.

    2022年9月11日
    0
  • 傅里叶变换公式「建议收藏」

    傅里叶变换公式「建议收藏」傅里叶变换的目的:有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了。1、FS:(Fourierseries)连续时间周期信号的傅里叶级数,时域上任意连续的周期信号可以分解为无限多个正弦信号之和,在频域上表示为离散非周期的信号,即时域连续周期对应频域离散非周期的特点。时域上连续周期函数,采用FS(傅里叶级数)分解为频域上为非周期、连…

    2022年7月17日
    8
  • Mask Rcnn目标分割-训练自己数据集-详细步骤[通俗易懂]

    Mask Rcnn目标分割-训练自己数据集-详细步骤[通俗易懂]本文接着介绍了MaskRcnn目标分割算法如何训练自己数据集,对训练所需的文件以及训练代码进行详细的说明。本文详细介绍在只有样本图片数据时,如果建立MaskRcnn目标分割训练数据集的步骤。过程中用到的所有代码均已提供。

    2022年10月4日
    0
  • G1 收集器介绍「建议收藏」

    G1 收集器介绍「建议收藏」G1收集器一.名词解释MetaSpace在Java8之后取代永久代方法区的内存部分,NativeMemoryMixedGCEvent所有YoungRegion和一部分OldRegion的混合GC时间。ReclaimableG1为了能够回收,创建了一系列专门用于对象回收的Region,存放在链表中,只包含存活率小于-XX:G1MixedGCLIveThr…

    2022年6月7日
    46
  • 8大轻型网管工具,网络管理好帮手「建议收藏」

    8大轻型网管工具,网络管理好帮手「建议收藏」  从设备发现到系统、网络和流量可视性,这些轻型的网管工具非常实用。在网络和服务器世界,重点是可视性、可视性、可视性,如果你不知道你的网络和服务器在每天每秒正在做什么,你很可能会出问题。幸运的是,这里有很多好工具(商业和开源工具)来帮助你满足需求。  在本文中我们提供了一些很好用的网管工具,这些工具适合各种规模的网络。从网络和服务器监控到趋势、图形,甚至是交换和路由器配置备份,这些工具都可以帮…

    2022年10月6日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号