11.5.2 封装数据库操作
聊天机器人涉及的数据库操作主要包括获取问答知识表所有记录、获取上一次的聊天类别、根据知识id从问答知识分表随机获取一个答案、随机获取一条笑话和保存聊天记录。笔者将这些数据库操作统一封装到工具类MySQLUtil中,该类的完整代码如下:
- package org.liufeng.course.util;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.List;
- import org.liufeng.course.pojo.Knowledge;
- /**
- * MySQL数据库操作类
- *
- * @author liufeng
- * @date 2013-12-01
- */
- public class MySQLUtil {
- /**
- * 获取MySQL数据库连接
- *
- * @return Connection
- */
- private Connection getConn() {
- String url = "jdbc:mysql:// localhost:3306/liufeng";
- String username = "liufeng";
- String password = "lyq617617";
- Connection conn = null;
- try {
- // 加载MySQL驱动
- Class.forName("com.mysql.jdbc.Driver");
- // 获取数据库连接
- conn = DriverManager.getConnection(url, username, password);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return conn;
- }
- /**
- * 释放JDBC资源
- *
- * @param conn 数据库连接
- * @param ps
- * @param rs 记录集
- */
- private void releaseResources(Connection conn, PreparedStatement ps,
- ResultSet rs) {
- try {
- if (null != rs)
- rs.close();
- if (null != ps)
- ps.close();
- if (null != conn)
- conn.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 获取问答知识表中所有记录
- *
- * @return List<Knowledge>
- */
- public static List<Knowledge> findAllKnowledge() {
- List<Knowledge> knowledgeList = new ArrayList<Knowledge>();
- String sql = "select * from knowledge";
- MySQLUtil mysqlUtil = new MySQLUtil();
- Connection conn = null;
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- conn = mysqlUtil.getConn();
- ps = conn.prepareStatement(sql);
- rs = ps.executeQuery();
- while (rs.next()) {
- Knowledge knowledge = new Knowledge();
- knowledge.setId(rs.getInt("id"));
- knowledge.setQuestion(rs.getString("question"));
- knowledge.setAnswer(rs.getString("answer"));
- knowledge.setCategory(rs.getInt("category"));
- knowledgeList.add(knowledge);
- }
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- // 释放资源
- mysqlUtil.releaseResources(conn, ps, rs);
- }
- return knowledgeList;
- }
- /**
- * 获取上一次的聊天类别
- *
- * @param openId 用户的OpenID
- * @return chatCategory
- */
- public static int getLastCategory(String openId) {
- int chatCategory = -1;
- String sql = "select chat_category from chat_log
- where open_id=? order by id desc limit 0,1";
- MySQLUtil mysqlUtil = new MySQLUtil();
- Connection conn = null;
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- conn = mysqlUtil.getConn();
- ps = conn.prepareStatement(sql);
- ps.setString(1, openId);
- rs = ps.executeQuery();
- if (rs.next()) {
- chatCategory = rs.getInt("chat_category");
- }
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- // 释放资源
- mysqlUtil.releaseResources(conn, ps, rs);
- }
- return chatCategory;
- }
- /**
- * 根据知识id随机获取一个答案
- *
- * @param knowledgeId 问答知识id
- * @return
- */
- public static String getKnowledSub(int knowledgeId) {
- String knowledgeAnswer = "";
- String sql = "select answer from knowledge_sub
- where pid=? order by rand() limit 0,1";
- MySQLUtil mysqlUtil = new MySQLUtil();
- Connection conn = null;
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- conn = mysqlUtil.getConn();
- ps = conn.prepareStatement(sql);
- ps.setInt(1, knowledgeId);
- rs = ps.executeQuery();
- if (rs.next()) {
- knowledgeAnswer = rs.getString("answer");
- }
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- // 释放资源
- mysqlUtil.releaseResources(conn, ps, rs);
- }
- return knowledgeAnswer;
- }
- /**
- * 随机获取一条笑话
- *
- * @return String
- */
- public static String getJoke() {
- String jokeContent = "";
- String sql = "select joke_content
- from joke order by rand() limit 0,1";
- MySQLUtil mysqlUtil = new MySQLUtil();
- Connection conn = null;
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- conn = mysqlUtil.getConn();
- ps = conn.prepareStatement(sql);
- rs = ps.executeQuery();
- if (rs.next()) {
- jokeContent = rs.getString("joke_content");
- }
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- // 释放资源
- mysqlUtil.releaseResources(conn, ps, rs);
- }
- return jokeContent;
- }
- /**
- * 保存聊天记录
- *
- * @param openId 用户的OpenID
- * @param createTime 消息创建时间
- * @param reqMsg 用户上行的消息
- * @param respMsg 公众账号回复的消息
- * @param chatCategory 聊天类别
- */
- public static void saveChatLog(String openId,
- String createTime, String reqMsg,
- String respMsg, int chatCategory) {
- String sql = "insert into chat_log(open_id,
- create_time, req_msg, resp_msg, chat_category)
- values(?, ?, ?, ?, ?)";
- MySQLUtil mysqlUtil = new MySQLUtil();
- Connection conn = null;
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- conn = mysqlUtil.getConn();
- ps = conn.prepareStatement(sql);
- ps.setString(1, openId);
- ps.setString(2, createTime);
- ps.setString(3, reqMsg);
- ps.setString(4, respMsg);
- ps.setInt(5, chatCategory);
- ps.executeUpdate();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- // 释放资源
- mysqlUtil.releaseResources(conn, ps, rs);
- }
- }
- }
上述代码中,使用order by rand()随机获取记录,这种方式比较直观,但当数据量比较大时,查询效率会很低。另一种高效的随机获取记录的方法如下:
- SELECT joke_content FROM `joke` AS t1
- JOIN (SELECT ROUND(RAND() * (SELECT MAX(joke_id) FROM `joke`)) AS joke_id) AS t2
- WHERE t1.joke_id>= t2.joke_id
- ORDER BY t1.joke_id ASC LIMIT 1
上面的SQL语句也能够从joke表中随机获取一条记录,虽然看上去实现比较复杂,但执行效率却提高了许多倍。
在MySQLUtil类中,findAllKnowledge()方法的返回值是Knowledge集合,Knowledge类的定义如下:
- package org.liufeng.course.pojo;
- /**
- * 问答知识model
- *
- * @author liufeng
- * @date 2013-12-01
- */
- public class Knowledge {
- private int id;
- private String question;
- private String answer;
- private int category;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getQuestion() {
- return question;
- }
- public void setQuestion(String question) {
- this.question = question;
- }
- public String getAnswer() {
- return answer;
- }
- public void setAnswer(String answer) {
- this.answer = answer;
- }
- public int getCategory() {
- return category;
- }
- public void setCategory(int category) {
- this.category = category;
- }
- }