`
beat_it_
  • 浏览: 64135 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java操作mysql实现增删改查

    博客分类:
  • java
阅读更多

http://blog.csdn.net/yanzi1225627/article/details/26950615摘了 篇文章,具体如下:

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

 

最近看老罗的视频,跟着完成了利用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

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, List<Object>params)throws SQLException{
		boolean flag = false;
		int result = -1;
		pstmt = connection.prepareStatement(sql);
		int index = 1;
		if(params != null && !params.isEmpty()){
			for(int i=0; i<params.size(); i++){
				pstmt.setObject(index++, params.get(i));
			}
		}
		result = pstmt.executeUpdate();
		flag = result > 0 ? true : false;
		return flag;
	}

	/**
	 * 查询单条记录
	 * @param sql
	 * @param params
	 * @return
	 * @throws SQLException
	 */
	public Map<String, Object> findSimpleResult(String sql, List<Object> params) throws SQLException{
		Map<String, Object> map = new HashMap<String, Object>();
		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<String, Object>> findModeResult(String sql, List<Object> params) throws SQLException{
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		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()){
			Map<String, Object> map = new HashMap<String, Object>();
			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> T findSimpleRefResult(String sql, List<Object> params,
			Class<T> cls )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 <T> List<T> findMoreRefResult(String sql, List<Object> params,
			Class<T> cls )throws Exception {
		List<T> list = new ArrayList<T>();
		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 (?, ?), (?, ?), (?, ?)";
		List<Object> params = new ArrayList<Object>();
		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 = ?";
		List<Object> params = new ArrayList<Object>();
		params.add("小明");
		boolean flag = jdbcUtils.updateByPreparedStatement(sql, params);*/

		/*******************改*********************/
		//将名字为李四的密码改了
		/*		String sql = "update userinfo set pswd = ? where username = ? ";
		List<Object> params = new ArrayList<Object>();
		params.add("lisi88888");
		params.add("李四");
		boolean flag = jdbcUtils.updateByPreparedStatement(sql, params);
		System.out.println(flag);*/

		/*******************查*********************/
		//不利用反射查询多个记录
		/*		String sql2 = "select * from userinfo ";
		List<Map<String, Object>> list = jdbcUtils.findModeResult(sql2, null);
		System.out.println(list);*/

		//利用反射查询 单条记录
		String sql = "select * from userinfo where username = ? ";
		List<Object> params = new ArrayList<Object>();
		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();
		}


	}

}

 

根据上面代码可以看到,数据库名字: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代码如下:

<span style="font-size: 18px;">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 + "]";
	}





}
</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 使用jdbc 连接mysql 实现增删改查

    java 使用jdbc 连接mysql 实现增删改查java 使用jdbc 连接mysql 实现增删改查java 使用jdbc 连接mysql 实现增删改查java 使用jdbc 连接mysql 实现增删改查java 使用jdbc 连接mysql 实现增删改查

    java操作mysql实现增删改查的方法

    在本文中,我们将详细介绍 Java 操作 MySQL 实现增删改查的方法,并且结合实例形式分析了 Java 操作 MySQL 数据库进行增删改查的具体实现技巧与相关注意事项。 首先,需要把 MySQL 与 Java 连接的 JAR 包(mysql-...

    java连接mysql的 gui图形界 面实现增删改查

    在Java编程中,连接MySQL数据库并实现GUI图形界面的增删改查功能是一项常见的任务,尤其在开发桌面应用时。这个任务涉及到多个知识点,包括Java的数据库连接、Swing或JavaFX图形界面库的使用、SQL语言以及多线程处理...

    简单的jsp+mysql实现数据库的增删改查

    综上所述,"简单的jsp+mysql实现数据库的增删改查"项目涵盖了Web开发的基本流程,包括用户交互、服务器处理、数据库操作以及权限控制。这样的实践有助于开发者理解Web应用的工作原理,同时为更复杂的系统开发打下...

    JSP页面连接mysql实现增删改查简单实例

    ### JSP页面连接MySQL实现增删改查简单实例 #### 一、背景介绍 在Web开发中,经常需要处理数据库的操作,例如增加、删除、修改和查询数据等基本操作(通常称为CRUD操作)。Java Server Pages (JSP) 是一种用于生成...

    spring boot maven 连接mysql实现增删改查

    这篇文章将深入探讨如何在MyEclipse环境中使用这些技术实现一个简单的数据管理应用,即增删改查(CRUD)功能。 首先,`Spring Boot`是Spring框架的简化版本,它提供了快速构建独立的、生产级别的基于Spring的应用...

    Java之JDBC连接MySQL数据库实现增删改查(2018 使用Dao层实现 完美封装解决硬编码问题 使用预编译对象PreparedStatement)

    Java之JDBC连接数据库实现增删改查(2018 使用Dao层实现 完美封装解决硬编码问题 使用预编译对象PreparedStatement) 配置文件 db.properties(保存数据库账号和密码等) 工具类 JDBCUtil.java(抽取公共部分,解决硬...

    java连接mysql数据库 增删改查

    在Java编程中,连接MySQL数据库并执行增删改查(CRUD)操作是常见的任务,尤其是在开发基于数据库的Web应用程序时。以下是对标题和描述中所述知识点的详细说明: 1. **Java数据库连接(JDBC)**: JDBC是Java平台的...

    java 数据库 mysql 增删改查

    本知识点主要聚焦于使用Java进行MySQL数据库的增删改查(CRUD)操作。这些基本操作是任何数据驱动应用程序的基础,无论是简单的信息管理还是复杂的业务逻辑处理。 首先,我们需要了解Java与MySQL交互的基本原理。...

    Java MySQL 图形界面增删改查功能全部代码.pdf

    Java MySQL 图形界面增删改查功能全部代码

    Java-Swing+Mysql+增删改查Demo

    总之,"Java-Swing+Mysql+增删改查Demo"是一个结合了Java GUI编程和数据库操作的实例,它展示了如何使用Swing构建用户界面,并通过MySQL进行数据管理,对于初学者来说,这是一个很好的学习资源,可以帮助理解Java...

    java+swing入门级增删改查源码

    通过学习和实践这个Java+Swing入门级增删改查源码,开发者可以快速掌握Swing的基本用法,理解如何处理用户交互,以及如何进行简单的文件操作。进一步,可以扩展此基础,学习更高级的Swing特性,如模型视图控制器...

    java连接数据库实现增删改查 教师管理系统

    在Java编程中,连接数据库并实现增删改查(CRUD)操作是常见的任务,尤其在构建管理系统如教师管理系统时。下面将详细讲解这个过程涉及的关键知识点。 首先,要连接数据库,我们需要使用Java的JDBC(Java Database ...

    jsp+servlet+mysql实现简单的增删改查+分页

    Servlet会通过JDBC(Java Database Connectivity)接口与MySQL进行通信,执行SQL语句来实现数据的增删改查。 **分页** 是为了提高用户体验和性能,将大量数据分批显示的技术。在这个项目中,分页可能是通过查询特定...

    mysql 增删改查

    2、直接调用动软的相关dll和生成的三层代码,可以较快的实现增删改查操作。 3、由于一些dll版本的问题及动软生成器自身的一些不完善,产生了一些问题并查找了挺久,所以把可以实现的版本发布出来共享。 前提: 使用...

    java swing 增删改查

    在这个"java swing 增删改查"的小项目中,我们可以推测开发者利用Swing 创建了一个简单的数据库操作应用,允许用户对数据进行添加、删除、修改和查询。 在Java Swing中,主要涉及以下几个核心知识点: 1. **容器与...

    Maven+SpringBoot+MyBatis+MySQL实现增删改查源码

    本教程将通过一个实际的项目案例,讲解如何使用Maven、SpringBoot、MyBatis和MySQL这四个关键技术来实现基本的数据增删改查(CURD)功能。下面我们将深入探讨这些技术及其在项目中的应用。 首先,Maven是一个项目...

    spring4+hibernate4实现增删改查

    本文将深入探讨如何使用Spring4和Hibernate4实现数据库的增删改查操作,以及在这个过程中可能涉及的关键知识点。 首先,Spring4是一个全面的Java应用程序框架,它提供了一种方式来管理组件(或称为bean)之间的依赖...

    javaWeb-连接mysql数据库增删改查

    JavaWeb 连接 MySQL 数据库增删改查是 Java 新手非常有用的知识点,本文将详细介绍如何使用 JavaWeb 连接到 MySQL 数据库,并实现增删改查的操作。 知识点一:JavaWeb 连接 MySQL 数据库 要连接 MySQL 数据库,...

Global site tag (gtag.js) - Google Analytics