数据库操作工具类

所需属性以及无参构造

//url用来指定连接哪台电脑的什么数据库,以及数据库端口,和数据库名称
    private static final String URL = "jdbc:mysql:///";
    //数据库名称
	private static final String DB_NAME = "aaa";
    //数据库账户
	private static final String USENAME = "root";
    //数据库密码
	private static final String PASSWORD = "123456";
	//数据库连接对象
	private static Connection con;
	//获取预编译对像,因为是预编译对象所以在获取的时候就需要将sql语句传递进去。
	private static PreparedStatement ps;
    //sql语句查询的结果集
	private static ResultSet rs;
    //无参构造
    private DBUtil(){
		
	 }

1:获取连接

/**
	 * 1:获取连接
	 * @return
	 */
	public static Connection getConnection(){
		try {
      //URL正常写法jdbc:mysql://192.169.218.204:3306/aaa(3306端口号),连接本地可以不写IP和端口号
			con = DriverManager.getConnection(URL+DB_NAME, USENAME, PASSWORD);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return con;
	}

2.获取预编译对像

/**
	 * 2:获取预编译对像
	 * @param sql 要执行的sql语句
	 * @return
	 */
	public static PreparedStatement getPS(String sql){
		getConnection();
		try {
			ps = con.prepareStatement(sql);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return ps;
	}

3:编写关闭结果集对象的方法(方法重载)

/**
	 * 3:编写关闭结果集对象的方法
	 * @param con
	 */
	public static void close(Connection con){
		if(con!=null){
        try {
			con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
 }
	/**
	 * 4:编写关闭结果集对象的方法
	 * @param con
	 * @param ps
	 */
	public static void close(Connection con,PreparedStatement ps){
		if(ps!=null){
			try {
				ps.close();
				close(con);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	/**
	 * 5:编写关闭结果集对象的方法
	 * @param con
	 * @param ps
	 * @param rs
	 */
	public static void close(Connection con,PreparedStatement ps,ResultSet rs){
		if(rs!=null){
			try {
				rs.close();
				close(con,ps);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

4:向数据库中增加数据的通用方法

 /**
	 * 通用的增加方法:
	 * 1:有多少个占位符,传入的model中有多少个属性有值。
	 * 2:model属性的书写顺序要与数据库的顺序一致
	 * @param sql语句
	 * @param e
	 */
	public static <E> void saveModel(String sql,E e){
		getPS(sql);
		try {
            //通过反射获得E的class对象
			Class<?> class1 = e.getClass();
            //获取class对象的属性集
		    Field[] df = class1.getDeclaredFields();
		    int j=1;
			for (int i = 0; i < df.length; i++) {
                //破坏属性的访问修饰符
				df[i].setAccessible(true);
                //如果为空,说明添加数据时没有加入这个属性,直接跳过
				if(df[i].get(e) != null){
                    //向sql语句的占位符中传参
					ps.setObject(j++, df[i].get(e));
				}
			}
            //将sql语句提交到数据库
			ps.executeUpdate();
		} catch (Exception ee) {
			ee.printStackTrace();
		}finally{
			close(con,ps);
		}
	}

5:将数据库中的数据修改的通用方法

/**
	 * 通用修改方法
	 * @param sql
	 * @param e
	 */
	public static <E> void updateModel(String sql,E e){
		getPS(sql);
		try {
			Class<?> class1 = e.getClass();
		    Field[] df = class1.getDeclaredFields();
		    int j=1;
            //通过主键进行修改,一般主键都是表的第一列,所以i从1开始,将下标为0的属性放到最后。
			for (int i = 1; i < df.length; i++) {
				df[i].setAccessible(true);
				if(df[i].get(e) != null){
					ps.setObject(j++, df[i].get(e));
				}
			}
			df[0].setAccessible(true);
            //将对应主键的属性值,传入sql的占位符中
			ps.setObject(j,df[0].get(e));
			ps.execute();
		} catch (Exception ee) {
			ee.printStackTrace();
		}finally{
			close(con,ps);
		}
	}

6.通用的dml(增删改),有bug,使用麻烦

//Object...可以传入多个属性
public static void dml(String sql,Object...objects){
		getPS(sql);
		try {
			for (int i = 0; i < objects.length; i++) {
                //将传入来的objects依次放入sql语句的占位符中
				ps.setObject(i+1, objects[i]);
			}
            //将sql语句提交到数据库运行
			ps.execute();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			close(con,ps);
		}
	}

7.通用dql查找结果集为1

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++) {
                 //将传入来的objects依次放入sql语句的占位符中
				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);
			}
            //调用method方法将获取的列名称成与类属性相同的字符串
			String[] fields = method(str);
            //如果要查询的结果集是个数字,将直接返回结果
			if(c.getName().equals("int") || c.getName().equals("java.lang.Integer")){
				rs.next();
				return (E) new Integer(rs.getInt(1));
			}
			//开始遍历结果集。
			while(rs.next()){
                //因为本方法查询出的结果只为一条,查出多条要抛异常
				if(rs.getRow()>1){
					throw new Exception("查询结果应是1条结果,但是查出多条结果!");
				}
                //通过反射获取类的对象
				 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 ee) {
			ee.printStackTrace();
		}finally{
			close(con,ps,rs);
		}
		return e;
	}

8:通用的DQL(查询多个结果的集合)

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 ee) {
			ee.printStackTrace();
		}finally{
			close(con,ps,rs);
		}
		return list;
	}

9.将列名转化成与属性名相同的字符串(method方法)

public static String[] method(String[] str){
		String[] fields = new String[str.length];
		for (int i = 0; i < fields.length; i++) {
            //如果列名中有下划线,就进入if,没有就跳过,说明它与属性名一致
			if(str[i].indexOf("_")!=-1){
				//由于列名中可能不止一个下划线,所以做了如下处理:
                //将列名以下划线进行分割,分割的结果放进一个数组
				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();
                        //将第一个字符大写
					    charArray[0]-=32;
                        //拼接上这个单词
					    sb.append(charArray);
					}
				}
                //将转化后的列名放进要返回的数组中
				fields[i] = sb.toString();
			}else{
                //没有进if,说明它与属性名一致,直接放入数组中
				fields[i] = str[i];
			}
		}
       //返回已经放入和属性名一样的列名数组
		return fields;
	}

10.通用的分页查询,使用这个方法,会返回分页的各种数据.(所以返回值应为分页查询的对象)

public static <E> PageInfo<E> dqlListLim(String sql,Class<E> c, Object...objects){
		//1:将传入的sql语句转化成求总数的sql
		String sql1 = sql.toUpperCase();
		StringBuffer sb = new StringBuffer("SELECT COUNT(*)");
		sb.append(sql1.substring(sql1.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, c, objects);
		PageInfo<E> PageInfo = new PageInfo<>(data,count,pageSize,pageNumber);
		
		return PageInfo;
	}

分页查询类:

public class PageInfo<E> {
	/**
	 * 页中的数据
	 */
	//@NonNull //@NonNull表示这个属性不准为空,如果是空会抛空指针异常
	private List<E> data;
	/**
	 * 记录总条数
	 */
	@NonNull
	private int count;
	/**
	 * 每一页的行数
	 */
	private int pageSize;
	/**
	 * 总页数
	 */
	private int countPage;
	/**
	 * 当前页数
	 */
	private int pageNumber;
	/**
	 * 开始页
	 */
	private int startPage;
	/**
	 * 结束页
	 */
	private int endPage;
	/**
	 * 上一页
	 */
	private boolean upPage;
	/**
	 * 下一页
	 */
	private boolean nextPage;
	public PageInfo(List<E> data, @NonNull int count, int pageSize, int pageNumber) {
		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==endPage?false:true;
	}
	
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值