一、元数据介绍

  元数据指的是"数据库"、"表"、"列"的定义信息。

1.1、DataBaseMetaData元数据

  Connection.getDatabaseMetaData()获得代表DatabaseMetaData元数据的DatabaseMetaData对象。
  DataBaseMetaData对象的常用方法:

  • getURL():返回一个String类对象,代表数据库的URL。
  • getUserName():返回连接当前数据库管理系统的用户名。
  • getDatabaseProductName():返回数据库的产品名称。
  • getDatabaseProductVersion():返回数据库的版本号。
  • getDriverName():返回驱动驱动程序的名称。
  • getDriverVersion():返回驱动程序的版本号。
  • isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。
  1. 1 /**
  2. 2 * @Method: testDataBaseMetaData
  3. 3 * @Description: 获取数据库的元信息
  4. 4 * @Anthor:孤傲苍狼
  5. 5 *
  6. 6 * @throws SQLException
  7. 7 */
  8. 8 @Test
  9. 9 public void testDataBaseMetaData() throws SQLException {
  10. 10 Connection conn = JdbcUtils.getConnection();
  11. 11 DatabaseMetaData metadata = conn.getMetaData();
  12. 12 //getURL():返回一个String类对象,代表数据库的URL
  13. 13 System.out.println(metadata.getURL());
  14. 14 //getUserName():返回连接当前数据库管理系统的用户名
  15. 15 System.out.println(metadata.getUserName());
  16. 16 //getDatabaseProductName():返回数据库的产品名称
  17. 17 System.out.println(metadata.getDatabaseProductName());
  18. 18 //getDatabaseProductVersion():返回数据库的版本号
  19. 19 System.out.println(metadata.getDatabaseProductVersion());
  20. 20 //getDriverName():返回驱动驱动程序的名称
  21. 21 System.out.println(metadata.getDriverName());
  22. 22 //getDriverVersion():返回驱动程序的版本号
  23. 23 System.out.println(metadata.getDriverVersion());
  24. 24 //isReadOnly():返回一个boolean值,指示数据库是否只允许读操作
  25. 25 System.out.println(metadata.isReadOnly());
  26. 26 JdbcUtils.release(conn, null, null);
  27. 27 }

  运行结果如下:

  aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAkMAAACbCAIAAADuqQinAAAVKklEQVR4nO2dy7mruBJGHRcBEY+nPbtB9Oc8euxgfAc2IKleemBvsNeanLMNeiP9qCRUl3/+/e+ff//7HwAAwDm5PJXsAQAAcE5QMgAAODcoGQAAnBuUDAAAzo2nZLf5crlcLvPNDn6bL5fpek/u9+4+Ia86uIQ1EXO/TkllBVd3TLcJL91vbN8dMdv3S/tRlmeAvwUlq2O8bPfr5MRgXf2rOtXSfXNefKUPwm0UMfhXH49cvNXk0yjs/Nnt+/F+5L8G9dazlgpKBgdh0LqIkrVEYPd78ypK1sZt9uRGXs3KpAR+ikJFocfG9f36kcjwbda0HSWD7wIlq2O0bJ1ChpLtG4tmw01LVPxQP1gPDut79aPn9NEPi5LBFyKULLNMqPaU8g7RAxNrjOxTmbVHXtbeqe/X6TJd75uR5hXHdL1bfbccDHwDkVkiO8Ioz0qhmy2LbrrRQppTz7nBTU/YU7ItvP9s6HYtEbSw/9kRxPX8aKtqXcjWn/yogkT/ph95ShbWc6TrZp7r+iDAG3HnZPLtrXxm5btk2TPS4M/QyS+3WRusyl5/v06XaZqm6/2ZoWmab0k/kQNckcvihvt1FnkKX8OdbqnmOaNfyPR08wKJWvXrObM2mcYzU8nskS/IldsKawinFuN6bpyRKX/O1+23ISELcvW2flRRSf7OFFvJvDyHfRDgvbQpmRjmlR5YzoTysS16pbbmZEK1ktGjDOMPWDI9u0RFvjrnZL2WRSNdpTzZXU3WI+tmW8myJZgt7Hiuwjucek7mCv6eDiEIyfxrut7TMr0uB0aER9SCWsne2o/8uuhWsoo8230Q4M00KZlubXDs++kv/c92KVrz7SGHoaKnKzajqs7bo2QVua+dJlRkUAuR/tZYzw3l9Ua6KFcVs4VdBj85QbWvrg/KKmOPtD5EhvUJbEW2/6IfJXpW5LhPyaKeEvRBgPfSrGTytdvpgekDPagFnpLJkVwdbpQX1aBE+c9duR+wLOrpqkGSXIc5lesleymZkyuRskxzz50IdgWIPF8TGcsyocRjzZCDB+Pv+lG6omzlxi5dqWRuTwn7IMAbea+SfWhOlmbkng1MalSeyWRvJaseVqvvGJuTieWLj83JRCYqrKZd1Ff5c94iTGa2OMufqp6Lv+xHcr3qTUpW3QcB3kCTkpUduTDlBCvGVZ3eXCcLlGy5Eq5Z5IUKSmQVJc5zcql3icxKVxlhg4GwCCvaaAclC3OlZSS/OLJOVh2NtHhaQmbpVs2qapClD/QjM+3oBaPsUlb7aj2lug8C7E3bjo/y3X+a58nsgXLgEQsN9XsXQyXbTFeKjctcPZezmQZrm5dnLa2mq166ec3q6mTUcxZ0KfAeShblym0FqyAy+ajGfLUTV/MkywIWGRLlr50efa4flZ9Bq29mZj2LN5M0GT/PDz0QwIdo3IWfriSXa+ViBcYzLFkPfPecbI1a6UR5omW2thJN13vxlp2sm9sxWKPnwBJZmG52Q1hkKXNrhHkLuukGShblym+FKNsPq579h67ikUwzbTyQTtw1Y/Yn+1G5CtpWz8nv882YpOl5zsIjZPBpmpXsuASv9JXsZxoZtizCoalvwXP1oxH26YMAzbhK1rvN4U/YabjYS2F2sCzCgWlpwVP1oxF4rOGvKJTsfp2MdY+Ds1tmmSvBOKftRyP8TEHhgIg5mf/Nz/FYbfc7vfOiZLAHZ+tHI+zdBwGawWc0AACcG5QMAADODUoGAADnBiUDAIBzg5IBAMC5OZiSpTu+5Bmq9kkMb8NL92c+EwIAODQfVjL308ng+FZ5zwepOodwX/jMFACgisMomX6WurgVJQMAgJyjKNltVkRBkTKUDAAActQzPqbrPV2xMk/x1gZy/Wp5Qnd5izb9eoaqVY+mw+EVh1/BIpynZFt4fQppxqyfAxHVFQAAZNinVakuajUfVIVPEPOqjG1lEzLhYkWT0Rp/XdILVeYTJXX/JJylBK6b8pu3312/UkoeCv2aNQ8ZzMkAACIMJdOdIipjazJ6+1dFZMVti8ejzC9SlZJF6TYpgnWzrWSF/6bMi+VQrlAyAIAqdCXTzVja0Lr95l91osgNmi8Be95Uo2RRuo2CYJwg3OpDOa6N0AUySgYAUEWzkmmWvU3JzKtpFJqSZR5q1+0f1UrmpBvuy5DrUnspWVVtmGmiZAAAVRxlTvZSsjWm9T/hjo+xOZkwpn5sTiYyUWE1BQAASYuSGd98ZZJhXk1iMJQstSlaxkVzncxJ15uUSW/tOylZVW2UGanaHQMAADlNSqbvx/N36xVRaT/m1sVtk1/1l9FRusrWjOWPLOgyN9pDySrqSt9W49cVAACUNCrZo+9zsgz5+dYiWc/A0/UudkNk0WprS02fkykyt0a4mjbjdAMli3KVZ0mffNV86gYA8OMc4gThXD0AAAAaOISSIWUAANDNMZRMnHjxuF8npA0AACo4ipI9xHddLAoBAEANB1IyAACADlAyAAA4NygZAACcG5QMAADODUoGAADnBiUDAIBzkyuZ4uZ5PUGqMsLuw6xC7ysAAAAKuZJJ74+L9FRJjHJSb/6xc3JViCZKBgAAPUglm+c584gyzXNwpvAL/+h25apydDxKBgAAjShKdltdNj9djyyn4+tKtQmQq2Sq25JMvFAyAADoIVOyRbMWKXv50FqVrTwcsVAvaZvcUHUqkzeUDAAAelCV7OX7cnEGufk6Vs75zZUr2dFhK57+K0oGAAA9CCV7CtD9Ok3TtNkYF13Kpcvyypno2esqSgYAAG8iU7JSshKNWdQrlbLAvfTrbPvpeneVDOsiAACMYClZSv7z+lfsHjPRL7nEVsobSgYAAD3UKlmiMa8/jZtT0jlXsFsEJQMAgD5qlKy0Iq4uMctDOvKw5bfP+XfTwt6IkgEAQA+ZkmnffD2U9bCXlAnZKbw+y7iyw6qKq9k187grAACAnK4ThP3TPCIqzJIAAAC19CiZel5HA9mS2fLRGgAAQBftSqbtQmzG+oIaAACgkQYlW9WHORQAABwHPG0CAMC5QckAAODcoGQAAHBuUDIAADg3KBkAAJwblOzIPLeL8p0CAICHVDJ5alTjSLqcWdW9WX/JgR6Bf/W7cJRs9PN0AICvQVey3hHy9dX0beQ0q01JtQj8qz8ESgYA8GJHJbtfFyfTA+cyJi5jlAj8qz8FSgYA8GLfOdmLbiVbJUrVKv9qVZ70+VxmUN2uvVyJvq7Ot8wLdnBVyWT2w1LLSdJZpowsSX8D+V16zaP8APDVHEnJkgFXGXv9qxX5SQp1m3MHn+ul7M77dbpM0zRd788J0DTNty1t/2qNkqUqZRXJLKo1Jws9mgIAfBvhjo8eUesaO+VA78tAdfSeHU65tkWeFGPTh9VZm3+1TsliR6PNSiakDDMkAHw7/i58y6VmQIeSFSN2058VmakXsuQ3VZZyJTOvNovxbkpWXBFuUgEAvo3oe7Ku6VVzIDHcZgO4fzVJUV1a8mRPHeZX8+pJlSy7hJABwPcTfhnd446sVcnsXQyXy2W+ulfDRH5uTvYoxBjLIgB8OVVzsnIsLHbp6YEMkYnCPvHth23rZI2Tsm3Hy5iSlVHnK2PvVbL0cwWEDAC+HVfJxJ6/J+ueEGuQdJQsDJvctpOSqdsr3L2Lr4tjSpblcp117qZkwcRXJAgA8LUIJcu3LjoLMeZUzTcAfn5OpuRN2d+vXBpUsizR+ZZfC5RMHhkWV7hazwgZAHw/nCD8pfAVGQD8DCjZd8JXZADwO6Bk30jPhlMAgLOCkn0V5SFYAAA/AEoGAADnBiUDAIBzg5IBAMC5QckAAODcoGQAAHBuULLf5LnJkY36APAN5EqmHLTYOuRZRz+FVzuOoDIid86iah2+5QFchbsY/VJ1un5t+cVsDadEgpIBwDeQK9lrkEwGOF0dDJSTekvnxbnTMZHSiJLd5sUFTBaL5qWzbwQvTrcvDpovtSFM1zvX2CNIFwDg15BKNs/zNi7e5ss0z3XOGmsOZ3c0ZlTJbvPlMt/iQ+b7z3HylexRqFWQbn9xg3QBAH4NRcluL014/j3flgFcV6riHHjXEVg52Pq+J9tYM13G80ElyyTFTXfkfN8g3dW7ZmIZTW83DZpR+8rgeS6CdAEA3kWmZMtQvajCbV7+SUQiG52y0U/aJjdUncoG9zElS4Z3zfpWOFrpSyZWsjR2N92RwgbpCtdkhnQrWQh/yv4q461MFwBgb1Qle9yv03NutgrYc0QqpUwMVskbu614+q9DSpaN7vlQP7TjQ2bXVbK0EF66Qy5XgnRl5LqkaPUtXlVEvcpZnP2SgJQBwGcQSvYcee7XaZqmZEx+DUj54FQM7SvJIG6NrvLXHacp3vg7ICIdSmak+34li+OOZ8nFX8aMLXwaAADeTKZkpWQlGpMt8Cj3KKTeoR0lq7Quiv3wxdpNOrb78XZPFUasi3m6eyuZlMlOJfPaV/djXVgbUTIA+DyWkqVIa92qTr4gJAOstr0uH8/HNvMpGDsvzGKGVO74MOeYxVper+EtSHdMyYr29bbOlKBkAPBH1CpZ+W7+3OEYjMXpC36wW2RAybSMJCkHqzv9CYl0A2XO0h2YlQXpjirZEr98UQlaHCUDgD+iRsnKIarcpPZYQstd2XLrhTmU9ypZZCXT1quqZ0PJx8rq7pbt7+hLbxFcnqfS9WW0jGZUyZ6T7XmWM+6KLwZRMgD4PJmSGYO8GKJeUqbLh7TvbWR2QM1CZq3B2FgD8qocZbyNNj1rN6bMsLYPMEg3v6dSBYJ0A0XRTbHaO4jzOYUaEiUDgD+i6wThoQ0L3ctUAAAACj1KNvqdULZktny0BgAA0EW7ko1su8sj6bL2AQAAZDQo2ao+zKEAAOA44GkTAADODUoGAADnBiUDAIBzg5IBAMC5QckAduDpCOmvc/HdxCe9whm5X6fxZj2Okpm+jOFNvGqcuh5m7KiAd/Bs277xYSTsW1ld/tqXD5rz3TlY+66nO3WfzD6coeMo2cKY7+hT8ceuKI+kZPIQraZ6SYO3VujwK1R7MwoXRbs/BAcb6QYJj8E72LDxq+076M9kKEso2R+CU+WVkSPMsiemrUtoLtgas9HTiJqz7R955ttZG8UzLh7rCLyfbd+Bs1dHB0OU7A9ByVb6RyLxvDQ8QLqDnPbZYOvjqrp+40HQKPwzGTV9sJ70u+272xtpM7mSvd56NrNT7Pe5TD6dWMsiVRwQ312ebErvHUxfDnvFifmKM2r9qohZa0ItV8L4YGZNT3Z5OU3iafBTUySpu24R6Va1vhG2MltdPUAXssrEx/2J9+W7YqTTn6uKVgiNpU4PDcN29iOnnBFbEG9K5rWbXt6wJutKpPOr7Ts4Nx6SMkXJpunlZ/EyTdN8S+Kv85aZtsssHHK5Ppe7i6N4BzMyVdxZHsGVp+5fLf6WvcnLlR4ii9jKs3AQ1/tGqoTLnMzlHuWUhilrywwb0tsDiiLcr9NlvlZXh+pCr1XIOvpePtLJqnKeq7AVKn61eqgfdqAfZQXtkbLLZbreepTMKW9Qk1UlMvjR9n2MWnlHpEwqmVCtpFnKnq6MI/WW7P2ULHwjU16HsufVEqeKq+KNPp/FuK1q3RHkWb65dUpZGEzpZOnt7mPb6tL0ktK10LW+tDd0p8ToIH2WNqXeQjkpD0auLJnaVlD7UWWjKGGH+lH2Y/tzGk+LrIYIRyS7JutKpPOr7TuqZCPBFSVLRGu+PeRgUei2YtkxX46yku+mZI1Clv2mG6dMrRKNK5/RJbGKh8q4Jcrzbj4t4yzmbaS0vhO6+6lsWSFfqyK1PTWmvI07rXXa+w6ZNKCsxeC5qm0F5509rB0Zdqwf7UGqDuoAblq7zPK6NTlSoh9u37F2HwjdqGRZ6dTnx7LSytGlTcnE2lJupmx6WUtSHlUyhXprhKdkTp5DJXPqKkxfruEZc3AlE27Y6lytt9Y80c9cXDPDU8tsMH0DblHQJPSYkhmLKvZzVdEH/bw56yh22LF+tAe3+XKZb2UjPSsrtnzo5fVqcicl+8X2TQwdjXxQyZLi3a/eF/dLfaaP3IiSORxnTlabK/+Wv5uTCQWxTcIiD3HYBurNUMpQVv0EyYqul9Dt9lElCycDErsV8nvcaMoe6ob98znZNtoobVT17qKW167J3ZTsp9q3c50jjfUz1sXkSpyoO/qaqxIdXaBxUpbmfEDJomqPC2I1e5DntymZHCPM9w/xGlMTtjtjSQriZ1Vsy9rRw0q9bFSy3vHaf/+vqDirFRqzZj2A1jpKbz/Kfux7Jgol8170/Egqn+e6EhnP5K+279jr69jrT4eSbdNX5UEttUq3+awx7KNky5t59uxkD06hAvlT1atk4bjn5cqPwM3z++ZkWbJLIymDxjTPoovVhK3PlQy5GmV0hTObzAtbTOjazYutypcGE8+V2d5GDForFFE29dA4bG8/Sn9reyju12kbj+abVTfOkB2V132egxJZz9WPtu9jUMmGxrUeJXN6fL4Wor0+b1fyQuvW44ZKyZM2njhxaUjJtHy7y05hjZXvcXrAtylZnqrxUmhawSvCWuS1qIfyrO9peK1i7LBF+zX3wq4XL6tLWc2vZMwqUdSPvB4a9sHefpT92FrFUU2spVIj9kek5A51sNppTvYr7TumZGMG6a4zPjrfRAvGJqIwzqBRGx4PKvEzLFMyAxrhIPQP6qNN2KNkOz02KNlfM/YSBC/2ebEDh9AKwWByCLqtReOa0q5kA6u2MiIevs+yLjs8dmxIMLcvwYfgbeII9A4pewxFDUq2GlF3el5Qsr8gtaNT+/tx38NbIAzgbSOD9zJU9y0L6jbHOwsfAACgBZQMAADODUoGAADnBiUDAIBzg5IBAMC5cZTMOWTCoiMIAADAEJaSje3w55NbAAD4FIaSDUoRSgYAAJ/CUbKBj9VQMgAA+BTtShae7v5wlMw/YaI4TL2jOAAA8HPkSqYf+587XxFOACz3WuL3Yu3tfp1NB4mcbQ0AAJWMWRcbfJIG6iRC7OWDCwAAvpzBdTLjPmdOVu3ElAOGAQCghmYly5fJDGVqXiezzJpMygAAIKBNyVQf3i1Klke03cNmRwAA6KRJyaQ7u14le5TLZtgSAQCgj7Y5Wbb7cJlX1SrZbU5/Kvd/4PQVAAC6aF0nKz75yt196qtd6b77Sf1di9zaGwIAAJDBWfgAAHBuUDIAADg3KBkAAJwblAwAAM4NSgYAAOfm/2WpVcaWc4fUAAAAAElFTkSuQmCC" alt="" />

1.2、ParameterMetaData元数据

  PreparedStatement.getParameterMetaData() 获得代表PreparedStatement元数据的ParameterMetaData对象。 
  Select * from user where name=? And password=?
  ParameterMetaData对象的常用方法:

  • getParameterCount(): 获得指定参数的个数
  • getParameterType(int param):获得指定参数的sql类型,MySQL数据库驱动不支持
  1. 1 /**
  2. 2 * @Method: testParameterMetaData
  3. 3 * @Description: 获取参数元信息
  4. 4 * @Anthor:孤傲苍狼
  5. 5 *
  6. 6 * @throws SQLException
  7. 7 */
  8. 8 @Test
  9. 9 public void testParameterMetaData() throws SQLException {
  10. 10 Connection conn = JdbcUtils.getConnection();
  11. 11 String sql = "select * from user wherer name=? and password=?";
  12. 12 //将SQL预编译一下
  13. 13 PreparedStatement st = conn.prepareStatement(sql);
  14. 14 ParameterMetaData pm = st.getParameterMetaData();
  15. 15 //getParameterCount() 获得指定参数的个数
  16. 16 System.out.println(pm.getParameterCount());
  17. 17 //getParameterType(int param):获得指定参数的sql类型,MySQL数据库驱动不支持
  18. 18 System.out.println(pm.getParameterType(1));
  19. 19 JdbcUtils.release(conn, null, null);
  20. 20 }

1.3、ResultSetMetaData元数据

  ResultSet. getMetaData() 获得代表ResultSet对象元数据的ResultSetMetaData对象。 
  ResultSetMetaData对象的常用方法:

  • getColumnCount() 返回resultset对象的列数
  • getColumnName(int column) 获得指定列的名称
  • getColumnTypeName(int column)获得指定列的类型
  1. 1 /**
  2. 2 * @Method: testResultSetMetaData
  3. 3 * @Description: 结果集的元数据
  4. 4 * @Anthor:孤傲苍狼
  5. 5 *
  6. 6 * @throws Exception
  7. 7 */
  8. 8 @Test
  9. 9 public void testResultSetMetaData() throws Exception {
  10. 10 Connection conn = JdbcUtils.getConnection();
  11. 11 String sql = "select * from account";
  12. 12 PreparedStatement st = conn.prepareStatement(sql);
  13. 13 ResultSet rs = st.executeQuery();
  14. 14 //ResultSet.getMetaData()获得代表ResultSet对象元数据的ResultSetMetaData对象
  15. 15 ResultSetMetaData metadata = rs.getMetaData();
  16. 16 //getColumnCount() 返回resultset对象的列数
  17. 17 System.out.println(metadata.getColumnCount());
  18. 18 //getColumnName(int column) 获得指定列的名称
  19. 19 System.out.println(metadata.getColumnName(1));
  20. 20 //getColumnTypeName(int column)获得指定列的类型
  21. 21 System.out.println(metadata.getColumnTypeName(1));
  22. 22 JdbcUtils.release(conn, st, rs);
  23. 23 }

二、使用元数据封装简单的JDBC框架

  系统中所有实体对象都涉及到基本的CRUD操作
  所有实体的CUD操作代码基本相同,仅仅发送给数据库的SQL语句不同而已,因此可以把CUD操作的所有相同代码抽取到工具类的一个update方法中,并定义参数接收变化的SQL语句。
  实体的R操作,除SQL语句不同之外,根据操作的实体不同,对ResultSet的映射也各不相同,因此可义一个query方法,除以参数形式接收变化的SQL语句外,可以使用策略模式由qurey方法的调用者决定如何把ResultSet中的数据映射到实体对象中。

2.1、封装通用的update方法和qurey方法

  定义一个JdbcUtils工具类,工具类负责获取数据库连接,释放资源,执行SQL的update和query操作,代码如下:

  1. 1 package me.gacl.util;
  2. 2
  3. 3 import java.io.InputStream;
  4. 4 import java.sql.Connection;
  5. 5 import java.sql.DriverManager;
  6. 6 import java.sql.PreparedStatement;
  7. 7 import java.sql.ResultSet;
  8. 8 import java.sql.SQLException;
  9. 9 import java.sql.Statement;
  10. 10 import java.util.Properties;
  11. 11
  12. 12 public class JdbcUtils {
  13. 13
  14. 14 private static String driver = null;
  15. 15 private static String url = null;
  16. 16 private static String username = null;
  17. 17 private static String password = null;
  18. 18
  19. 19 static{
  20. 20 try{
  21. 21 //读取db.properties文件中的数据库连接信息
  22. 22 InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
  23. 23 Properties prop = new Properties();
  24. 24 prop.load(in);
  25. 25
  26. 26 //获取数据库连接驱动
  27. 27 driver = prop.getProperty("driver");
  28. 28 //获取数据库连接URL地址
  29. 29 url = prop.getProperty("url");
  30. 30 //获取数据库连接用户名
  31. 31 username = prop.getProperty("username");
  32. 32 //获取数据库连接密码
  33. 33 password = prop.getProperty("password");
  34. 34
  35. 35 //加载数据库驱动
  36. 36 Class.forName(driver);
  37. 37
  38. 38 }catch (Exception e) {
  39. 39 throw new ExceptionInInitializerError(e);
  40. 40 }
  41. 41 }
  42. 42
  43. 43 /**
  44. 44 * @Method: getConnection
  45. 45 * @Description: 获取数据库连接对象
  46. 46 * @Anthor:孤傲苍狼
  47. 47 *
  48. 48 * @return Connection数据库连接对象
  49. 49 * @throws SQLException
  50. 50 */
  51. 51 public static Connection getConnection() throws SQLException{
  52. 52 return DriverManager.getConnection(url, username,password);
  53. 53 }
  54. 54
  55. 55 /**
  56. 56 * @Method: release
  57. 57 * @Description: 释放资源,
  58. 58 * 要释放的资源包括Connection数据库连接对象,负责执行SQL命令的Statement对象,存储查询结果的ResultSet对象
  59. 59 * @Anthor:孤傲苍狼
  60. 60 *
  61. 61 * @param conn
  62. 62 * @param st
  63. 63 * @param rs
  64. 64 */
  65. 65 public static void release(Connection conn,Statement st,ResultSet rs){
  66. 66 if(rs!=null){
  67. 67 try{
  68. 68 //关闭存储查询结果的ResultSet对象
  69. 69 rs.close();
  70. 70 }catch (Exception e) {
  71. 71 e.printStackTrace();
  72. 72 }
  73. 73 rs = null;
  74. 74 }
  75. 75 if(st!=null){
  76. 76 try{
  77. 77 //关闭负责执行SQL命令的Statement对象
  78. 78 st.close();
  79. 79 }catch (Exception e) {
  80. 80 e.printStackTrace();
  81. 81 }
  82. 82 }
  83. 83
  84. 84 if(conn!=null){
  85. 85 try{
  86. 86 //关闭Connection数据库连接对象
  87. 87 conn.close();
  88. 88 }catch (Exception e) {
  89. 89 e.printStackTrace();
  90. 90 }
  91. 91 }
  92. 92 }
  93. 93
  94. 94 /**
  95. 95 * @Method: update
  96. 96 * @Description: 万能更新
  97. 97 * 所有实体的CUD操作代码基本相同,仅仅发送给数据库的SQL语句不同而已,
  98. 98 * 因此可以把CUD操作的所有相同代码抽取到工具类的一个update方法中,并定义参数接收变化的SQL语句
  99. 99 * @Anthor:孤傲苍狼
  100. 100 * @param sql 要执行的SQL
  101. 101 * @param params 执行SQL时使用的参数
  102. 102 * @throws SQLException
  103. 103 */
  104. 104 public static void update(String sql,Object params[]) throws SQLException{
  105. 105 Connection conn = null;
  106. 106 PreparedStatement st = null;
  107. 107 ResultSet rs = null;
  108. 108 try{
  109. 109 conn = getConnection();
  110. 110 st = conn.prepareStatement(sql);
  111. 111 for(int i=0;i<params.length;i++){
  112. 112 st.setObject(i+1, params[i]);
  113. 113 }
  114. 114 st.executeUpdate();
  115. 115
  116. 116 }finally{
  117. 117 release(conn, st, rs);
  118. 118 }
  119. 119 }
  120. 120
  121. 121 /**
  122. 122 * @Method: query
  123. 123 * @Description:万能查询
  124. 124 * 实体的R操作,除SQL语句不同之外,根据操作的实体不同,对ResultSet的映射也各不相同,
  125. 125 * 因此可义一个query方法,除以参数形式接收变化的SQL语句外,可以使用策略模式由qurey方法的调用者决定如何把ResultSet中的数据映射到实体对象中。
  126. 126 * @Anthor:孤傲苍狼
  127. 127 *
  128. 128 * @param sql 要执行的SQL
  129. 129 * @param params 执行SQL时使用的参数
  130. 130 * @param rsh 查询返回的结果集处理器
  131. 131 * @return
  132. 132 * @throws SQLException
  133. 133 */
  134. 134 public static Object query(String sql,Object params[],ResultSetHandler rsh) throws SQLException{
  135. 135
  136. 136 Connection conn = null;
  137. 137 PreparedStatement st = null;
  138. 138 ResultSet rs = null;
  139. 139
  140. 140 try{
  141. 141 conn = getConnection();
  142. 142 st = conn.prepareStatement(sql);
  143. 143 for(int i=0;i<params.length;i++){
  144. 144 st.setObject(i+1, params[i]);
  145. 145 }
  146. 146 rs = st.executeQuery();
  147. 147 /**
  148. 148 * 对于查询返回的结果集处理使用到了策略模式,
  149. 149 * 在设计query方法时,query方法事先是无法知道用户对返回的查询结果集如何进行处理的,即不知道结果集的处理策略,
  150. 150 * 那么这个结果集的处理策略就让用户自己提供,query方法内部就调用用户提交的结果集处理策略进行处理
  151. 151 * 为了能够让用户提供结果集的处理策略,需要对用户暴露出一个结果集处理接口ResultSetHandler
  152. 152 * 用户只要实现了ResultSetHandler接口,那么query方法内部就知道用户要如何处理结果集了
  153. 153 */
  154. 154 return rsh.handler(rs);
  155. 155
  156. 156 }finally{
  157. 157 release(conn, st, rs);
  158. 158 }
  159. 159 }
  160. 160 }

  在设计query方法时,对于查询返回的结果集处理使用到了策略模式,query方法事先是无法知道用户对返回的查询结果集如何进行处理的,即不知道结果集的处理策略, 那么这个结果集的处理策略就让用户自己提供,query方法内部就调用用户提交的结果集处理策略进行处理, 为了能够让用户提供结果集的处理策略,需要对用户暴露出一个结果集处理接口ResultSetHandler, 结果集处理器接口ResultSetHandler的定义如下:

  1. 1 package me.gacl.util;
  2. 2
  3. 3 import java.sql.ResultSet;
  4. 4
  5. 5 /**
  6. 6 * @ClassName: ResultSetHandler
  7. 7 * @Description:结果集处理器接口
  8. 8 * @author: 孤傲苍狼
  9. 9 * @date: 2014-10-5 下午12:01:27
  10. 10 *
  11. 11 */
  12. 12 public interface ResultSetHandler {
  13. 13
  14. 14 /**
  15. 15 * @Method: handler
  16. 16 * @Description: 结果集处理方法
  17. 17 * @Anthor:孤傲苍狼
  18. 18 *
  19. 19 * @param rs 查询结果集
  20. 20 * @return
  21. 21 */
  22. 22 public Object handler(ResultSet rs);
  23. 23 }

  用户只要实现了ResultSetHandler接口,那么就是针对查询结果集写了一个处理器,在query方法内部就调用用户自己写的处理器处理结果集。

2.2、编写常用的结果集处理器

  为了提高框架的易用性,我们可以事先就针对结果集写好一些常用的处理器,比如将结果集转换成bean对象的处理器,将结果集转换成bean对象的list集合的处理器。

2.2.1、BeanHandler——将结果集转换成bean对象的处理器

  1. 1 package me.gacl.util;
  2. 2
  3. 3 import java.lang.reflect.Field;
  4. 4 import java.sql.ResultSet;
  5. 5 import java.sql.ResultSetMetaData;
  6. 6
  7. 7 /**
  8. 8 * @ClassName: BeanHandler
  9. 9 * @Description: 将结果集转换成bean对象的处理器
  10. 10 * @author: 孤傲苍狼
  11. 11 * @date: 2014-10-5 下午12:00:33
  12. 12 *
  13. 13 */
  14. 14 public class BeanHandler implements ResultSetHandler {
  15. 15 private Class<?> clazz;
  16. 16 public BeanHandler(Class<?> clazz){
  17. 17 this.clazz = clazz;
  18. 18 }
  19. 19 public Object handler(ResultSet rs) {
  20. 20 try{
  21. 21 if(!rs.next()){
  22. 22 return null;
  23. 23 }
  24. 24 Object bean = clazz.newInstance();
  25. 25 //得到结果集元数据
  26. 26 ResultSetMetaData metadata = rs.getMetaData();
  27. 27 int columnCount = metadata.getColumnCount();//得到结果集中有几列数据
  28. 28 for(int i=0;i<columnCount;i++){
  29. 29 String coulmnName = metadata.getColumnName(i+1);//得到每列的列名
  30. 30 Object coulmnData = rs.getObject(i+1);
  31. 31 Field f = clazz.getDeclaredField(coulmnName);//反射出类上列名对应的属性
  32. 32 f.setAccessible(true);
  33. 33 f.set(bean, coulmnData);
  34. 34 }
  35. 35 return bean;
  36. 36 }catch (Exception e) {
  37. 37 throw new RuntimeException(e);
  38. 38 }
  39. 39 }
  40. 40 }

2.2.2、BeanListHandler——将结果集转换成bean对象的list集合的处理器

  1. 1 package me.gacl.util;
  2. 2
  3. 3 import java.lang.reflect.Field;
  4. 4 import java.sql.ResultSet;
  5. 5 import java.sql.ResultSetMetaData;
  6. 6 import java.util.ArrayList;
  7. 7 import java.util.List;
  8. 8
  9. 9 /**
  10. 10 * @ClassName: BeanListHandler
  11. 11 * @Description: 将结果集转换成bean对象的list集合的处理器
  12. 12 * @author: 孤傲苍狼
  13. 13 * @date: 2014-10-5 下午12:00:06
  14. 14 *
  15. 15 */
  16. 16 public class BeanListHandler implements ResultSetHandler {
  17. 17 private Class<?> clazz;
  18. 18 public BeanListHandler(Class<?> clazz){
  19. 19 this.clazz = clazz;
  20. 20 }
  21. 21
  22. 22 public Object handler(ResultSet rs) {
  23. 23 try{
  24. 24 List<Object> list = new ArrayList<Object>();
  25. 25 while(rs.next()){
  26. 26 Object bean = clazz.newInstance();
  27. 27
  28. 28 ResultSetMetaData metadata = rs.getMetaData();
  29. 29 int count = metadata.getColumnCount();
  30. 30 for(int i=0;i<count;i++){
  31. 31 String name = metadata.getColumnName(i+1);
  32. 32 Object value = rs.getObject(name);
  33. 33
  34. 34 Field f = bean.getClass().getDeclaredField(name);
  35. 35 f.setAccessible(true);
  36. 36 f.set(bean, value);
  37. 37 }
  38. 38 list.add(bean);
  39. 39 }
  40. 40 return list.size()>0?list:null;
  41. 41
  42. 42 }catch (Exception e) {
  43. 43 throw new RuntimeException(e);
  44. 44 }
  45. 45 }
  46. 46 }

  当框架自身提供的结果集处理器不满足用户的要求时,那么用户就可以自己去实现ResultSetHandler接口,编写满足自己业务要求的结果集处理器。

  有了上述的JdbcUtils框架之后,针对单个实体对象CRUD操作就非常方便了,如下所示:

  1. 1 package me.gacl.dao;
  2. 2
  3. 3 import java.sql.SQLException;
  4. 4 import java.util.List;
  5. 5 import me.gacl.domain.Account;
  6. 6 import me.gacl.util.BeanHandler;
  7. 7 import me.gacl.util.BeanListHandler;
  8. 8 import me.gacl.util.JdbcUtils;
  9. 9
  10. 10 public class AccountDao {
  11. 11
  12. 12 public void add(Account account) throws SQLException{
  13. 13 String sql = "insert into account(name,money) values(?,?)";
  14. 14 Object params[] = {account.getName(),account.getMoney()};
  15. 15 JdbcUtils.update(sql, params);
  16. 16 }
  17. 17
  18. 18
  19. 19 public void delete(int id) throws SQLException{
  20. 20 String sql = "delete from account where id=?";
  21. 21 Object params[] = {id};
  22. 22 JdbcUtils.update(sql, params);
  23. 23 }
  24. 24
  25. 25 public void update(Account account) throws SQLException{
  26. 26
  27. 27 String sql = "update account set name=?,money=? where id=?";
  28. 28 Object params[] = {account.getName(),account.getMoney(),account.getId()};
  29. 29 JdbcUtils.update(sql, params);
  30. 30
  31. 31 }
  32. 32
  33. 33 public Account find(int id) throws SQLException{
  34. 34 String sql = "select * from account where id=?";
  35. 35 Object params[] = {id};
  36. 36 return (Account) JdbcUtils.query(sql, params, new BeanHandler(Account.class));
  37. 37 }
  38. 38
  39. 39 public List<Account> getAll() throws SQLException{
  40. 40 String sql = "select * from account";
  41. 41 Object params[] = {};
  42. 42 return (List<Account>) JdbcUtils.query(sql, params,new BeanListHandler(Account.class));
  43. 43 }
  44. 44 }

  编写的这个JDBC框架就是模拟Apache的DBUtils框架的实现,下一篇将具体介绍Apache的DBUtils框架。

编写自己的JDBC框架(转)的更多相关文章

  1. 【总结】编写自己的JDBC框架

    一.数据库连接池: 在一般用JDBC 进行连接数据库进行CRUD操作时,每一次都会: 通过:java.sql.Connection conn = DriverManager.getConnection ...

  2. javaweb学习总结(四十)——编写自己的JDBC框架

    一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...

  3. 编写自定义的JDBC框架与策略模式

    本篇根据上一篇利用数据库的几种元数据来仿造Apache公司的开源DbUtils工具类集合来编写自己的JDBC框架.也就是说在本篇中很大程度上的代码都和DbUtils中相似,学完本篇后即更容易了解DbU ...

  4. javaweb总结(四十)——编写自己的JDBC框架

    一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...

  5. java web学习总结(二十三) -------------------编写自己的JDBC框架

    一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...

  6. JDBC 学习复习10 编写自己的JDBC框架

    首先万分感谢狼哥 孤傲苍狼 博客,整个jdbc学习的博客资料 链接为http://www.cnblogs.com/xdp-gacl/p/4006830.html 详细代码见狼哥博客,列出我学习过程中遇 ...

  7. 编写自己的JDBC框架

    目的 简化代码,提高开发效率 设计模式 策略设计模式 代码 #连接设置 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost ...

  8. JDBC框架

    一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...

  9. Spring的JDBC框架

    转自: http://www.cnblogs.com/windlaughing/p/3287750.html Spring JDBC提供了一套JDBC抽象框架,用于简化JDBC开发. Spring主要 ...

随机推荐

  1. 个人总结OLinux上安装oracle11G Data Guard

    一.准备环境 1.swap要求 swap最好设置3G以上,如果安装过程中报swap不足,可参考: https://www.jianshu.com/p/46635a12c8d0 2.官网必须安装包列表: ...

  2. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十一章:模板测试

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十一章:模板测试 代码工程地址: https://github.co ...

  3. python 文本文件的写入

  4. hdu 1503 LCS输出路径【dp】

    hdu 1503 不知道最后怎么输出,因为公共部分只输出一次.有人说回溯输出,感觉好巧妙!其实就是下图,输出的就是那条灰色的路径,但是初始时边界一定要初始化一下,因为最第一列只能向上走,第一行只能向左 ...

  5. 2015 Objective-C 三大新特性

    http://www.cocoachina.com/ios/20150617/12148.html Overview 自 WWDC 2015 推出和开源 Swift 2.0 后,大家对 Swift 的 ...

  6. 无人驾驶——对frenet坐标的理解

    好的确定车和路之间的关系,我们通常将车辆的在大地坐标坐标转化为车辆和道路之间的frenet坐标. 可能有人会疑问为什么转换后就方便了呢?我们来看一个例子. 在大地坐标下: 无人车首先要知道红色车的位置 ...

  7. Hadoop应用程序示例2

  8. http://www.freeopensourcesoftware.org

    Applications http://www.freeopensourcesoftware.org/index.php?title=Applications   Main Page > Thi ...

  9. 洛谷 1602 Sramoc问题

    Description 话说员工们整理好了筷子之后,就准备将快餐送出了,但是一看订单,都傻眼了:订单上没有留电话号码,只写了一个sramoc(k,m)函数,这什么东西?什么意思?于是餐厅找来了资深顾问 ...

  10. 永久设置anaconda的环境变量

    安装anaconda后都显示install seccessful,可是输入anaconda 终端却显示“未找到命令” 原因是没有添加环境变量,按照如下方式将环境变量添加的安装路径下: emport P ...