Java工厂模式JDBC连接数据库的方式

学JAVA也有一段时间了,数据库的连接在JAVA项目中运用非常多,这里总结一下连接的方式以及JDBC连接数据库常见的问题供新人参考。在我今后的博文中还会继续带来在网站开发中一些常见的问题汇总,希望能帮助想学习这个领域的小伙伴。

首先是普通的连接方式,本文中的连接都是针对MySQL数据库的连接,在人以后的博客中也都是MySQL的数据库,因为本人主要是从事网站的开发。其实不论是对于何种数据库,只是加载驱动的名称、url的写法以及jar包的导入不同而已。(相应的jar包可以在我上传的文件里找到)

MySqlConnectToDB.java

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class MySqlConnectToDB {

	public static void main(String args[]) {
		try {
			Class.forName("com.mysql.jdbc.Driver"); // 加载MYSQL JDBC驱动程序
			// Class.forName("org.gjt.mm.mysql.Driver");//旧版本驱动,与上面的驱动一样
			System.out.println("Success loading Mysql Driver!");
		} catch (Exception e) {
			System.out.print("Error loading Mysql Driver!");
			e.printStackTrace();
		}
		try {
			Connection conn = (Connection) DriverManager.getConnection(
					"jdbc:mysql://localhost:3306/trainningdb", "root", "root");
			// 连接URL为 jdbc:mysql//服务器地址/数据库名 ,后面的2个参数分别是登陆数据库用户名和密码

			System.out.println("Success connect Mysql server!");
			String sql = "select sname from student";// student 为你表的名称
			PreparedStatement pstm = conn.prepareStatement(sql);
			ResultSet rs = pstm.executeQuery(sql);

			while (rs.next()) {
				System.out.println(rs.getString("sname"));
			}
		} catch (Exception e) {
			System.out.print("get data error!");
			e.printStackTrace();
		}

	}
}
需要指出的是连接数据库需要对应的jar包,对于MySQL需要mysql-connector-java-5.1.8-bin.jar(版本会不同)放在项目的WEB-INF的lib目录下,对于Oracle则需要ojdbc14.jar放在同样的目录,同时将加载驱动的部分修改为如下

Class.forName("oracle.jdbc.driver.OracleDriver");
conn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl","scott","tiger");


上边的代码是用来自己研究,可以看出来在项目的实际引用中操作很麻烦,因为把数据库的驱动加载,连接,表的查询等等操作放在了一起,在进行大量的增删改查时将难以维护。所以以下代码将驱动加载,创建连接已经数据库的操作分离开,用简单工厂模式的方式实现了业务的提取与分离。

另外这里要注意应为用到了数据源所以除了mysql-connector-java-5.1.8-bin.jar,还需要导入commons-dbcp.jar以及commons-pool.jar

DataSourceHolder.java(创建数据源即加载驱动的名称与连接数据库的信息,注意BacicDataSource的包别导错)

import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;


public class DataSourceHolder {
	private BasicDataSource ds = new BasicDataSource();

	private DataSourceHolder() {
		ds.setDriverClassName("com.mysql.jdbc.Driver");
		ds.setUrl("jdbc:mysql://localhost:3306/dbo");//dbo为连接的数据库名称
		ds.setUsername("root");//账号
		ds.setPassword("root");//密码
	}
	private static class SingletonHolder{
		private static DataSourceHolder instance = new DataSourceHolder();
	}
	public static DataSourceHolder getInstance(){
		return SingletonHolder.instance;
	}
	public DataSource getDataSource(){
		return ds;
	}
}

ConnectionFactory.java(创建连接的工厂类)

import java.sql.Connection;
import java.sql.SQLException;

public class ConnectionFactory {

	public static Connection getConnection() {
		Connection conn = null;

			try {
				conn = DataSourceHolder.getInstance().getDataSource()
						.getConnection();
			} catch (SQLException e) {
				e.printStackTrace();
			}

		return conn;
	}
}

DBClose.java(处理关闭数据流等)

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DBClose {
	public static void close(Connection conn) {
		if (null != conn) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public static void close(Statement stmt) {
		if (null != stmt) {
			try {
				stmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public static void close(ResultSet rs) {
		if (null != rs) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

UserJDBCDAO.java(把增删改查的处理提取出来,此处用到一个自己编写的UserModel bean,在这里我把自己总结的增删改查,已经条件查询,获取数据库里存在最大id值等的方法都总结出来,尤其是条件查询的地方值得大家细细研究,根据判断是否有参数的传入而选择不同的sql语句,)

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;


public class UserJDBCDAO {
	// 增加
	public void create(UserModel user,Connection conn) {

		try {

			final String sql = "insert into tbl_user(userId,name,sex,age) values(?,?,?,?)";
			PreparedStatement ps = conn.prepareStatement(sql);
			int count = 1;
			ps.setInt(count++, user.getUserId());
			ps.setString(count++, user.getName());
			ps.setString(count++, user.getSex());
			ps.setInt(count++, user.getAge());
			ps.execute();
			ps.close();

		} catch (SQLException e) {
			e.printStackTrace();
		} 
	}

	// 修改
	public void update(UserModel user,Connection conn) {

		try {
			final String sql = "update tbl_user set name=?, sex=?, age= ? where userId = ?";
			PreparedStatement ps = conn.prepareStatement(sql);
			int count = 1;

			ps.setString(count++, user.getName());
			ps.setString(count++, user.getSex());
			ps.setInt(count++, user.getAge());
			ps.setInt(count++, user.getUserId());
			ps.execute();
			ps.close();

		} catch (SQLException e) {
			e.printStackTrace();
		} 
	}

	// 删除
	public void delete(int userId,Connection conn) {

		try {

			final String sql = "delete from tbl_user where userId=?";
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setInt(1, userId);

			ps.execute();
			ps.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} 
	}

	// 按照主键查询一条已有的记录
	public UserModel getSingle(int userId,Connection conn) {
		UserModel user = null;

		try {

			final String sql = "select * from tbl_user where userId = ?";
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setInt(1, userId);
			ResultSet rs = ps.executeQuery();
			if (rs.next()) {
				user = this.rs2model(rs);
			}
			rs.close();
			ps.close();
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return user;
	}

	// 将查询结果存储到userModel中
	private UserModel rs2model(ResultSet rs) throws Exception {
		UserModel user = new UserModel();
		user.setUserId(rs.getInt("userId"));
		user.setName(rs.getString("name"));
		user.setSex(rs.getString("sex"));
		user.setAge(rs.getInt("age"));
		return user;
	}

	// 查询所有记录
	public List getAll(Connection conn) {
		List list = new ArrayList();

		try {

			final String sql = "select * from tbl_user order by userId";
			PreparedStatement ps = conn.prepareStatement(sql);
			ResultSet rs = ps.executeQuery();
			while (rs.next()) {
				UserModel user = this.rs2model(rs);
				list.add(user);
			}
			rs.close();
			ps.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return list;
	}

	/*
	 * 以下实现按条件查询 getByCondition方法调用generateWhere()和preparedPs()方法实现
	 */

	// 实现按照组合条件查询所有符合条件的记录
	private String generateWhere(UserModel uqm) {
		StringBuffer buffer = new StringBuffer();
		// 用户选择编号作为条件
		if (uqm.getUserId() > 0) {
			buffer.append(" and userId = ?");
		}
		// 用户选择姓名作为条件
		if (uqm.getName() != null && uqm.getName().trim().length() > 0) {
			buffer.append(" and name like ?");
		}
		if (uqm.getSex() != null && uqm.getSex().trim().length() > 0) {
			buffer.append(" and sex = ?");
		}
		// 年龄的最小值
		if (uqm.getAge() > 0) {
			buffer.append(" and age >= ?");
		}
		if (uqm.getAge2() > 0) {
			buffer.append(" and age<= ?");
		}
		return buffer.toString();
	}

	// 参数
	private void preparedPs(UserModel uqm, PreparedStatement ps)
			throws Exception {
		int count = 1;
		if (uqm.getUserId() > 0) {
			ps.setInt(count++, uqm.getUserId());
		}
		if (uqm.getName() != null && uqm.getName().trim().length() > 0) {
			ps.setString(count++, "%" + uqm.getName() + "%");
		}
		if (uqm.getSex() != null && uqm.getSex().trim().length() > 0) {
			ps.setString(count++, uqm.getSex());
		}
		if (uqm.getAge() > 0) {
			ps.setInt(count++, uqm.getAge());
		}
		if (uqm.getAge2() > 0) {
			ps.setInt(count++, uqm.getAge2());
		}
	}

	// 按条件查询,调用generateWhere(),preparedPs()实现
	public List getByCondition(UserModel uqm,Connection conn) {
		List list = new ArrayList();

		try {

			final String sql = "select * from tbl_user where 1=1"
					+ this.generateWhere(uqm) + " order by userId";
			PreparedStatement ps = conn.prepareStatement(sql);
			this.preparedPs(uqm, ps);
			ResultSet rs = ps.executeQuery();
			while (rs.next()) {
				UserModel user = this.rs2model(rs);
				list.add(user);
			}
			rs.close();
			ps.close();

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return list;
	}
}

UserModel.java(简单的bean)

public class UserModel {
	private int userId;
	private String name;
	private String sex;
	private int age;
	public int getUserId() {
		return userId;
	}
	public void setUserId(int userId) {
		this.userId = userId;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

Test.java(简单的测试类,展示使用方法)

import java.sql.Connection;

public class Test {

	public static void main(String[] args) {
		Connection conn = ConnectionFactory.getConnection();//获取数据库连接
		UserJDBCDAO dao = new UserJDBCDAO();//创建SQL处理类的实例
		dao.delete(conn);//执行某一个操作
		DBClose.close(conn);//关闭数据库
	}

}

在上面Test.java里可以清楚的看到我们把连接数据库操作的步骤分为4步:1.创建连接 2.实例化操作类 3.执行操作 4.关闭数据源,这也使得整个数据库部分的耦合度大大降低,大家在一开始编程的时候就应该养成这种良好的思维方式。以上代码可以在非常多的项目中复用。

最后希望我的代码能对你有所帮助,欢迎提问。



你可能感兴趣的:(数据库问题与JDBC连接)