JDBC数据库操作

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

一、数据库操作

1.Statement

数据库连接被用于向数据库服务器发送命令和 SQL 语句,在连接建立后,需要对数据库进行访问,执行 sql 语句
    SQL 注入攻击(不建议使用)可以解决

2.PreparedStatement

代码如下(示例):

    可以通过调用 Connection 对象的 preparedStatement() 方法获取
    PreparedStatement 对象
    PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的SQL 语句

update块:

// 增删改操作
	public static void update(String sql, Object... args) {
		// 1.获取数据库的连接
		Connection conn = null;
		PreparedStatement ps = null;
		// 2.预编译sql语句,返回PreparedStatement的实例
		try {
			conn = JDBCUtil.getConnection();
			ps = conn.prepareStatement(sql);
			// 3.填充占位符
			for(int i = 0;i < args.length;i++){
				ps.setObject(i + 1, args[i]);
			}
			// 4.执行
			ps.execute();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			// 5.资源的关闭
			JDBCUtil.closeResource(conn, ps);
		}

	}
public static void main(String[] args) {
		
		 String sql = "delete from customers where id = ?"; update(sql,3);
	}

2.ResultSet

代码如下(示例):

通过调用 PreparedStatement 对象的 excuteQuery() 方法创建该对象
   ResultSet 对象以逻辑表格的形式封装了执行数据库操作的结果集,ResultSet 接口由数据库厂商实现
   ResultSet 对象维护了一个指向当前数据行的游标,初始的时候,游标在第一行之前,可以通过
   ResultSet 对象的 next() 方法移动到下一行

public static void main(String[] args) throws Exception {
		Connection conn = null;
		PreparedStatement ps = null;

		ResultSet resultSet = null;
		try {
			conn = JDBCUtil.getConnection();
			String sql = "select id,name,email,birth from customers where id = ?";
			ps = conn.prepareStatement(sql);
			ps.setObject(1, 1);
			// 执行,并返回结果集
			resultSet = ps.executeQuery();
			// 处理结果集
			if (resultSet.next()) {// next():判断结果集的下一条是否有数据
				// 获取当前这条数据的各个字段值
				int id = resultSet.getInt(1);
				String name = resultSet.getString(2);
				String email = resultSet.getString(3);
				Date birth = resultSet.getDate(4);
				// 将数据封装为一个对象
				Customer customer = new Customer(id, name, email, birth);
				System.out.println(customer);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			// 关闭资源
			JDBCUtil.closeResource(conn, ps, resultSet);
		}
 
	}

 将数据封装为一个对象

public class Customer {
	
	private int id;
	private String name;
	private String email;
	private Date birth;
	public Customer() {
		super();
	}
	public Customer(int id, String name, String email, Date birth) {
		super();
		this.id = id;
		this.name = name;
		this.email = email;
		this.birth = birth;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Date getBirth() {
		return birth;
	}
	public void setBirth(Date birth) {
		this.birth = birth;
	}
	@Override
	public String toString() {
		return "Customer [id=" + id + ", name=" + name + ", email=" + email + ", birth=" + birth + "]";
	}

2.ResultSetMetaData

代码如下(示例):

可用于获取关于 ResultSet 对象中列的类型和属性信息的对象
 ResultSetMetaData meta = rs.getMetaData();
 getColumnName(int column):获取指定列的名称
 getColumnLabel(int column):获取指定列的别名
 getColumnCount():返回当前 ResultSet 对象中的列数。

//针对于Customers表的查询操作
	public static Customer uqeryfors(String sql, Object... args) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = JDBCUtil.getConnection();

			ps = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				ps.setObject(i + 1, args[i]);
			}
			rs = ps.executeQuery();

			// 获取结果集的元数据 :ResultSetMetaData
			ResultSetMetaData rsmd = rs.getMetaData();
			// 通过ResultSetMetaData获取结果集中的列数
			int columnCount = rsmd.getColumnCount();

			if (rs.next()) {
				Customer cust = new Customer();
				// 处理结果集一行数据中的每一个列
				for (int i = 0; i < columnCount; i++) {
					// 获取列值
					Object coulmValue = rs.getObject(i + 1);
					// 获取每个列的别名
					/* String coulmnName = rsmd.getColumnClassName(i + 1); */
					String columnLabel = rsmd.getColumnLabel(i + 1);

					// 给cust对象指定的columnName属性,赋值为columValue:通过反射
					Field field = Customer.class.getDeclaredField(columnLabel);
					field.setAccessible(true);
					field.set(cust, coulmValue);

				}
				return cust;

			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			JDBCUtil.closeResource(conn, ps, rs);
		}

		return null;

	}
public static void main(String[] args) {
		String sql = "select id,name,birth,email from customers where id = ?";
		Customer customer = uqeryfors(sql, 13);
		System.out.println(customer);
	}

 二、针对不同的表查询操作,返回表中的一条记录

代码如下(示例):

//针对于不同的表的通用的查询操作,返回表中的一条记录
	public static <T> T getInstance(Class<T> clazz,String sql, Object... args) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = JDBCUtil.getConnection();

			ps = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				ps.setObject(i + 1, args[i]);
			}

			rs = ps.executeQuery();
			// 获取结果集的元数据 :ResultSetMetaData
			ResultSetMetaData rsmd = rs.getMetaData();
			// 通过ResultSetMetaData获取结果集中的列数
			int columnCount = rsmd.getColumnCount();

			if (rs.next()) {
				T t = clazz.newInstance();
				// 处理结果集一行数据中的每一个列
				for (int i = 0; i < columnCount; i++) {
					// 获取列值
					Object columValue = rs.getObject(i + 1);

					// 获取每个列的列名
					// String columnName = rsmd.getColumnName(i + 1);
					String columnLabel = rsmd.getColumnLabel(i + 1);

					// 给t对象指定的columnName属性,赋值为columValue:通过反射
					Field field = clazz.getDeclaredField(columnLabel);
					field.setAccessible(true);
					field.set(t, columValue);
				}
				return t;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtil.closeResource(conn, ps, rs);

		}

		return null;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String sql = "select id,name,email from customers where id = ?";
		Customer customer = getInstance(Customer.class,sql,12);
		System.out.println(customer);
		
		String sql1 = "select order_id orderId,order_name orderName from `order` where order_id = ?";
		Order order = getInstance(Order.class, sql1, 1);
		System.out.println(order);
	}

、实现针对于不同表的通用的查询操作多条记录

 代码如下(示例):

// 使用PreparedStatement实现针对于不同表的通用的查询操作
	public static <T> List<T> getForList(Class<T> clazz, String sql, Object... args) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = JDBCUtil.getConnection();

			ps = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				ps.setObject(i + 1, args[i]);
			}

			rs = ps.executeQuery();
			// 获取结果集的元数据 :ResultSetMetaData
			ResultSetMetaData rsmd = rs.getMetaData();
			// 通过ResultSetMetaData获取结果集中的列数
			int columnCount = rsmd.getColumnCount();
			//创建集合对象
			ArrayList<T> list = new ArrayList<T>();
			while (rs.next()) {
				T t = clazz.newInstance();
				// 处理结果集一行数据中的每一个列:给t对象指定的属性赋值
				for (int i = 0; i < columnCount; i++) {
					// 获取列值
					Object columValue = rs.getObject(i + 1);

					// 获取每个列的列名
					// String columnName = rsmd.getColumnName(i + 1);
					String columnLabel = rsmd.getColumnLabel(i + 1);

					// 给t对象指定的columnName属性,赋值为columValue:通过反射
					Field field = clazz.getDeclaredField(columnLabel);
					field.setAccessible(true);
					field.set(t, columValue);
				}
				list.add(t);
			}
			
			return list;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtil.closeResource(conn, ps, rs);

		}

		return null;
	}
	
	public static void main(String[] args) {
		String sql = "select id,name,email from customers where id < ?";
		List<Customer> list = getForList(Customer.class,sql,11);
		list.forEach(System.out::println);
		
		String sql1 = "select order_id orderId,order_name orderName from `order`";
		List<Order> orderList = getForList(Order.class, sql1);
		orderList.forEach(System.out::println);
	}

四、释放资源 

释放ResultSet, Statement,Connection。
 数据库连接(Connection)是非常稀有的资源,用完后必须马上释放,
如果Connection不能及时正确的关闭将导致系统宕机。Connection的使
用原则是尽量晚创建,尽量早的释放

总结

两种技术 

JDBC元数据:ResultSetMetaData

通过反射,获取指定的属性,并赋值

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值