Java工具类——jdbc

java代码中操作数据库。(本文以MySQL为例)

操作通常分6步:

1.加载数据库驱动

2.建立数据库连接对象

3.创建执行SQL的语句对象

4.执行SQL语句

5.处理结果

6.释放数据库资源


数据库厂商会实现符合自己的数据库特点的数据库驱动程序。

常见数据库产品驱动加载方式如下:

Mysql
Class.forName("com.mysql.jdbc.Driver");


Oracle
Class.forName("oracle.jdbc.driver.OracleDriver");


SQLServer
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");


实际操作:

本文使用的是MySQL,首先下载一个MySQL的jdbc的jar文件。本文使用的是mysql-connector-java-5.1.41-bin.jar(可自行官网或网络下载并导入)

封装:

	private static String className,url,user,password;

	/**
	 * 1.加载驱动,静态代码块,只执行一次
	 */
	static {
		try {
			// 1.1.从配置文件中初始化数据库连接参数
			Properties pops = new Properties();
			pops.load(UtilsJDBC.class.getResourceAsStream("/jdbc.properties"));
			className = pops.getProperty("className");
			url = pops.getProperty("url");
			user = pops.getProperty("user");
			password = pops.getProperty("password");

			// 1.2.加载驱动
			Class.forName(className);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 建立连接
	 * @return	连接对象
	 */
	private static Connection getConn() {
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(url, user, password);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}

考虑到多人同时操作数据库的问题,于是并没有给静态参数url、user、password赋值。而是通过使用配置文件jdbc.properties来封装。然后从配置文件中取出数据初始化。


下面到了创建SQL语句对象

常用的有Statement对象和PreparedStatement对象


Statement对象通过

Statement stmt = conn.createStatement();


PreparedStatement对象通过

String sql = “select * from students where name = ? and sex = ?”;
PreparedStatement ps = conn.preparedStatement(sql);
ps.setString(1,”张三”);
ps.setString(2,”女”);
此处,参数sql可以带有占位符。


Statement对象或者PreparedStatement对象调用executeXxx()方法将SQL语句发送到数据库管理系统,数据库管理系统执行完毕之后会有结果返回,不同类型的sql语句以及不同的executeXxx()方法返回的结果都不相同,那么对结果的处理方式也不各不相同。


Statement类型语句对象的执行

boolean b = stmt.execute(sql);//执行任何sql语句

int I = stmt.executeUpdate(sql);//执行增删改SQL语句

ResultSet rs = stmt.executeQuery(sql);//执行查询语句


PreparedStatement类型语句对象的执行
boolean b = ps.execute();//执行任何类型sql语句
int I = ps.executeUpdate();//执行增删改类型sql语句
ResultSet rs = ps.executeQuery();//执行查询语句

综上,可以看出增删改,返回的是sql语句在数据库中响应的行数;而查询是返回的结果集合。所以我们可写2个封装方法来区分。

另外,

·如使用createStatement,则需要配合使用executeUpdate(sql)方法,此处传入的sql不可使用占位符;

·如使用preparedStatement(sql),则需要配合使用executeUpdate()方法,此处传入的sql可使用占位符;

  ··又需要对sql使用占位符或不使用占位符来进行区分。或者写重载方法。


此处,以使用preparedStatement(sql)为例,传入可变参数来避免重载,并优化使用占位符的操作

	/**
	 * 增删改
	 * @param sql	sql增删改语句,可含占位符?
	 * @param args	如使用占位符,则对占位符释义
	 * @return	相应数据库响应行数
	 */
	static public int updata(String sql,Object...args){
		Connection conn = null;
		PreparedStatement ps=null;
		int rows = 0;
		try {
			conn=getConn();
			ps=conn.prepareStatement(sql);
			
			//逐个解释占位符,占位符索引从1计数,数组索引从0计数
			if(args!=null && args.length>0){
				for(int i=0;i0) {
			System.out.println("操作成功");
		}else {
			System.out.println("操作失败");
		}
		return rows;
	}
	/**
	 * 查询
	 * 多表查询时,请使用别名来区分相同的列名
	 * @param sql	sql查询语句,不含占位符?
	 * @param obj	占位符释义
	 * @return	结果集封装的list集合
	 */
	public static List> query(String sql,Object...args) {
		Connection conn = null;
		PreparedStatement ps=null;
		ResultSet res=null;
		
		List> list=new ArrayList>();
		try {
			conn=getConn();
			ps = conn.prepareStatement(sql);	
			//如果数组不为null且长度大于0说明sql语句中有?占位符
			//逐个解释占位符,占位符索引从1计数,数组索引从0计数
			if(args!=null && args.length>0){ //1
				for(int i=0;i rowData=new HashMap();
				
				//列索引从1开始
				for (int i = 1; i <= count; i++) {
					//获取每一列的列名           resmd.getColumnType();//获取类型		resmd.getColumnTyoeName();//获取类型名称
					String cname=resmd.getColumnLabel(i);
					Object cvalue=res.getObject(cname);
					rowData.put(cname, cvalue);
				}
				list.add(rowData);
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			close(res, ps, conn);
		}
		return list;
	}

最后,关闭资源。当然,上述方法中已经在执行完SQL操作之后就调用了此方法对资源进行了关闭

	/**
	 * 关闭资源
	 * @param res	结果集
	 * @param stmt	语句
	 * @param conn	连接
	 * @throws SQLException
	 */
	private static void close(ResultSet res, Statement stmt, Connection conn){
		try {
			if (res != null) {
				res.close();
			}
			if (stmt != null) {
				stmt.close();
			}
			if (conn != null) {
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}


 在上述的查询方法中,对结果集进行了处理,把结果集放入了list集合中。

这样做的原因是,在处理结果集之前,不能关闭资源。否则就无法对结果集进行处理。

而在查询后,把结果放入list之后,就立即关闭了资源。而对查询结果的处理可以通过对list的操作来执行。

这样做符合Connection的使用原则,即尽量晚创建,尽可能早释放,因为数据库的连接很有限,如果不及时释放将导致系统崩溃











你可能感兴趣的:(JAVA)