ThinkPHP 大D方法思想下的JDBC操作数据库D类

2023-05-16

       这里我封装出来的D类,是根据ThinkPHP中的D方法中做出来的,其中有些出入的地方,我进行了一些个性化的修正,如:ThinkPHP中操作数据库时,需要在配置文件中定义关于数据库的配置,这里我采用外部接口定义常量的方法进行定义,在D类中实现该接口,实现接口中常量的引用,方便配置的修改;D类中还提供了executeDMLexecuteDQL这两个方法——传入SQL语句即可进行更复杂的增删查改操作

       该类还存有许多不足的地方。


       DBConfig.java

package cn.zhku.myjdbc;

public interface DBConfig {
	public final String IP = "localhost"; //MySQL主机
	public final int PORT = 3306; //MySQL端口号
	public final String DB_NAME = "mydb_329"; //数据库名
	public final String DB_USERNAME = "root";
	public final String DB_PASSWORD = "";
	public final String DB_ENCODING = "UTF-8"; //数据库编码
}
       D.java

package cn.zhku.myjdbc;

import java.sql.Connection;
import java.sql.Date;
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.LinkedHashMap;
import java.util.List;

public class D implements DBConfig {
	protected String tableName = ""; // 表名

	protected String where = ""; // 条件 采用含占位符的方式,如:id=?&name=?
	protected Object[] whereData;
	
	protected String[] fields; // 操作字段
	protected Object[] data; //传递数据
	
	protected String limit = ""; //limit语句
	
	private Connection con;
	
	private static final String INSERT_SQL = "insert";
	private static final String DELETE_SQL = "delete";
	private static final String SELECT_SQL = "select";
	private static final String UPDATE_SQL = "update";

	public D(String tableName) {
		// TODO Auto-generated constructor stub
		this.tableName = tableName;

		init();
	}
	
	/**
	 * 加载数据库驱动,注册到驱动管理器
	 * 设置数据连接
	 * 创建Connection连接
	 */
	private void init() {
		try {
			Class.forName("com.mysql.jdbc.Driver");
			// 建立链接
			String url = "jdbc:mysql://" + IP + ":" + PORT + "/" + DB_NAME
					+ "?user=" + DB_USERNAME + "&password=" + DB_PASSWORD + "&useUnicode=true&characterEncoding=" + DB_ENCODING;

			con = DriverManager.getConnection(url);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 设置操作字段
	 * @param fields 操作字段构成的字符串数组
	 * @return 返回当前对象
	 */
	public D field(String... fields) {
		/*if (field.length == 0) {
			this.fields = "*";
		} else {
			this.fields = "`" + field[0] + "`";
			for (int i = 1; i < field.length; i++) {
				this.fields += ", `" + field[i] + "`";
			}
		}*/
		this.fields = fields;
		return this;
	}

	/**
	 * 设置操作字段
	 * @param fields 以SQL设置操作字段的方式传入字符串
	 * @return
	 */
	public D field(String fields) {
		if("*".equals(fields)) {
			this.fields = null;			
		} else {
			this.fields = fields.split(",");
		}
		return this;
	}

	/**
	 * 设置where条件
	 * @param w jdbc的where条件,含占位符
	 * @return 返回当前对象引用
	 */
	public D where(String w, String... wd) {
		this.where = " where " + w;
		this.whereData = wd;
		return this;
	}
	
	/**
	 * 设置data数据,用于插入数据时设置数据
	 * @param data
	 * @return
	 */
	public D data(Object... data) {
		this.data = data;
		return this;
	}
	
	/**
	 * 分页设置
	 * @param cur 当前页数
	 * @param rows 每页记录的条数
	 * @return
	 */
	public D page(int cur, int rows) {
		this.limit = " limit " + (cur - 1) * rows + ", " + rows;
		return this;
	}
	
	/**
	 * limit限制查询
	 * @param offset 偏移位置
	 * @param length 获取长度
	 * @return
	 */
	public D limit(int offset, int length) {
		this.limit = " limit " + offset + ", " + length;
		return this;
	}
	
	/**
	 * 查询操作(可以通过使用field方法设置要查询的字段,不使用field方法默认查询所有字段、可使用where方法设置查询的条件)
	 * @param field 查询字段
	 */
	public List<LinkedHashMap<String, Object>> select() {
		try {
			String sql = createSQL(SELECT_SQL);
			PreparedStatement ps = this.getPreparedStatement(sql, this.whereData);
			List<LinkedHashMap<String, Object>> list = getRes(ps);

			return list;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			// e.printStackTrace();
			System.out.println("Error: Select Failed");
		} finally {
			this.reset();
		}
		return null;
	}
	/**
	 * 封装结果集
	 * @param ps
	 * @return
	 * @throws SQLException
	 */
	private List<LinkedHashMap<String, Object>> getRes(PreparedStatement ps) throws SQLException {
		ResultSet rs = ps.executeQuery();
		ResultSetMetaData rsmd = rs.getMetaData(); // 获取表信息
		int cols = rsmd.getColumnCount(); // 获取表的列数
		String[] columnName = new String[cols];
		for (int i = 0; i < cols; i++) {
			columnName[i] = rsmd.getColumnName(i + 1);
		}

		List<LinkedHashMap<String, Object>> list = new ArrayList<LinkedHashMap<String, Object>>();
		while (rs.next()) {
			LinkedHashMap<String, Object> m = new LinkedHashMap<String, Object>();
			for (int i = 0; i < cols; i++) {
				m.put(columnName[i], rs.getString(i + 1));
			}
			list.add(m);
		}

		ps.close();
		rs.close();
		
		return list;
	}
	
	/**
	 * 添加操作(可以通过使用field方法设置要添加的字段,不使用field方法,表示需要添加所有字段、可以通过data方法设置添加的数据,没有使用data方法时会添加错误)
	 * @return
	 */
	public int add() {
		return addCommon();
	}
	
	/**
	 * 添加操作(可以通过使用field方法设置要添加的字段,不使用field方法,表示需要添加所有字段)
	 * @param data 将要添加的数据
	 * @return 返回所影响的行数,-1表示添加数据失败
	 */
	public int add(Object... data) {
		this.data = data;
		return addCommon();
	}
	
	/**
	 * 添加操作
	 * @return 返回所影响的行数,-1表示添加数据失败
	 */
	private int addCommon() {
		String sql = createSQL(INSERT_SQL);
		if("".equals(sql)) {
			this.reset();
			return -1;
		}

		return executeDML(sql, this.data);
	}
	
	/**
	 * 更新操作(可以通过使用field方法设置要更新的字段,没有使用field方法时会更新错误;可以通过data方法设置要更新的数据,没有使用data方法时会更新错误;可以使用where方法设置更新条件)
	 * @return 返回所影响的行数,-1表示更新数据失败
	 */
	public int save() {
		return saveCommon();
	}
	
	/**
	 * 更新操作(可以通过使用field方法设置要更新的字段,没有使用field方法时会更新错误;可以使用where方法设置更新条件)
	 * @param data 设置要更新的数据
	 * @return
	 */
	public int save(Object... data) {
		this.data = data;
		return saveCommon();
	}
	
	/**
	 * 更新操作
	 * @return 返回所影响的行数,-1表示更新数据失败
	 */
	private int saveCommon() {
		String sql = createSQL(UPDATE_SQL);
		if("".equals(sql) || this.data == null) {
			this.reset();
			return -1;
		}
		
		//合并 this.data 和 this.whereData中的数据
		Object[] arr = new Object[this.data.length + (this.whereData == null ? 0 : this.whereData.length)];
		if(arr.length > 0) {
			for(int i = 0; this.data != null && i < this.data.length; i++) {
				arr[i] = this.data[i];
			}
			for(int i = this.data.length, j = 0; this.whereData != null && i < arr.length; i++, j++) {
				arr[i] = this.whereData[j];
			}
		}
		
		return executeDML(sql, arr);
	}
	
	/**
	 * 删除操作
	 * 可以使用where方法设置更新条件,没有删除条件的话将会把表内的数据均删除
	 * @return 返回所影响的行数,-1表示更新数据失败
	 */
	public int delete() {
		return deleteCommon();
	}
	
	/**
	 * 删除操作
	 * @param where 设置where条件(SQL语句,含占位符)
	 * @param whereData where条件中占位符赋值的数据
	 * @return 返回所影响的行数,-1表示更新数据失败
	 */
	public int delete(String where, Object... whereData) {
		this.where = " WHERE " + where;
		this.whereData = whereData;
		return deleteCommon();
	}
	
	/**
	 * 删除操作
	 * @return 返回所影响的行数,-1表示更新数据失败
	 */
	private int deleteCommon() {
		String sql = createSQL(DELETE_SQL);
		if(this.whereData == null) {
			this.reset();
			return -1;	
		}
		
		return executeDML(sql, this.whereData);
	}
	
	/**
	 * 根据type创建SQL语句
	 * @param type SQL语句的类型
	 * @return SQL语句
	 */
	private String createSQL(String type) {
		String sql = "";
		if(INSERT_SQL.equals(type)) {
			String field = formFields();
			if(!"".equals(field)) {
				field = "(" + field + ")";				
			}
			if (this.data != null && this.data.length > 0) {
				sql = "INSERT INTO " + this.tableName  + field + " VALUES";
				sql += "(?";
				for (int i = 1; i < this.data.length; i++) {
					sql += ",?";
				}
				sql += ")";
			} else {
				return "";
			}
		} else if(DELETE_SQL.equals(type)) {
			sql = "DELETE FROM " + this.tableName + this.where;
		} else if(SELECT_SQL.equals(type)) {
			String field = formFields();
			if("".equals(field)) {
				field = "*";
			}
			sql = "SELECT " + field + " FROM " + this.tableName + this.where + this.limit;
		} else if(UPDATE_SQL.equals(type)) {
			if(this.fields == null || this.fields.length == 0) {
				return "";
			} else {
				sql = "UPDATE " + this.tableName + " SET `";
				sql += this.fields[0] + "`=?";
				for(int i = 1; i < this.fields.length; i++) {
					sql += ",`" + this.fields[i] + "`=?";
				}
				sql += this.where;
			}
		}
		return sql;
	}
	
	/**
	 * 组成SQL语句中的字段
	 * @return
	 */
	private String formFields() {
		String f = "";
		if (this.fields != null) {
			f = "`" + this.fields[0] + "`";
			for(int i = 1; i < this.fields.length; i++) {
				f += ",`" + this.fields[i] + "`";
			}
		}
		
		return f;
	}
	
	/**
	 * 根据SQL语句创建PreparedStatement对象,并为参数赋值
	 * @param sql SQL语句
	 * @param data 数据
	 * @return PreparedStatement对象
	 * @throws SQLException
	 */
	private PreparedStatement getPreparedStatement(String sql, Object... data) throws SQLException {
		PreparedStatement ps = con.prepareStatement(sql);
		if(data == null) return ps; //在select操作中没有where,此时没有where中的?,就不需要以下设置了
		
		for (int i = 0; i < data.length; i++) {
			Object param = data[i];
			if (param instanceof Integer) {
				int value = ((Integer) param).intValue();
				ps.setInt(i + 1, value);
			} else if (param instanceof String) {
				String s = (String) param;
				ps.setString(i + 1, s);
			} else if (param instanceof Double) {
				double d = ((Double) param).doubleValue();
				ps.setDouble(i + 1, d);
			} else if (param instanceof Float) {
				float f = ((Float) param).floatValue();
				ps.setFloat(i + 1, f);
			} else if (param instanceof Long) {
				long l = ((Long) param).longValue();
				ps.setLong(i + 1, l);
			} else if (param instanceof Boolean) {
				boolean b = ((Boolean) param).booleanValue();
				ps.setBoolean(i + 1, b);
			} else if (param instanceof Date) {
				Date d = (Date) param;
				ps.setDate(i + 1, (Date) param);
			}
		}
		
		return ps;
	}
	
	/**
	 * 执行DML语句 INSET/UPDATE/DELETE
	 * @param sql SQL语句
	 * @param arr 对SQL语句占位符赋值的数组
	 * @return
	 * @throws SQLException
	 */
	public int executeDML(String sql, Object... arr) {
		try {
			PreparedStatement ps = getPreparedStatement(sql, arr);
			int row = ps.executeUpdate();
			ps.close();
			
			return row > 0 ? row : -1;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			this.reset();
		}
		
		return -1;
	}
	
	/**
	 * 执行DQL语句 SELECT
	 * @param sql SQL语句
	 * @param arr 对SQL语句占位符赋值的数组
	 * @return
	 */
	public List<LinkedHashMap<String, Object>> executeDQL(String sql, Object... arr) {
		try {
			PreparedStatement ps = this.getPreparedStatement(sql, arr);
			List<LinkedHashMap<String, Object>> list = getRes(ps);

			return list;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			// e.printStackTrace();
			System.out.println("Error: Select Failed");
		} finally {
			this.reset();
		}
		return null;
	}
	
	/**
	 * 将条件(where)或操作(fields)字段或数据(data)置为初始状态
	 */
	public void reset() {
		this.where = "";
		this.whereData = null;
		this.fields = null;
		this.data = null;
		this.limit = "";
	}

	/**
	 * 关闭Connection对象的连接
	 */
	public void close() {
		try {
			con.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			System.out.println("Error: Close Failed");
		}
	}
}

      Demo 演示类  App.java

package cn.zhku.myjdbc;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class App {
	public static void main(String[] args) {
		D d = new D("t_user");
	
		//addDemo(d);
		selectDemo(d);
		
		/*System.out.println();
		updateDemo(d);
		System.out.println();
		selectDemo(d);*/
		
		/*deleteDemo(d);
		System.out.println();
		selectDemo(d);*/
		
		//out(d.executeDQL("SELECT * FROM t_user", null));
		
		//d.executeDML("DELETE FROM t_user WHERE name=?", "酱油5");
		d.close();
	}
	
	/**
	 * D类中的select方法Demo演示
	 * @param d
	 */
	public static void selectDemo(D d) {
		//1.查询所有记录的所有字段数据
		//1.1 默认查询所有记录的所有字段数据
		List<LinkedHashMap<String, Object>> s = d.select();
		//1.2 使用字符串"*"同样达到同样效果
		//List<LinkedHashMap<String, Object>> s = d.field("*").select();
		//1.3 设置字段,以数组方式
		//String[] fields = {"name","grade"};
		//List<LinkedHashMap<String, Object>> s = d.field(fields).select();
		//1.4 设置字段,以参数方式
		//List<LinkedHashMap<String, Object>> s = d.field("name","grade").select();
		
		//2.查询所有记录的grade字段数据
		//List<LinkedHashMap<String, Object>> s = d.field("grade").select();
		
		//3.添加where条件
		//List<LinkedHashMap<String, Object>> s = d.field("*").where("name=?","dreamboy").select();
		
		//4.分页查询(每页5行记录,查询第3页的记录)
		//List<LinkedHashMap<String, Object>> s = d.page(3,5).select();
		out(s);
	}
	public static void out(List<LinkedHashMap<String, Object>> s) {
		if(s == null) {
			System.out.println("Error: 结果为空!");
			return ;
		}
		
		for(LinkedHashMap<String, Object> map : s) {
			boolean isFist = true;
			for (Map.Entry<String, Object> entry : map.entrySet()) {
				if(isFist) {
					System.out.print(entry.getValue());
					isFist = false;
				} else {
					System.out.print(/*"Key = " + entry.getKey() + ", Value = " +*/ " " + entry.getValue());					
				}
			}
			System.out.println();
		}
	}
	
	/**
	 * D类中的add方法Demo演示
	 * @param d
	 */
	public static void addDemo(D d) {
		//1.使用data方法设置插入的数据
		for(int i = 0; i < 5; i++) {
			String name = "酱油" + i;
			int grade = (int) (Math.random() * 101);
			
			d.data(name, grade).add();
		}
		
		//2.向add方法传入要插入的数据,以参数的方式传入
		for(int i = 0; i < 5; i++) {
			String name = "酱油" + (i + 5);
			int grade = (int) (Math.random() * 101);
			
			d.add(name, grade);
		}
	}
	
	/**
	 * D类中的save方法Demo演示
	 * @param d
	 */
	public static void updateDemo(D d) {
		//1.使用data方法传递更新的数据
		//d.field("grade").data(88).where("name=?","dreamboy").save();
		
		//2.在save方法中传入更新的数据
		d.field("grade").where("name=?","dreamboy").save(99);
	}
	
	/**
	 * D类中的delete方法Demo演示
	 * @param d
	 */
	public static void deleteDemo(D d) {
		//1.使用where方法设置删除条件
		//d.where("name=?", "酱油1").delete();
		
		//2.在delete方法中传入删除条件
		d.delete("name=?", "酱油2");
	}
}



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ThinkPHP 大D方法思想下的JDBC操作数据库D类 的相关文章

随机推荐

  • PHP实现页面静态化——局部动态化

    上回说到 xff1a PHP实现页面静态化 全部纯静态化 这次实现PHP的局部动态化 xff0c 也就是说静态化的页面存在 动态 过程 xff0c 结合全部静态化技术 43 Ajax技术实现局部动态化 xff0c 局部更新页面 在上文的数据
  • CSS3的过渡 transition

    这里只考虑 chrome 的兼容 transition html lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 3
  • CSS3中的3D旋转 rotate、3D位移 translate

    这里只考虑 chrome 的兼容 3DrotateDemo html lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8
  • CSS3让登陆面板旋转起来

    这里只考虑chrome的兼容 LoginRotate html lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34
  • CSS3 卡片翻转(transform)

    这里只考虑chrome的兼容 card1 html lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt
  • 他们的CSS3 3D正方体

    摘自 xff1a 程旭元 所分享的程序 效果图如下 xff1a cube html lt DOCTYPE html gt lt html lang 61 34 zh CN 34 gt lt head gt lt title gt 3D正方体
  • html自定义复选框

    自定义复选框的素材 xff1a icon check circle png icon checked png checkbox html xff08 为了方便起见 xff0c 这里使用到了jQuery xff09 lt DOCTYPE ht
  • CSS3的基本介绍

    知识点记录 xff1a 1 圆角效果 border radius 如 xff1a border radius 10px 所有角都使用半径为10px 的圆角 border radius 5px 4px 3px 2px 四个半径值分别是左上角
  • CSS3选择器(上)

    1 属性选择器 E att 61 val 选择匹配元素 E xff0c 且 E元素定义了属性 att xff0c 其属性值以 val开头的任何字符串 E att 61 val 选择匹配元素 E xff0c 且 E元素定义了属性 att xf
  • CSS3实现曲线阴影和翘边阴影

    效果图如下 xff1a index html lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt ti
  • THINKPHP 数据操作方法

    一 ThinkPHP Insert 添加数据 ThinkPHP 内置的 add 方法用于向数据表添加数据 xff0c 相当于 SQL 中的 INSERT INTO 行为 添加数据 add 方法是 CURD xff08 Create Upda
  • PHP文件上传的实现及其介绍

    关于实现及介绍在程序注释中 提交文件的页面 xff1a xff08 可以分别提交到doAction php doAction1 php doAction2 php进行测试 xff09 upload php lt doctype html g
  • PHP单文件上传的过程化函数封装

    提交文件的页面 xff1a upload php lt doctype html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt
  • PHP的单个文件上传、多个单文件上传、多文件上传

    单文件上传 upload1 php lt doctype html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt title g
  • PHP实现单文件上传、多个单文件上传、多文件上传的过程化封装

    上回提到 PHP的单个文件上传 多个单文件上传 多文件上传 这里给出 三种方式的统一实现 下面先给出各种方式的文件提交页面 xff1a 单个文件上传 upload1 php lt doctype html gt lt html lang 6
  • PHP的单文件上传类

    提交单文件的页面 upload php lt doctype html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt title
  • PHP的多文件上传类

    提交表单的页面 upload php lt doctype html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt title
  • Nginx负载均衡配置实例详解

    转载自 xff1a http www php100 com html program nginx 2013 0905 5525 html 负载均衡是我们大流量网站要做的一个东西 xff0c 下面我来给大家介绍在Nginx服务器上进行负载均衡
  • 基于Bootstrap使用jQuery实现简单可编辑表格

    editTable js 提供编辑表格当前行 添加一行 删除当前行的操作 xff0c 其中可以设置参数 xff0c 如 xff1a operatePos 用于设置放置操作的列 xff0c 从0开始 xff0c 1表示以最后一列作为放置操作的
  • ThinkPHP 大D方法思想下的JDBC操作数据库D类

    这里我封装出来的D 类 xff0c 是根据 ThinkPHP 中的 D 方法中做出来的 xff0c 其中有些出入的地方 xff0c 我进行了一些个性化的修正 xff0c 如 xff1a ThinkPHP 中操作数据库时 xff0c 需要在配