Java 通过 socket 获取 mysql 中的记录遇到的问题
在实际应用中,经常会遇到这种需求,客户端发送关键字到服务器端,服务器端根据关键字查找数据库中的内容并发送给客户端。本文主要阐述根据传输过来的关键字在查找数据库时查找不到(实际上是数据库中是有数据的)的问题,以及解决方法。
先看 Java 与 mysql 交互的代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 String driver = "com.mysql.jdbc.Driver"; // 驱动程序名
String url = "mysql的地址"; // URL指向要访问的数据库
String user = "用户名"; // MySQL配置时的用户名
String password = "你的密码"; // MySQL配置时的密码
Class.forName(driver);// 加载驱动程序
Connection conn = DriverManager.getConnection(url, user, password);// 连接数据库
if(!conn.isClosed())
System.out.println("成功连接到数据库!");
PreparedStatement prepstmt = null; //用预编译对象执行sql语句并返回结果
String sql = "select admoment,url1,url2 from captiontest where filmname=? order by admoment";//要执行的SQL语句,按时间查找广告出现的数据记录
prepstmt=conn.prepareStatement(sql);
prepstmt.setString(1,name); // 由于filmnam是String类所以这里是setString,其他同理为setxxx(xxx为类型)
ResultSet rs=prepstmt.executeQuery(); //结果集
其中程序中的 name
为 String
类型,也就是客户端传过来的关键字,但是测试时的问题是即使数据库中存在相关的关键字信息,也不会输出相关信息。。
这个时候首先要做的就是将执行的 SQL 语句打印出来,因为很多时候得不到预期的结果都是因为是实际执行的 SQL 语句跟自己预期会执行的 SQL 语句不同。通过下面语句可以得出执行的 SQL 语句: System.out.println(prepstmt.toString());
。
结果如下1
select admoment,url1,url2 from captiontest where filmname='爱情公寓4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\' order by admoment
怪不得找不到,sql 语句都变成这个模样了,那中间的 \0
是从哪里来的?在网上查了后得出的原因如下:在 socket
传输自己流时,默认会有一段固定长度的 bufferstream
来接受传输的字节流,这段固定长度的默认值就是 \0
, 而那些 \0
就是 bufferstream
中没被传输过来的字节流覆盖的单元,解决方法也很简单,就是在服务器接受到客户端传输过来的字节流时,根据字节流有效长度来创建 String
原来我的 name
是这样产生的,is 是 socket 的输入流:1
2int n = is.read(b);
String name=new String(b,"UTF-8");
没有指定长度,改为下面的产生方式就好了1
2int n = is.read(b);
String name=new String(b,0,n);//0和n是指定产生String用到的字节流的开头和结尾