[英]Retrieving a result by different combination's using StringTokenizer and MYSQL
I'm retrieving user input such as "tea, coffee, latte" from a JTextField, the following input is then queried to a particular result that includes the strings "tea, coffee, latte" within the database: 我从JTextField检索用户输入,例如“茶,咖啡,拿铁咖啡”,然后将以下输入查询到特定的结果,该结果包括数据库中的字符串“茶,咖啡,拿铁咖啡”:
public void actionPerformed(ActionEvent e) {
try {
String abc = field.getText();
StringTokenizer str = new StringTokenizer(abc);
while (str.hasMoreTokens()) {
str.nextToken((", ")).trim();
}
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/intelli_db", "root", "root");
PreparedStatement st1 = con.prepareStatement("SELECT * FROM SHOP WHERE DRINKS LIKE '%" + abc + "%' OR '%" + abc + "%' OR '%" + abc + "%' OR '%" + abc + "%'");
ResultSet rs = st1.executeQuery();
if (rs.next()) {
String s = rs.getString(1);
String s1 = rs.getString(2);
String s2 = rs.getString(3);
//Sets Records in TextFields.
field6.setText(s2);
} else {
JOptionPane.showMessageDialog(null, "No such input found");
}
//Create Exception Handler
} catch (Exception ex) {
System.out.println(ex);
}
}
however, I wish it to find the result of any combination of these strings, so "coffee, latte, tea" would also give the same result as ""tea, coffee, latte" would. 但是,我希望它能找到这些字符串的任意组合的结果,因此“咖啡,拿铁,茶”也将与“茶,咖啡,拿铁”得到相同的结果。
The database structure: 数据库结构:
Menu_ID -------- 1
Drinks ------- tea, coffee, latte
Hot_Drinks_Description ------------------------ There are various hot drinks available, including Earl Grey tea, white or black coffee or a Latte.
Thus if the user types in either, tea or coffee or latte or a combination - separated by comma's, the result would display the description of the hot drinks available. 因此,如果用户输入茶,咖啡或拿铁咖啡或两者的组合(以逗号分隔),则结果将显示可用热饮的描述。
It seems that the problem is a little messy. 看来问题有点混乱。 This seems to be the situation:
似乎是这样的情况:
You have a List
of user inputs. 您有一个用户输入
List
。 You have have a database field that is, itself, as comma separated list. 您有一个数据库字段,其本身就是逗号分隔的列表。
You need to see if there is a permutation in the database that matches one of the permutations of your input. 您需要查看数据库中是否存在与输入的排列之一匹配的排列。
First your query. 首先您的查询。 From this answer this is how to create a prepared statement with an
IN
clause. 从这个答案中,这就是如何使用
IN
子句创建准备好的语句。
PreparedStatement st1 = con.prepareStatement("SELECT * FROM SHOP WHERE DRINKS IN (?)");
Array array = con.createArrayOf("VARCHAR", stringPermutations);
st1.setArray(1, array);
This essentially queries your database where DRINKS
is one of IN
. 这实际上查询了
DRINKS
是IN
之一的数据库。
Now onto creating the stringPermutations
. 现在开始创建
stringPermutations
。 This needs to be an Object[]
of the comma separated permutations - to match the database. 这必须是逗号分隔排列的
Object[]
-才能匹配数据库。
First, get a Set<String>
of the user inputs: something like this ought to do: 首先,获取用户输入的
Set<String>
:应该执行以下操作:
public Set<String> getInputs(final JTextComponent component) {
final Set<String> inputs = new LinkedHashSet<>();
for (final String input : component.getText().split("\\s+")) {
inputs.add(input);
}
return inputs;
}
In Java 8: 在Java 8中:
public Set<String> getInputs(final JTextComponent component) {
return Stream.of(component.getText().split("\\s+")).
collect(Collectors.toSet());
}
Now you need to permute the inputs to get all possible combinations. 现在,您需要对输入进行置换以获得所有可能的组合。 You will have
n!
您将拥有
n!
of them - this is many : 其中-这是很多 :
public List<Set<String>> permutations(final Set<String> input) {
if (input.size() == 1) {
return Arrays.asList(input);
}
final List<Set<String>> output = new ArrayList<>();
final Iterator<String> iter = input.iterator();
while (iter.hasNext()) {
final String item = iter.next();
final Set<String> copy = new LinkedHashSet<>(input);
copy.remove(item);
for (final Set<String> rest : permutations(copy)) {
rest.add(item);
output.add(rest);
}
}
return output;
}
This is a recursive algorithm, it's pretty standard. 这是一个递归算法,很标准。 The output is something like this:
输出是这样的:
[D, C, B, A]
[C, D, B, A]
[D, B, C, A]
[B, D, C, A]
[C, B, D, A]
[B, C, D, A]
[D, C, A, B]
[C, D, A, B]
[D, A, C, B]
[A, D, C, B]
[C, A, D, B]
[A, C, D, B]
[D, B, A, C]
[B, D, A, C]
[D, A, B, C]
[A, D, B, C]
[B, A, D, C]
[A, B, D, C]
[C, B, A, D]
[B, C, A, D]
[C, A, B, D]
[A, C, B, D]
[B, A, C, D]
[A, B, C, D]
So, for 4
input you get 4! = 24
因此,对于
4
输入,您将得到4! = 24
4! = 24
permutations. 4! = 24
个排列。 Now we need to join those individual items into comma separated lists: 现在,我们需要将这些单独的项目加入逗号分隔的列表中:
public List<String> combine(final List<Set<String>> toJoin) {
final List<String> outputs = new ArrayList<>(toJoin.size());
for (final Set<String> items : toJoin) {
outputs.add(join(items));
}
return outputs;
}
private String join(final Set<String> items) {
final Iterator<String> iter = items.iterator();
final StringBuilder sb = new StringBuilder();
sb.append(iter.next());
while (iter.hasNext()) {
sb.append(", ").append(iter.next());
}
return sb.toString();
}
Again, tidier in Java 8: 同样,在Java 8中更整洁:
public List<String> combine(final List<Set<String>> toJoin) {
return toJoin.stream().
map(items -> items.stream().collect(Collectors.joining(", "))).
collect(Collectors.toList());
}
Finally we can get the Object[]
input to the PeparedStatement
: 最后,我们可以将
Object[]
输入到PeparedStatement
:
final Object[] stringPermutations = combine(permutations(getInputs(field))).toArray();
PreparedStatement st1 = con.prepareStatement("SELECT * FROM SHOP WHERE DRINKS IN (?)");
Array array = con.createArrayOf("VARCHAR", stringPermutations);
st1.setArray(1, array);
It should further be noted that you should be closing your resources , you can use the try-with-resources
construct: 还应该注意的是,您应该关闭资源 ,可以使用
try-with-resources
构造:
final Object[] stringPermutations = combine(permutations(getInputs(field))).toArray();
try (final Connection con = getConnection()) {
try (final PreparedStatement st1 = con.prepareStatement("SELECT * FROM SHOP WHERE DRINKS IN (?)")) {
Array array = con.createArrayOf("VARCHAR", stringPermutations);
st1.setArray(1, array);
try (final ResultSet rs = st1.executeQuery()) {
//do stufd
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.