QueryDSL SQL与JDBCTemplate之间的性能测试

Ame*_*n.M 8 java spring jdbc querydsl

我试图说服"更高层次"使用querydsl sql来保持持久性.但是他们更喜欢spring jdbctemplate,原因是它提供了最好的原始性能.

表现是我​​们对课程的首要要求.这就是为什么JPA根本不是一个选择.QueryDSL SQL开销是否过多,无法从我们的选项中解脱出来?

我想知道是否有任何"最近的"性能测试来显示querydsl sql如何使用jdbctemplate和jpa.

我遇到过这个.我想知道querydsl sql与jdbctemplate和jpa实现进行比较时的相对性能.

Ame*_*n.M 14

我做了一些性能测试来比较querydsl和jdbctemplate之间的开销/性能.

这就是我做的
1.创建一个使用querydsl和jdbctemplate的spring引导项目
2.创建2个端点,1个用于使用querydsl,另一个用于jdbctemplate.
3. querydsl配置使用spring boot autoconfigured数据源来配置其SQLQueryFactory.
4. JdbcTemplate也使用相同的自动配置数据源进行自动配置.
5.存储库中有两个类似查询的实现,一个使用querydsl,另一个使用jdbctemplate.查询相对复杂,由几个内部联接和where子句组成.
6. Service方法有一个for循环,并在每次迭代中调用repository方法.迭代次数是可配置的,并且已设置为1万次迭代.
7. System.nanoTime()用于控制器中的服务方法,以计算执行存储库方法的多次迭代所花费的时间.
8. JdbcTemplate平均花费800毫秒来执行10万次存储库调用.
9. Querydsl平均花费5000毫秒来执行10万次存储库调用.
10.观察:对于相同的查询,Querydsl比JdbcTemplate慢6倍.开销可能是在querydsl的查询序列化中.

QueryDSL存储库实现

List<Customer> customers = new ArrayList<>();
Customer customerObj = null;
List<Tuple> customerTuples =queryFactory.select(customer.firstName,customer.status,customer.customerId).
                                from(customer).innerJoin(customerChat).on(customer.customerId.eq(customerChat.senderId)).
                                innerJoin(customerChatDetail).on(customerChat.chatDetailId.eq(customerChatDetail.chatDetailId)).
                                where(customerChatDetail.isRead.eq(true).and(customer.status.eq(true))).fetch();

    for (Tuple row : customerTuples) {
        customerObj = new Customer();
      customerObj.setFirstName(row.get(customer.firstName));
      customerObj.setStatus( row.get(customer.status));
      customerObj.setCustomerId(row.get(customer.customerId));
      customers.add(customerObj);
    }
return customers;
Run Code Online (Sandbox Code Playgroud)

JdbcTemplate实现

List<Customer> customers = this.jdbcTemplate.query(
            "select first_name,status,customer_id from customer inner join v_customer_chat on customer.customer_id=v_customer_chat.sender_id inner join v_customer_chat_detail on v_customer_chat.chat_detail_id = v_customer_chat_detail.chat_detail_id where v_customer_chat_detail.is_read = ? and customer.status = ?;",new Object[] {true, true},
            new RowMapper<Customer>() {
                public Customer mapRow(ResultSet rs, int rowNum) throws SQLException {
                    Customer customer = new Customer();
                    customer.setFirstName(rs.getString("first_name"));
                    customer.setStatus(rs.getBoolean("status"));
                    customer.setCustomerId(rs.getLong("customer_id"));
                    return customer;
                }
            });  
Run Code Online (Sandbox Code Playgroud)

基本上我试图用不同的库做同样的事情并测量哪一个会产生更多的开销.
1.使用连接执行相对复杂的查询.
2.从结果集中填充bean.

我正在使用H2内存数据库.数据库只保存每个表的几个记录.和1个匹配查询的结果行.

该方法在for循环中执行(1万亿次迭代).并且在循环周围的System.nanoTime()的帮助下计算时间.

它是一个具有不同端点的spring引导项目(一个用于querydsl,另一个用于jdbctemplate).querydsl和queryfactory的配置如下

  @Autowired
public DataSource dataSource;

@Bean
public PlatformTransactionManager transactionManager() {
    return new DataSourceTransactionManager(dataSource);
}

@Bean
public com.querydsl.sql.Configuration querydslConfiguration() {
    SQLTemplates templates = H2Templates.builder().build();
    com.querydsl.sql.Configuration configuration = new com.querydsl.sql.Configuration(templates);

    configuration.setExceptionTranslator(new SpringExceptionTranslator());

    return configuration;
}

@Bean
public SQLQueryFactory queryFactory() {
    Provider<Connection> provider = new SpringConnectionProvider(dataSource);
    return new SQLQueryFactory(querydslConfiguration(), provider);
}
Run Code Online (Sandbox Code Playgroud)