最近看老罗的视频,跟着完成了利用Java操作MySql数据库的一个框架类JdbcUtils.java,完成对数据库的增删改查。其中查询这块,包括普通的查询和利用反射完成的查询,主要包括以下几个函数接口:

1、public Connection getConnection()   获得数据库的连接

2、public boolean updateByPreparedStatement(String sql, List<Object>params)throws SQLException  更新数据库,包括增加记录、删除记录、改动某个记录三个功能。

3、public Map<String, Object> findSimpleResult(String sql, List<Object> params) throws SQLException 查询单条记录,传进去的是一个List<Object>参数填充占位符,返回的是一个Map<String, Object>.一个Map对应一条完整的记录,String对应属性名,Object是属性值。

4、public List<Map<String, Object>> findModeResult(String sql, List<Object> params) throws SQLException 查询多条记录,放在List里。

上面四个函数已经包括了MySQl的所有操作,完全能够满足使用需要。视频里老罗还扩展了两个反射来查询的函数。

5、public <T> T findSimpleRefResult(String sql, List<Object> params,
Class<T> cls )throws Exception   利用反射查询单个记录。

6、 public <T> List<T> findMoreRefResult(String sql, List<Object> params,
Class<T> cls )throws Exception   利用反射查询多个记录。

下面附完整代码:

JdbcUtils.java

  1. <span style="font-size:18px;">package com.jdbc.dbutils;
  2. import java.lang.reflect.Field;
  3. import java.sql.Connection;
  4. import java.sql.DriverManager;
  5. import java.sql.PreparedStatement;
  6. import java.sql.ResultSet;
  7. import java.sql.ResultSetMetaData;
  8. import java.sql.SQLException;
  9. import java.util.ArrayList;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Map;
  13. import domain.UserInfo;
  14. public class JdbcUtils {
  15. //数据库用户名
  16. private static final String USERNAME = "root";
  17. //数据库密码
  18. private static final String PASSWORD = "yanzi";
  19. //驱动信息
  20. private static final String DRIVER = "com.mysql.jdbc.Driver";
  21. //数据库地址
  22. private static final String URL = "jdbc:mysql://localhost:3306/mydb";
  23. private Connection connection;
  24. private PreparedStatement pstmt;
  25. private ResultSet resultSet;
  26. public JdbcUtils() {
  27. // TODO Auto-generated constructor stub
  28. try{
  29. Class.forName(DRIVER);
  30. System.out.println("数据库连接成功!");
  31. }catch(Exception e){
  32. }
  33. }
  34. /**
  35. * 获得数据库的连接
  36. * @return
  37. */
  38. public Connection getConnection(){
  39. try {
  40. connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
  41. } catch (SQLException e) {
  42. // TODO Auto-generated catch block
  43. e.printStackTrace();
  44. }
  45. return connection;
  46. }
  47. /**
  48. * 增加、删除、改
  49. * @param sql
  50. * @param params
  51. * @return
  52. * @throws SQLException
  53. */
  54. public boolean updateByPreparedStatement(String sql, List<Object>params)throws SQLException{
  55. boolean flag = false;
  56. int result = -1;
  57. pstmt = connection.prepareStatement(sql);
  58. int index = 1;
  59. if(params != null && !params.isEmpty()){
  60. for(int i=0; i<params.size(); i++){
  61. pstmt.setObject(index++, params.get(i));
  62. }
  63. }
  64. result = pstmt.executeUpdate();
  65. flag = result > 0 ? true : false;
  66. return flag;
  67. }
  68. /**
  69. * 查询单条记录
  70. * @param sql
  71. * @param params
  72. * @return
  73. * @throws SQLException
  74. */
  75. public Map<String, Object> findSimpleResult(String sql, List<Object> params) throws SQLException{
  76. Map<String, Object> map = new HashMap<String, Object>();
  77. int index  = 1;
  78. pstmt = connection.prepareStatement(sql);
  79. if(params != null && !params.isEmpty()){
  80. for(int i=0; i<params.size(); i++){
  81. pstmt.setObject(index++, params.get(i));
  82. }
  83. }
  84. resultSet = pstmt.executeQuery();//返回查询结果
  85. ResultSetMetaData metaData = resultSet.getMetaData();
  86. int col_len = metaData.getColumnCount();
  87. while(resultSet.next()){
  88. for(int i=0; i<col_len; i++ ){
  89. String cols_name = metaData.getColumnName(i+1);
  90. Object cols_value = resultSet.getObject(cols_name);
  91. if(cols_value == null){
  92. cols_value = "";
  93. }
  94. map.put(cols_name, cols_value);
  95. }
  96. }
  97. return map;
  98. }
  99. /**查询多条记录
  100. * @param sql
  101. * @param params
  102. * @return
  103. * @throws SQLException
  104. */
  105. public List<Map<String, Object>> findModeResult(String sql, List<Object> params) throws SQLException{
  106. List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
  107. int index = 1;
  108. pstmt = connection.prepareStatement(sql);
  109. if(params != null && !params.isEmpty()){
  110. for(int i = 0; i<params.size(); i++){
  111. pstmt.setObject(index++, params.get(i));
  112. }
  113. }
  114. resultSet = pstmt.executeQuery();
  115. ResultSetMetaData metaData = resultSet.getMetaData();
  116. int cols_len = metaData.getColumnCount();
  117. while(resultSet.next()){
  118. Map<String, Object> map = new HashMap<String, Object>();
  119. for(int i=0; i<cols_len; i++){
  120. String cols_name = metaData.getColumnName(i+1);
  121. Object cols_value = resultSet.getObject(cols_name);
  122. if(cols_value == null){
  123. cols_value = "";
  124. }
  125. map.put(cols_name, cols_value);
  126. }
  127. list.add(map);
  128. }
  129. return list;
  130. }
  131. /**通过反射机制查询单条记录
  132. * @param sql
  133. * @param params
  134. * @param cls
  135. * @return
  136. * @throws Exception
  137. */
  138. public <T> T findSimpleRefResult(String sql, List<Object> params,
  139. Class<T> cls )throws Exception{
  140. T resultObject = null;
  141. int index = 1;
  142. pstmt = connection.prepareStatement(sql);
  143. if(params != null && !params.isEmpty()){
  144. for(int i = 0; i<params.size(); i++){
  145. pstmt.setObject(index++, params.get(i));
  146. }
  147. }
  148. resultSet = pstmt.executeQuery();
  149. ResultSetMetaData metaData  = resultSet.getMetaData();
  150. int cols_len = metaData.getColumnCount();
  151. while(resultSet.next()){
  152. //通过反射机制创建一个实例
  153. resultObject = cls.newInstance();
  154. for(int i = 0; i<cols_len; i++){
  155. String cols_name = metaData.getColumnName(i+1);
  156. Object cols_value = resultSet.getObject(cols_name);
  157. if(cols_value == null){
  158. cols_value = "";
  159. }
  160. Field field = cls.getDeclaredField(cols_name);
  161. field.setAccessible(true); //打开javabean的访问权限
  162. field.set(resultObject, cols_value);
  163. }
  164. }
  165. return resultObject;
  166. }
  167. /**通过反射机制查询多条记录
  168. * @param sql
  169. * @param params
  170. * @param cls
  171. * @return
  172. * @throws Exception
  173. */
  174. public <T> List<T> findMoreRefResult(String sql, List<Object> params,
  175. Class<T> cls )throws Exception {
  176. List<T> list = new ArrayList<T>();
  177. int index = 1;
  178. pstmt = connection.prepareStatement(sql);
  179. if(params != null && !params.isEmpty()){
  180. for(int i = 0; i<params.size(); i++){
  181. pstmt.setObject(index++, params.get(i));
  182. }
  183. }
  184. resultSet = pstmt.executeQuery();
  185. ResultSetMetaData metaData  = resultSet.getMetaData();
  186. int cols_len = metaData.getColumnCount();
  187. while(resultSet.next()){
  188. //通过反射机制创建一个实例
  189. T resultObject = cls.newInstance();
  190. for(int i = 0; i<cols_len; i++){
  191. String cols_name = metaData.getColumnName(i+1);
  192. Object cols_value = resultSet.getObject(cols_name);
  193. if(cols_value == null){
  194. cols_value = "";
  195. }
  196. Field field = cls.getDeclaredField(cols_name);
  197. field.setAccessible(true); //打开javabean的访问权限
  198. field.set(resultObject, cols_value);
  199. }
  200. list.add(resultObject);
  201. }
  202. return list;
  203. }
  204. /**
  205. * 释放数据库连接
  206. */
  207. public void releaseConn(){
  208. if(resultSet != null){
  209. try{
  210. resultSet.close();
  211. }catch(SQLException e){
  212. e.printStackTrace();
  213. }
  214. }
  215. }
  216. /**
  217. * @param args
  218. */
  219. public static void main(String[] args) throws SQLException {
  220. // TODO Auto-generated method stub
  221. JdbcUtils jdbcUtils = new JdbcUtils();
  222. jdbcUtils.getConnection();
  223. /*******************增*********************/
  224. /*      String sql = "insert into userinfo (username, pswd) values (?, ?), (?, ?), (?, ?)";
  225. List<Object> params = new ArrayList<Object>();
  226. params.add("小明");
  227. params.add("123xiaoming");
  228. params.add("张三");
  229. params.add("zhangsan");
  230. params.add("李四");
  231. params.add("lisi000");
  232. try {
  233. boolean flag = jdbcUtils.updateByPreparedStatement(sql, params);
  234. System.out.println(flag);
  235. } catch (SQLException e) {
  236. // TODO Auto-generated catch block
  237. e.printStackTrace();
  238. }*/
  239. /*******************删*********************/
  240. //删除名字为张三的记录
  241. /*      String sql = "delete from userinfo where username = ?";
  242. List<Object> params = new ArrayList<Object>();
  243. params.add("小明");
  244. boolean flag = jdbcUtils.updateByPreparedStatement(sql, params);*/
  245. /*******************改*********************/
  246. //将名字为李四的密码改了
  247. /*      String sql = "update userinfo set pswd = ? where username = ? ";
  248. List<Object> params = new ArrayList<Object>();
  249. params.add("lisi88888");
  250. params.add("李四");
  251. boolean flag = jdbcUtils.updateByPreparedStatement(sql, params);
  252. System.out.println(flag);*/
  253. /*******************查*********************/
  254. //不利用反射查询多个记录
  255. /*      String sql2 = "select * from userinfo ";
  256. List<Map<String, Object>> list = jdbcUtils.findModeResult(sql2, null);
  257. System.out.println(list);*/
  258. //利用反射查询 单条记录
  259. String sql = "select * from userinfo where username = ? ";
  260. List<Object> params = new ArrayList<Object>();
  261. params.add("李四");
  262. UserInfo userInfo;
  263. try {
  264. userInfo = jdbcUtils.findSimpleRefResult(sql, params, UserInfo.class);
  265. System.out.print(userInfo);
  266. } catch (Exception e) {
  267. // TODO Auto-generated catch block
  268. e.printStackTrace();
  269. }
  270. }
  271. }
  272. </span>

根据上面代码可以看到,数据库名字:mydb,表名:userinfo,结构如下:

+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(11)     | NO   | PRI | NULL    | auto_increment |
| username | varchar(64) | YES  |     | NULL    |                |
| pswd     | varchar(64) | YES  |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+

是用Nvicat提前创建好的:

因为有两个接口用到了反射,因此对应的JavaBean UserInfo.java代码如下:

  1. <span style="font-size:18px;">package domain;
  2. import java.io.Serializable;
  3. public class UserInfo implements Serializable{
  4. /**
  5. *
  6. */
  7. private static final long serialVersionUID = 1L;
  8. private int id;
  9. private String username;
  10. private String pswd;
  11. public UserInfo() {
  12. // TODO Auto-generated constructor stub
  13. }
  14. public int getId() {
  15. return id;
  16. }
  17. public void setId(int id) {
  18. this.id = id;
  19. }
  20. public String getUsername() {
  21. return username;
  22. }
  23. public void setUsername(String username) {
  24. this.username = username;
  25. }
  26. public String getPswd() {
  27. return pswd;
  28. }
  29. public void setPswd(String pswd) {
  30. this.pswd = pswd;
  31. }
  32. @Override
  33. public String toString() {
  34. return "UserInfo [id=" + id + ", username=" + username + ", pswd="
  35. + pswd + "]";
  36. }
  37. }
  38. </span>

补充说明:

1. 在安装完mysql-connector-java-gpl-5.1.26.exe后会发现找不到jar包,其实jar文件在C:\Program Files\MySQL\MySQL Connector J目录下,有两个jar包:

用哪一个都ok。在Java工程里新建一个文件夹libs,然后将mysql-connector-java-5.1.26-bin.jar拷贝过去,右键单击 add to build path就ok了。

2.抛开这个框架类JdbcUtils.java来说,操作数据库的一般性步骤如下:

(1)连接数据库,加载驱动: Class.forName(DRIVER); DRIVER = "com.mysql.jdbc.Driver";这本身就是反射!!

(2) 利用用户名和密码及数据库的名字连接,这一步才是真正的连接:

connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);

其中:String URL = "jdbc:mysql://localhost:3306/mydb";

(3)编写一个sql语句,其中的参数用?来代替,然后将参数写到List里。

执行:pstmt = connection.prepareStatement(sql); 然后将参数从list里取出来填充到pstmt里。

(4)如果是增、删、改执行:result = pstmt.executeUpdate(); 其中的result是执行完影响的数据库里的行数,也即几条记录。如果是查询执行:resultSet = pstmt.executeQuery(); 返回的类型是ResultSet类型。之后就是把resultSet 弄成Map或List<Map>传递出去,给查询者看。

3.关于查询操作,在得到resultSet后利用getMetaData得到表的结构信息,如getColumnCount()得到有多少个列。String cols_name = metaData.getColumnName(i+1); 得到每个列的属性名称,如是id、username还是pswd.然后从Object cols_value = resultSet.getObject(cols_name);取出来,放到Map或List<Map>里。

4.关于查询里利用的反射操作,步骤如下:

(1) T resultObject = cls.newInstance(); 利用class文件的newInstance()方法创建一个实例。

(2)在通过getColumnCount()得到有多少个列之后,进入循环,

String cols_name = metaData.getColumnName(i+1);
                 Object cols_value = resultSet.getObject(cols_name);

读取每一列的属性名字和放的值。通过属性的名字cols_name进行反射:Field field = cls.getDeclaredField(cols_name);这样就得到了Field 等于类里的成员变量,field.setAccessible(true); //打开javabean的访问权限 在利用set方法将从数据库中查出来的cols_value通过JavaBean 也即定义的UserInfo这个类的 set方法赋进去。field.set(resultObject, cols_value);

5.一般意义上,要利用Java的反射需要以下步骤

(1)加载Class对象,这个一般有两种方式:Class cls1 = UserInfo.class  或

Class cls2 = Class.forName("domain.UserInfo") 后者是利用包名+类名的方法。

(2)反射出来Class之后干啥事呢?一个类不外乎构造函数、成员变量、成员函数。所以得到Class之后就可以干这三件事。

A、关于构造函数,获得Constructor 有四种方法:

Constructor getConstructor(Class[] params)

Constructor[] getConstructors()

Constructor getDeclaredConstructor(Class[] params)

Constructor[] getDeclaredConstructors()

这四个函数,如果不传参数则是获得所有的构造函数,得到的是一个集合。如果传特定的参数,则是寻找这个特定的构造函数,不带Declared是获得公共的public,带了Declared是可以获得私有构造函数。 得到构造函数后就可以利用反射创建实例了:

Constructor con1[] = cls1.getDeclaredConstructors();
         con1[1].setAccessible(true);
     Object obj1 = con1[1].newInstance(new Object[]{"tom"}); 如果直接调用clcs.newInstance()则是用默认的构造函数创建实例。

B、关于成员变量,同样有四种方法:

public Field getDeclaredField(String name)  获取任意指定名字的成员
public Field[] getDeclaredFields()          获取所有的成员变量
public Field getField(String name)          获取任意public成员变量
public Field[] getFields()                  获取所有的public成员变量

本文封装的JdbcUtils类就是利用这种方式操作类里的私有成员变量,记得要setAccessible打开开关。如下:

Field field = cls.getDeclaredField(cols_name);
field.setAccessible(true); //打开javabean的访问权限
field.set(resultObject, cols_value);

C、关于成员函数,也有四种方法:

public Method[] getMethods()    获取所有的共有方法的集合
public Method getMethod(String name,Class<?>... parameterTypes) 获取指定公有方法 ,

参数1:方法名 参数2:参数类型集合  
public Method[] getDeclaredMethods()  获取所有的方法
public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 获取任意指定方法

下面是利用文中的UserInfo这个类写的一个完成的反射例子,拿到setUsername(String username)方法,然后反射。再拿到getUsername()方法再反射,然后打印出结果:

Class clcs = UserInfo.class;
try {
Object obj = clcs.newInstance();
Method f = clcs.getDeclaredMethod("setUsername", String.class);
f.invoke(obj, "yan123");
Method f2 = clcs.getDeclaredMethod("getUsername", null);
Object name = f2.invoke(obj, null);
System.out.println("反射得到的名字 = "  +  name);

} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

在反射方法的时候,Method f = clcs.getDeclaredMethod("setUsername", String.class); 原函数里的输入参数是什么类型,就写什么类型.class. 如原来的setXXX需要输入参数String,反射的时候就写String.class.

6. JavaBean是反射的一种,反射对构造函数之类的没任何要求,JavaBean要求这个类必须继承Serializable即可串行化,另外构造函数必须为public. 另外,就是JavaBean在得到某个field后可以直接调用set和get,而不必再反射得到method后再执行。

    最后,反射是在程序运行的时候而非编译时!!!

参考:链接1 链接2 链接3

文中代码下载链接:http://download.csdn.net/detail/yanzi1225627/7398533

利用Java针对MySql封装的jdbc框架类 JdbcUtils 完整实现(包含增删改查、JavaBean反射原理,附源码)的更多相关文章

  1. 利用Java针对MySql封装的jdbc框架类 JdbcUtils 完整实现(包括增删改查、JavaBean反射原理,附源代码)

    近期看老罗的视频,跟着完毕了利用Java操作MySql数据库的一个框架类JdbcUtils.java,完毕对数据库的增删改查.当中查询这块,包含普通的查询和利用反射完毕的查询,主要包含以下几个函数接口 ...

  2. Java数据库连接——JDBC基础知识(操作数据库:增删改查)

    一.JDBC简介 JDBC是连接java应用程序和数据库之间的桥梁. 什么是JDBC? Java语言访问数据库的一种规范,是一套API. JDBC (Java Database Connectivit ...

  3. 使用jdbc实现简单的mvc模式的增删改查

    Mvc模式设计: 视图:添加界面(addUser.jsp),修改界面(updateUser.jsp),显示页面(allUser.jsp) 控制器:添加信息控制器(AddUserServlet),修改信 ...

  4. Django框架(八)--单表增删改查,在Python脚本中调用Django环境

    一.数据库连接配置 如果连接的是pycharm默认的Sqlite,不用改动,使用默认配置即可 如果连接mysql,需要在配置文件中的setting中进行配置: 将DATABASES={} 更新为 DA ...

  5. Django框架(九)—— 单表增删改查,在Python脚本中调用Django环境

    目录 单表增删改查,在Python脚本中调用Django环境 一.数据库连接配置 二.orm创建表和字段 三.单表增删改查 1.增加数据 2.删除数据 3.修改数据 4.查询数据 四.在Python脚 ...

  6. 针对MySql封装的JDBC通用框架类(包含增删改查、JavaBean反射原理)

    package com.DBUtils; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.Dri ...

  7. 利用Hibernate 框架,实现对数据库的增删改查

    增: package com.maya.test; import org.hibernate.*; import org.hibernate.cfg.*; import com.maya.model. ...

  8. jdbc的连接数据库,使用PreparedStatement实现增删改查等接口

    首先是连接,关闭资源等数据库操作 将连接数据库,关闭资源封装在JDBCUtils里 package jdbc.utils; import java.sql.Connection; import jav ...

  9. 封装MySQL的单例,连接数据库并对数据进行增删改查操作

    单例: 一个类只能有一个对象 应用场景:多次请求数据库只需要一个连接对象. 实现:三私一公 1.私有的静态属性用来保存对象的单例2.私有的构造方法用来阻止在类的外部实例化3.私有的__clone阻止在 ...

随机推荐

  1. HDU 4334 Trouble (暴力)

    Trouble Time Limit: 5000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Statu ...

  2. July 27th, Week 31st Wednesday, 2016

    Don't let yesterday take up too much of today. 别让昨天的事情占据今天太多时间. Learn from yesterday, but don't let ...

  3. jQuery工具函数

    要点:1.字符串操作2.数组和对象操作3.测试操作4.URL 操作5.浏览器检测6.其他操作 工具函数是指直接依附于 jQuery 对象,针对 jQuery 对象本身定义的方法,即全局性的函数.它的作 ...

  4. jQuery操作DOM和CSS函数

    function des html jquery result html() 获取元素中HTML内容 <div id="box" style="color:red& ...

  5. ScrollView与TableView实现选择效果

    在cocos2dx中,ScrollView与TableView都可以实现选择效果,其中ScrollView较为原始,TableView的格子大小可以不与winSize一样大. ScrollView实现 ...

  6. hadoop配置文件加载顺序(转)

    原文  http://www.cnblogs.com/wolfblogs/p/4147485.html 用了一段时间的hadoop,现在回来看看源码发现别有一番味道,温故而知新,还真是这样的 在使用h ...

  7. ***阿里云linux 下怎么配置虚拟主机

    最近有个问题,本人在阿里云买了linux服务器,用wordpress做了一个博客网站www.bravetiger.cn,现在想加一个电商系统进去,假设二级域名为:shop.bravetiger.cn, ...

  8. hdu 4004 二分 2011大连赛区网络赛D

    题意:一个长为L的河,中间有n个石子,小青蛙需要跳少于m次过河,判断小青蛙每次跳跃最大距离的最小值 最大值最小,用二分 Sample Input 6 1 2 2 25 3 3 11 2 18 Samp ...

  9. Struts表单格局;theme三个属性值:simple,xhtml,css_xhtml

    转自:http://www.educity.cn/wenda/7156.html 解决Struts2 Form表单自己布局之前先看看 theme 属性, theme属性提供 三个属性值:simple, ...

  10. 【spring 配置文件】spring配置文件的解析

    一.总体结构 二.详解 1.spring <alias >标签 在对bean进行定义时,除了使用id属性来指定名称之外,为了提供多个名称,可以使用alias标签来指定.而所有的这些名称都指 ...