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

       这里我封装出来的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");
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值