一、JDBC(Java Database Connectivity)
JDBC是Java语言中访问数据库的应用程序接口,可以为多种关系数据库提供统一访问。
jdbc.properties
jdbc.driverClass=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://127.0.0.1:1433;DatabaseName=test
jdbc.username=root
jdbc.password=root
测试类
public class DBUtil {
public static Connection getConnection() throws IOException, ClassNotFoundException, SQLException {
Properties props = new Properties();
props.load(new FileInputStream("jdbc.properties"));
Class.forName(props.getProperty("jdbc.driverClass"));
String url = props.getProperty("jdbc.url");
String username = props.getProperty("jdbc.username");
String password = props.getProperty("jdbc.password");
return DriverManager.getConnection(url, username, password);
}
public static List<Student> query(String name) throws ClassNotFoundException, IOException, SQLException {
Connection conn = getConnection();
Statement st = conn.createStatement();
String sql = "select * from student where name='" + name + "'";
ResultSet rs = st.executeQuery(sql);
List<Student> list = new ArrayList<Student>();
while (rs.next()) {
int id = rs.getInt("id");
list.add(new Student(id, name));
}
st.close();
conn.close();
return list;
}
public static int insert(Student student) throws ClassNotFoundException, IOException, SQLException {
Connection conn = getConnection();
PreparedStatement pstmt = null;
int result = 0;
String sql = "insert into student(id, name) values(?, ?)";
try {
pstmt = (PreparedStatement) conn.prepareStatement(sql);
pstmt.setInt(1, student.getId());
pstmt.setString(2, student.getName());
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if(pstmt!=null)
pstmt.close();
if(conn!=null)
conn.close();
}
return result;
}
public static void main(String[] args) throws ClassNotFoundException, IOException, SQLException {
System.out.println("insert " + insert(new Student(1, "Anne")) + " records.");
System.out.println(query("Anne"));
}
}
二、DBCP
JDBC的访问模式存在以下问题:
1. 现在的Web应用经常有几千人同时访问,然而频繁的进行数据库连接操作不仅耗时,还会占用很多的系统资源,导致网站的响应速度下降,严重的甚至会造成服务器的崩溃。
2. 对于每一次数据库连接,使用完后都得断开。如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将不得不重启数据库。
3. 这种开发方式不能控制创建的连接数,系统资源会被毫无顾及的分配出去,连接过多可能导致内存泄漏,服务器崩溃。
为了解决资源的频繁分配、释放所造成的问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。Java中常用的两个数据库连接池: DBCP和C3P0
导入jar包 commons-dbcp-1.4.jar 和 commons-pool-1.3.jar
a. 直接代码实现
public class ConnectionFactory {
private static final Logger logger = Logger.getLogger(ConnectionFactory.class);
private PoolingDataSource dataSource = null;
private ObjectPool CP =null;
private static ConnectionFactory connectionFactory = new ConnectionFactory();
private ConnectionFactory() {
}
public static ConnectionFactory getInstance() {
return connectionFactory;
}
private void configure () throws ClassNotFoundException {
try {
Properties props = new Properties();
props.load(new FileInputStream("jdbc.properties"));
Class.forName(props.getProperty("jdbc.driverClass"));
String url = props.getProperty("jdbc.url");
String username = props.getProperty("jdbc.username");
String password = props.getProperty("jdbc.password");
dataSource = setupDataSource(url, username, password);
} catch (IOException e) {
logger.error("ConnectionFactory.configure() error", e);
}
}
public synchronized Connection getConnection() throws SQLException{
Connection conn = null;
try {
if (dataSource == null) {
configure();
}
conn = dataSource.getConnection();
} catch (SQLException e) {
logger.error("ConnectionFactory.getConnection() error", e);
throw e;
} catch (ClassNotFoundException e) {
logger.error("ConnectionFactory.getConnection() error", e);
throw new SQLException("Drive Class not found exception.");
}
return conn;
}
public void shutDown () {
try {
logger.info("db connection pool shut down is called");
CP.close();
} catch (Exception e) {
logger.error("db connection pool shut down throws exception");
}
}
private PoolingDataSource setupDataSource(String connectURI, String user, String password) {
GenericObjectPool.Config config = new GenericObjectPool.Config();
config.maxActive = 150;
config.maxIdle = 100;
config.minIdle = 30;
config.maxWait = 1000;
ObjectPool connectionPool = new GenericObjectPool(null, config);
DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(connectURI, user, password);
@SuppressWarnings("unused")
PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(
connectionFactory, connectionPool, null, null, false, true);
PoolingDataSource poolingDataSource = new PoolingDataSource(connectionPool);
CP = connectionPool;
return poolingDataSource;
}
}
b. 使用配置文件
driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
url=jdbc:sqlserver://127.0.0.1:1433;DatabaseName=test
username=root
password=root
#<!-- 初始化连接 -->
dataSource.initialSize=10
#<!-- 最大空闲连接 -->
dataSource.maxIdle=20
#<!-- 最小空闲连接 -->
dataSource.minIdle=5
#最大连接数量
dataSource.maxActive=50
#是否在自动回收超时连接的时候打印连接的超时错误
dataSource.logAbandoned=true
#是否自动回收超时连接
dataSource.removeAbandoned=true
#超时时间(以秒数为单位)
dataSource.removeAbandonedTimeout=180
#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
dataSource.maxWait=1000
public static DataSource getDataSource () {
DataSource dataSource = null;
try {
Properties props = new Properties();
props.load(DBUtil.class.getResourceAsStream("dbcp.properties"));
dataSource = BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
throw new DBException("file not found: dbcp.properties");
}
return dataSource ;
}
三、Spring
jtds
JPA
Hibernate