项目打印出每句sql,有利于我们维护项目,出现bug时能够及时的找到原因,因此sql的打印和慢sql的监控相当重要。
springboot默认使用的数据源是HikariCP,它的速度较快,但是并不提供监控。我们使用p6spy来进行sql的打印。为方便演示使用H2内嵌式数据库+Jpa,为了便于开发使用lombok提供快捷的注解。
在https://start.spring.io/上选择自己需要的依赖,便可生成一个zip包。我选择的是maven项目,zip解压之后直接使用idea打开就可以开发了
pom.xml文件中需要添加p6spy的依赖`
p6spy
p6spy
3.8.1
source文件夹下添加spy.properties配置文件提供p6spy的相关配置
# 单行日志
logMessageFormat=com.p6spy.engine.spy.appender.SingleLineFormat
# 使用Slf4J记录sql
appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准,单位秒
outagedetectioninterval=2
application.properties中配置数据库连接相关属性
由于使用的是p6spy,url和driver-class-name与平常不大一样,driver使用的是p6spy提供的Driver,url里面要添加p6spy。
spring.jpa.hibernate.ddl-auto=none让jpa不进行ddl操作,不创建表
注:spring.jpa.properties.hibernate.show_sql=true,spring.jpa.properties.hibernate.format_sql=true
其实也可以使用jpa自带的sql打印
spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
spring.datasource.url=jdbc:p6spy:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=none
在项目运行的时候床架数据表:在resource文件夹下创建schema.sql文件,项目运行时会执行文件夹里的sql语句
drop table coffee if exists ;
create table coffee(
id bigint auto_increment,
name varchar(64) not null,
price bigint not null,
create_time timestamp ,
update_time timestamp ,
primary key(id)
);
insert into coffee(name,price,create_time,update_time) values ('latte',30,now(),now())
实体类BaseEntity
@Data //自动添加get、set、toString方法
@MappedSuperclass //定义为父类可以被其它类继承
@NoArgsConstructor //自动添加无参构造方法
@AllArgsConstructor //自动添加所有参数的构造方法
public class BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@CreationTimestamp //创建时间
@Column(updatable = false) //不可被修改
private Date createTime;
@UpdateTimestamp //修改时间
private Date updateTime;
}
实体类Coffee
@Entity //定义为实体类
@Table(name = "coffee") //关联数据表
@Data
@ToString(callSuper = true) //生成toString方法并继承父类的toString
@NoArgsConstructor
@AllArgsConstructor
@Builder //生成builder
@EqualsAndHashCode(callSuper = true)
public class Coffee extends BaseEntity implements Serializable {
private String name;
@Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyMinorAmount",
parameters = {@org.hibernate.annotations.Parameter(name = "currencyCode", value = "CNY")})
private Money price;
}
repository
public interface CoffeeRepository extends JpaRepository {
Coffee findCoffeeByName(String name);
}
切面
@Aspect //定义为切面
@Component //加component注解和bean注解才能被容器加载
@Slf4j
public class performanceAspect {
@Around("crud()") //在方法执行前后执行,使用crud()定义的切点
public Object logPerformance(ProceedingJoinPoint pjp) throws Throwable{
long start = System.currentTimeMillis();
String name="-";
String result="Y";
try{
name = pjp.getSignature().toShortString();
return pjp.proceed();
}catch (Throwable t){
result = "N";
throw t;
}finally {
long end =System.currentTimeMillis();
log.info("{};{};{}ms",name,result,end-start);
}
}
@Pointcut("execution(* com.changli.aop.repository..*(..))") //定义切点
private void crud(){}
}
主程序
@SpringBootApplication
@Slf4j
@EnableAspectJAutoProxy //开启aspectJ
@EnableJpaRepositories //开启jpa
@EnableTransactionManagement //开启事务
public class AopApplication implements CommandLineRunner {
@Autowired
private CoffeeRepository coffeeRepository;
public static void main(String[] args) {
SpringApplication.run(AopApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
log.info("latte {}",coffeeRepository.findCoffeeByName("latte"));
}
}
demo的git地址:https://github.com/struggle1to1win/aop.git
注:此demo是在学习丁雪丰老师课程时跟着写的练习demo,侵删