数据库的基本工具类,增删改查,分页查询

util工具类

package com.ishangu.util;

import java.lang.reflect.Field;
import java.security.spec.ECField;
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.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 数据库基本工具类
 *
 */
public class DBUtil {
	/**
	 * 将基本数据库信息封装成常量
	 */
	private static final String URL="jdbc:mysql:///";
	private static final String DB_NAME="aaa";
	private static final String USERNAME="root";
	private static final String PASSWORD="123456";
	/**
	 * JDBC常用对象
	 */
	private static Connection con;
	private static PreparedStatement ps;
	private static ResultSet rs;
			
	/**
	 * 私有化工具类的构造方法,不让别人new对象
	 */
	private DBUtil(){
		
	}
	/**
	 * 1.获取数据库连接
	 */
	private static Connection getConnection(){
		try{
		con=DriverManager.getConnection(URL+DB_NAME, USERNAME, PASSWORD);
		}catch(Exception e){
			e.printStackTrace();
		}
		return con;
	}
	/**
	 * 2.获取预编译对象
	 */
	public static PreparedStatement getPS(String sql){
		getConnection();
		try {
			ps=con.prepareStatement(sql);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ps;
	}
	
	/**
	 * 3.编写关闭连接的方法
	 */
	public static void close(Connection con){
		if(con!=null){
			try {
				con.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	/**
	 * 4.关闭预编译对象
	 */
	public static void close(Connection con,PreparedStatement ps){
		if(ps!=null){
			try {
				ps.close();
				close(con);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	/**
	 * 5.编写关闭结果集对象的方法
	 */
	public static void close(Connection con,PreparedStatement ps,ResultSet rs){
		if(rs!=null){
			try {
				rs.close();
				close(con,ps);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	/**
	 * 6.通用的DML 参数1.需要执行的sql语句
	 * 			   参数2.是sql中占位符需要的值
	 * 
	 */
	public static void dml(String sql,Object...objects){
		getPS(sql);//预编译对象已经有了。
		try {
			//通过for循环,将所有参数放入到sql的占位符之内
			for(int i=0;i<objects.length;i++){
				ps.setObject(i+1, objects[i]);
			}
			ps.execute();//执行sql语句
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			close(con,ps);
		}
	}
	/**
	 * 7.通用的DQL:最大难题:查询不同的表,需要返回不同的model类对象,此时我门可以在形参中传入查询的model类型,没然后根据反射创建对象,完成结果集的封装
	 */
	public static <E> E dqlOne(String sql,Class<E> c,Object...objects){
		getPS(sql);
		E e=null;
		try {
			for (int i = 0; i < objects.length; i++) {
				ps.setObject(i+1, objects[i]);
			}
			
			rs=ps.executeQuery();
			//首先获取结果集中所有列的集合
			ResultSetMetaData data = rs.getMetaData();
			//然后获取列的数量
			int count = data.getColumnCount();
			//根据列的数量创建一个字符串数组
			String[] str =new String[count];
			//将所有列明后才能存入到字符串数组之中
			for (int i = 0; i < str.length; i++) {
				str[i]=data.getColumnLabel(i+1);
			}
			String[] fields=method(str); 
			//开始遍历结果集
			
			if(c.getName().equals("Integer")||c.getName().equals("int")){
				//需要返回的是一个单纯的整数,也证明sql是求总数的sql。
				rs.next();
				return  (E) new Integer(rs.getInt(1));
			}
			while (rs.next()) {
				//获取当前列数
				if(rs.getRow()>1){
					throw new Exception("查出多条数据");
				}
				//通过反射将e实例化为实力对象
				e=c.newInstance();
				//通过循环给e对象的属性赋值
				for(int i=0;i<str.length;i++){
					//使用列名称通过反射对象,获取对象的属性
					Field field = c.getDeclaredField(fields[i]);
					//公开访问权限
					field.setAccessible(true);
					//给属性设置值
					field.set(e, rs.getObject(str[i]));
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}finally {
			close(con,ps,rs);
		}
		return e;
	}
	/**
	 * 将数据库列名称转化为Java的属性名,并返回对应的数组
	 */
	public static String[] method(String[] str){
		//创建一个数组用来保存model中的属性名长度与数据库列的数组长度一致
		String[] fields =new String [str.length]; 
		for (int i = 0; i < fields.length; i++) {
			if(str[i].indexOf("_")!=-1){//进入if代表列名中包含有下划线
				//由于列名中可能不止一个下划线,所以做了如下处理
				String[] split=str[i].split("_");
				StringBuffer sb=new StringBuffer();
				//遍历根据_分割出来的数组
				for (int j = 0; j < split.length; j++) {
					if(j==0){
						sb.append(split[j]);
					}else{
						char[] charArray = split[j].toCharArray();//将字符串转换成char数组
						charArray[0]-=32;//数组中的第一个元素进行大写转换。
						sb.append(charArray);
					}
				}
				//将StringBuffer转换成字符串,然后存入到字符串数组中
				fields[i]=sb.toString();
			}else{
				fields[i]=str[i];
			}
		}
		return fields;
	}
	/**
	 * 8.通用的DQL:最大难题:查询不同的表,需要返回不同的model类对象,此时我门可以在形参中传入查询的model类型,没然后根据反射创建对象,完成结果集的封装
	 * 查询多个
	 */
	
	public static <E> List<E> dqlList(String sql,Class<E> c,Object...objects){
		getPS(sql);
		List<E> list=new ArrayList<>();
		try {
			for (int i = 0; i < objects.length; i++) {
				ps.setObject(i+1, objects[i]);
			}
			rs=ps.executeQuery();
			//首先获取结果集中所有列的集合
			ResultSetMetaData data = rs.getMetaData();
			//然后获取列的数量
			int count = data.getColumnCount();
			//根据列的数量创建一个字符串数组
			String[] str =new String[count];
			//将所有列明后才能存入到字符串数组之中
			for (int i = 0; i < str.length; i++) {
				str[i]=data.getColumnLabel(i+1);
			}
			String[] fields=method(str); 
			//开始遍历结果集
			while (rs.next()) {
				//通过反射将e实例化为实力对象
				E e=c.newInstance();
				//通过循环给e对象的属性赋值
				for(int i=0;i<str.length;i++){
					//使用列名称通过反射对象,获取对象的属性
					Field field = c.getDeclaredField(fields[i]);
					//公开访问权限
					field.setAccessible(true);
					//给属性设置值
					field.set(e, rs.getObject(str[i]));
				}
				list.add(e);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}finally {
			close(con,ps,rs);
		}
		return list;
	}
	public static <E> void dml(String sql,E e){
		getPS(sql);
		Class<? extends Object> class1 = e.getClass();
		if(class1.getName().equals("int")||class1.getName().equals("Integer")||class1.getSimpleName().equals("String")){
				try {
					ps.setObject(1, e);
					ps.execute();
				} catch (SQLException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}finally {
					close(con,ps);
				}
				
		}else{
		try {
		Field[] fields = class1.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
				fields[i].setAccessible(true);
				ps.setObject(i+1, fields[i].get(e));
			}
				ps.execute();
		}catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}finally {
			close(con,ps);
		}
		}
		
	}
	
	
	/**
	 * 1.通用的增加,要求有多少个占位符,传入的model中需要有多少个属性有值
	 * 2.model属性的书写规范顺序要与数据库列名的顺序一致,书写sql要规范
	 * 由于传入的model是任何类型,所以要用到泛型
	 */
	public static <E> void saveModel(String sql,E e){
		getPS(sql);
		try {
			Class<? extends Object> class1 = e.getClass();
			Field[] fields = class1.getDeclaredFields();
			int j=1;
			for (int i = 0; i < fields.length; i++) {
				fields[i].setAccessible(true);
				if(fields[i].get(e)!=null){
					ps.setObject(j++, fields[i].get(e));
				}
			}
			ps.execute();
		} catch (Exception e2) {
			e2.printStackTrace();
		}finally {
			close(con,ps);
		}
	}
	public static <E> void updateModel(String sql,E e){
		getPS(sql);
		try {
			Class<? extends Object> class1 = e.getClass();
			Field[] fields = class1.getDeclaredFields();
			int j=1;
			for (int i = 1; i < fields.length; i++) {
				fields[i].setAccessible(true);
				if(fields[i].get(e)!=null){
					ps.setObject(j++, fields[i].get(e));
				}
				
			}
			fields[0].setAccessible(true);
			ps.setObject(j,fields[0].get(e));
			ps.execute();
		} catch (Exception e2) {
			e2.printStackTrace();
		}finally {
			close(con,ps);
		}
	}
/**
 * 通用分页查询,使用这个方法,会返回分页的数据
 */
	public static <E> PageInfo<E> dqlListLimit(String sql,Class<E> e,Object...objects){
		//1.将传入的sql语句转化为求总数的sql
		StringBuffer sb=new StringBuffer("select count(*)");
		sb.append(sql.substring(sql.indexOf("from")));
		//2.去除limit之后的sql
		sb.replace(sb.indexOf("limit"), sb.length(), "");
		//3.去除参数中的分页参数
		Object[] of = Arrays.copyOf(objects, objects.length-2);
		Integer count = dqlOne(sb.toString(), int.class,of);
		//4.修改参数执行原来的sql
		int pageSize=(int) objects[objects.length-1];
		int pageNumber=  (int) objects[objects.length-2];
		objects[objects.length-2]=(pageNumber-1)*pageSize;
		List<E> data = dqlList(sql, e, objects);
		PageInfo<E> pageInfo=new PageInfo<>(data,count,pageSize,pageNumber);
		return pageInfo;
	}
	 	
	  

package com.ishangu.util;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.Value;


分页查询

package com.ishangu.util;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.Value;

/**
 * 主要记录跟分页有关的数据
 * 1.数据
 * 2.记录总条数
 * 3.每页显示多少条数据
 * 4.当前页码
 * 5.首页
 * 6.尾页
 * 7.上一页
 * 8.下一页
 */
//@Setter 
//@Getter
//@ToString
//@EqualsAndHashCode
@Data  //以上所有
@NoArgsConstructor  //无参构造 
@AllArgsConstructor    //有参构造
//@RequiredArgsConstructor  //指定构造
//@Value					//类被static final修饰
public class PageInfo<E> {
	/**
	 * 存放数据
	 */
	//@NonNull //指定生成在构造器中
	private List<E> data;
	public PageInfo(List<E> data, int count, int pageSize, int pageNumber) {
		super();
		this.data = data;						//数据
		this.count = count;						//总数
		this.pageSize = pageSize;				//每页显示多少数据
		this.pageNumber = pageNumber;			//当前页码
		this.countPage=count%pageSize==0 ? count/pageSize : (count/pageSize)+1;//求总共有几页
		this.startPage=1;
		this.endPage=countPage;
		this.upPage=pageNumber==1?false:true;	//第一也没有上一页
		this.nextPage=pageNumber==countPage?false:true; //pageNumber==countPage 表示已经是最后一页了,所以没有下一页了
	}
	/**
	 * 记录总条数
	 */
    private int count;//总记录数
    /**
     * 每页显示多少条数据
     */
    private int pageSize;
    /**
     * 当前页码
     */
    private int pageNumber;
    /**
     * 总共有多少页
     */
    private int countPage;
    /**
     * 首页
     */
    private int startPage;
    /**
     * 尾页
     */
    private int endPage;
    /**
     * 上一页
     */
    private boolean upPage;
    /**
     * 下一页
     */
    private boolean nextPage;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值