Maison base de données tutoriel mysql 利用Java针对MySql封装的jdbc框架类JdbcUtils完整实现(包含增删_MySQL

利用Java针对MySql封装的jdbc框架类JdbcUtils完整实现(包含增删_MySQL

Jun 01, 2016 pm 01:13 PM

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

1、public Connection getConnection() 获得数据库的连接
2、public boolean updateByPreparedStatement(String sql, List
3、public Map
4、public List<Map
Copier après la connexion

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

5、public

6、 public

下面附完整代码:

JdbcUtils.java

package com.jdbc.dbutils;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;import java.sql.SQLException;
import java.util.ArrayList;import java.util.HashMap;
import java.util.List;import java.util.Map;
import domain.UserInfo;
public class JdbcUtils {	//数据库用户名	
private static final String USERNAME = "root";	//数据库密码	
private static final String PASSWORD = "yanzi";	//驱动信息 	
private static final String DRIVER = "com.mysql.jdbc.Driver";	//数据库地址	
private static final String URL = "jdbc:mysql://localhost:3306/mydb";	
private Connection connection;	
private PreparedStatement pstmt;	
private ResultSet resultSet;	
public JdbcUtils() {		// TODO Auto-generated constructor stub		
try{			
Class.forName(DRIVER);			
System.out.println("数据库连接成功!");		
}catch(Exception e){		
}	
}		
/**	 
* 获得数据库的连接	 
* @return	 
*/	
public Connection getConnection(){		
try {			
connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);		
} 
catch (SQLException e) {			// TODO Auto-generated catch block			
e.printStackTrace();		
}		
return connection;	
}		
/**	 
* 增加、删除、改	 
* @param sql	 
* @param params	 
* @return	 
* @throws SQLException	 
*/	
public boolean updateByPreparedStatement(String sql, Listparams)throws SQLException{		
boolean flag = false;		
int result = -1;		
pstmt = connection.prepareStatement(sql);		
int index = 1;		
if(params != null && !params.isEmpty()){			
for(int i=0; i0 ? true : false;		
return flag;	
}	
/**	 
* 查询单条记录	 
* @param sql	 
* @param params	 
* @return	 
* @throws SQLException	 
*/	
public MapfindSimpleResult(String sql, Listparams) throws SQLException{		
Mapmap = new HashMap();		
int index  = 1;		
pstmt = connection.prepareStatement(sql);		
if(params != null && !params.isEmpty()){			
for(int i=0; i<params.size(); i++){				
pstmt.setObject(index++, params.get(i));			
}		
}		
resultSet = pstmt.executeQuery();//返回查询结果		
ResultSetMetaData metaData = resultSet.getMetaData();		
int col_len = metaData.getColumnCount();		
while(resultSet.next()){			
for(int i=0; i<col_len; i++ ){				
String cols_name = metaData.getColumnName(i+1);				
Object cols_value = resultSet.getObject(cols_name);				
if(cols_value == null){					
cols_value = "";				
}				
map.put(cols_name, cols_value);			
}		
}		
return map;	
}	
/**查询多条记录	 
* @param sql	 
* @param params	 
* @return	 
* @throws SQLException	 
*/	
public List<Map> findModeResult(String sql, Listparams) throws SQLException{		
List<Map> list = new ArrayList<Map>();		
int index = 1;		
pstmt = connection.prepareStatement(sql);		
if(params != null && !params.isEmpty()){			
for(int i = 0; i<params.size(); i++){				
pstmt.setObject(index++, params.get(i));			
}		
}		
resultSet = pstmt.executeQuery();		
ResultSetMetaData metaData = resultSet.getMetaData();		
int cols_len = metaData.getColumnCount();		
while(resultSet.next()){			
Mapmap = new HashMap();			
for(int i=0; i<cols_len; i++){				
String cols_name = metaData.getColumnName(i+1);				
Object cols_value = resultSet.getObject(cols_name);				
if(cols_value == null){					
cols_value = "";				
}				
map.put(cols_name, cols_value);			
}			
list.add(map);		
}		
return list;	
}	
/**通过反射机制查询单条记录	 
* @param sql	 
* @param params	 
* @param cls	
* @return	
* @throws Exception	 
*/	
public T findSimpleRefResult(String sql, Listparams,			
Classcls )throws Exception{		
T resultObject = null;		
int index = 1;		
pstmt = connection.prepareStatement(sql);		
if(params != null && !params.isEmpty()){			
for(int i = 0; i<params.size(); i++){				
pstmt.setObject(index++, params.get(i));			
}		
}		
resultSet = pstmt.executeQuery();		
ResultSetMetaData metaData  = resultSet.getMetaData();		
int cols_len = metaData.getColumnCount();		
while(resultSet.next()){			//通过反射机制创建一个实例			
resultObject = cls.newInstance();			
for(int i = 0; i<cols_len; i++){				
String cols_name = metaData.getColumnName(i+1);				
Object cols_value = resultSet.getObject(cols_name);				
if(cols_value == null){					
cols_value = "";				
}				
Field field = cls.getDeclaredField(cols_name);				
field.setAccessible(true); //打开javabean的访问权限				
field.set(resultObject, cols_value);			
}		
}		
return resultObject;	
}	
/**通过反射机制查询多条记录	 
* @param sql 	 
* @param params	 
* @param cls	 
* @return	 
* @throws Exception	 
*/	
public ListfindMoreRefResult(String sql, Listparams,			
Classcls )throws Exception {		
Listlist = new ArrayList();		
int index = 1;		
pstmt = connection.prepareStatement(sql);		
if(params != null && !params.isEmpty()){			
for(int i = 0; i<params.size(); i++){				
pstmt.setObject(index++, params.get(i));			
}		
}		
resultSet = pstmt.executeQuery();		
ResultSetMetaData metaData  = resultSet.getMetaData();		
int cols_len = metaData.getColumnCount();		
while(resultSet.next()){			
//通过反射机制创建一个实例			
T resultObject = cls.newInstance();			
for(int i = 0; i<cols_len; i++){				
String cols_name = metaData.getColumnName(i+1);				
Object cols_value = resultSet.getObject(cols_name);				
if(cols_value == null){					
cols_value = "";				
}				
Field field = cls.getDeclaredField(cols_name);				
field.setAccessible(true); //打开javabean的访问权限				
field.set(resultObject, cols_value);			
}			
list.add(resultObject);		
}		
return list;	
}	
/**	 
* 释放数据库连接	 
*/	
public void releaseConn(){		
if(resultSet != null){			
try{				
resultSet.close();			
}catch(SQLException e){				
e.printStackTrace();			
}		
}	
}	
/**	 
* @param args	 
*/	
public static void main(String[] args) throws SQLException {		
// TODO Auto-generated method stub		
JdbcUtils jdbcUtils = new JdbcUtils();		
jdbcUtils.getConnection();		
/*******************增*********************/		
/*		
String sql = "insert into userinfo (username, pswd) values (?, ?), (?, ?), (?, ?)";		
Listparams = new ArrayList();		
params.add("小明");		
params.add("123xiaoming");		
params.add("张三");		
params.add("zhangsan");		
params.add("李四");		
params.add("lisi000");		
try {			
boolean flag = jdbcUtils.updateByPreparedStatement(sql, params);			
System.out.println(flag);		
} 
catch (SQLException e) {			
// TODO Auto-generated catch block			
e.printStackTrace();		
}
*/		
/*******************删*********************/		
//删除名字为张三的记录		
/*		
String sql = "delete from userinfo where username = ?";		
Listparams = new ArrayList();		
params.add("小明");		
boolean flag = jdbcUtils.updateByPreparedStatement(sql, params);
*/		
/*******************改*********************/		
//将名字为李四的密码改了		
/*		
String sql = "update userinfo set pswd = ? where username = ? ";		
Listparams = new ArrayList();		
params.add("lisi88888");		
params.add("李四");		
boolean flag = jdbcUtils.updateByPreparedStatement(sql, params);		
System.out.println(flag);
*/		
/*******************查*********************/		
//不利用反射查询多个记录		
/*		
String sql2 = "select * from userinfo ";		
List<Map> list = jdbcUtils.findModeResult(sql2, null);		
System.out.println(list);
*/		
//利用反射查询 单条记录		
String sql = "select * from userinfo where username = ? ";		
Listparams = new ArrayList();		
params.add("李四");		
UserInfo userInfo;		
try {			
userInfo = jdbcUtils.findSimpleRefResult(sql, params, UserInfo.class);			
System.out.print(userInfo);		
} 
catch (Exception e) {			
// TODO Auto-generated catch block			
e.printStackTrace();		
}	
}
}
Copier après la connexion

+----------+-------------+------+-----+---------+----------------+

是用Nvicat提前创建好的:

/

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

package domain;
import java.io.Serializable;
public class UserInfo implements Serializable{
/** 
*  
*/
private static final long serialVersionUID = 1L;
private int id;private String username;
private String pswd;
public UserInfo() {// TODO Auto-generated constructor stub}
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public String getUsername() 
{return username;}
public void setUsername(String username) 
{this.username = username;}
public String getPswd() {return pswd;}
public void setPswd(String pswd) {this.pswd = pswd;}
@Override
public String toString() 
{return "UserInfo [id=" + id + ", username=" + username + ", pswd="+ pswd + "]";
}
}
Copier après la connexion

补充说明:

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);
Copier après la connexion

其中: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

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

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

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

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

String cols_name = metaData.getColumnName(i+1);
Copier après la connexion

读取每一列的属性名字和放的值。通过属性的名字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()
Copier après la connexion

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

Constructor con1[] = cls1.getDeclaredConstructors();
Copier après la connexion

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

public Field getDeclaredField(String name) 获取任意指定名字的成员

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

Field field = cls.getDeclaredField(cols_name);
Copier après la connexion

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

public Method[] getMethods() 获取所有的共有方法的集合

参数1:方法名 参数2:参数类型集合

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

Class clcs = UserInfo.class;
Copier après la connexion

在反射方法的时候,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

以上就是利用Java针对MySql封装的jdbc框架类JdbcUtils完整实现(包含增删_MySQL的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Où trouver la courte de la grue à atomide atomique
1 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Racine carrée en Java Racine carrée en Java Aug 30, 2024 pm 04:26 PM

Guide de la racine carrée en Java. Nous discutons ici du fonctionnement de Square Root en Java avec un exemple et son implémentation de code respectivement.

Nombre parfait en Java Nombre parfait en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Générateur de nombres aléatoires en Java Générateur de nombres aléatoires en Java Aug 30, 2024 pm 04:27 PM

Guide du générateur de nombres aléatoires en Java. Nous discutons ici des fonctions en Java avec des exemples et de deux générateurs différents avec d'autres exemples.

Numéro Armstrong en Java Numéro Armstrong en Java Aug 30, 2024 pm 04:26 PM

Guide du numéro Armstrong en Java. Nous discutons ici d'une introduction au numéro d'Armstrong en Java ainsi que d'une partie du code.

Weka en Java Weka en Java Aug 30, 2024 pm 04:28 PM

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Numéro de Smith en Java Numéro de Smith en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Questions d'entretien chez Java Spring Questions d'entretien chez Java Spring Aug 30, 2024 pm 04:29 PM

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Break or Return of Java 8 Stream Forach? Break or Return of Java 8 Stream Forach? Feb 07, 2025 pm 12:09 PM

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

See all articles