protectedvoidcallDecode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) { try { while (in.isReadable()) { intoutSize= out.size(); intoldInputLength= in.readableBytes(); decode(ctx, in, out); // Check if this handler was removed before continuing the loop. // If it was removed, it is not safe to continue to operate on the buffer. // // See https://github.com/netty/netty/issues/1664 if (ctx.isRemoved()) { break; } if (outSize == out.size()) { if (oldInputLength == in.readableBytes()) { break; } else { continue; } } if (oldInputLength == in.readableBytes()) { thrownewDecoderException( StringUtil.simpleClassName(getClass()) + ".decode() did not read anything but decoded a message."); } if (isSingleDecode()) { break; } } } catch (DecoderException e) { throw e; } catch (Throwable cause) { thrownewDecoderException(cause); } }
绑定端口,同步等待成功...... TimeServer 接收到的消息 :QUERY TIME ORDER QUERY TIME ORDER ......省略部分 QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORD; 当前统计:1 QUERY TIME ORDER TimeServer 接收到的消息 : ......省略部分 QUERY TIME ORDER QUERY TIME ORDER; 当前统计:2
1 2 3
TimeClient 接收到的消息 :BAD ORDER BAD ORDER ; 当前统计:1
从上面的日志中,我们可以发现服务端发生TCP粘包的情况,正确情况应该是服务端输出100条含TimeServer 接收到的消息 :QUERY TIME ORDER; 当前统计:counter的日志,而且客户端只接收了部分断断续续的数据,说明返回时也发生了粘包…
/** * A decoder that splits the received {@link ByteBuf}s on line endings. * <p> * Both {@code "\n"} and {@code "\r\n"} are handled. * For a more general delimiter-based decoder, see {@link DelimiterBasedFrameDecoder}. */ publicclassLineBasedFrameDecoderextendsByteToMessageDecoder { protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer)throws Exception { finalinteol= findEndOfLine(buffer); if (!discarding) { if (eol >= 0) { final ByteBuf frame; finalintlength= eol - buffer.readerIndex(); finalintdelimLength= buffer.getByte(eol) == '\r'? 2 : 1; } } ...... } }
CREATE TABLE employees ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(24) NOT NULLDEFAULT'' COMMENT '姓名', age int(11) NOT NULLDEFAULT'0' COMMENT '年龄', position varchar(20) NOT NULLDEFAULT'' COMMENT '职位', hire_time timestampNOT NULLDEFAULTCURRENT_TIMESTAMP COMMENT '入职时间', PRIMARY KEY (id), KEY idx_name_age_position (name,age,position) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1DEFAULT CHARSET=utf8 COMMENT='员工记录表';
mysql> explain select name from employees where name >'a'orderby name ; +----+-------------+-----------+------------+-------+-----------------------+-----------------------+---------+------+-------+----------+--------------------------+ | id | select_type |table| partitions | type | possible_keys | key | key_len |ref|rows| filtered | Extra | +----+-------------+-----------+------------+-------+-----------------------+-----------------------+---------+------+-------+----------+--------------------------+ |1| SIMPLE | employees |NULL|range| idx_name_age_position | idx_name_age_position |74|NULL|48422|100|Usingwhere; Using index | +----+-------------+-----------+------------+-------+-----------------------+-----------------------+---------+------+-------+----------+--------------------------+ 1rowinset
/**
* 查询根据参数位置
* @param name
* @return
*/
@Query(value = "select * from person where name = ?1",nativeQuery = true)
Person findPersonByName(String Name);
/**
* 查询根据Param注解
* @param name
* @return
*/
@Query(value = "select p from person p where p.uname = :name")
Person findPersonByNameTwo(@Param("name") String name);
public List<Flow> queryFlows(int pageNo, int pageSize, String status, String userName, Date createTimeStart, Date createTimeEnd) { List<Flow> result = null;
@Query(nativeQuery = true, value = "select id, name,age FROM people WHERE id=?! and name=?2 and age=?3, countQuery = "select count(*) FROM people WHERE id=?! and name=?2 and age=?3") public Page findAll(Integer id,String name,Integer age,Pageable pageable);
如果既要分组group by,还要分页countQuery就需要: countQuery = "select count(*) FROM (select count(*) FROM people WHERE id=?! and name=?2 and age=?3 group by name) a"最后的a为别名,随意命名