java连接数据库()的多种方法

本文详细介绍了使用JDBC进行数据库操作的各种方法,包括直接使用JDBC、自定义连接池、以及使用C3P0、DBCP和Druid等第三方连接池。探讨了如何优化SQL查询防止SQL注入,以及如何利用ResultSetHandler处理查询结果。
摘要由CSDN通过智能技术生成

0.准备工作,有mysql,数据库,表格

1,使用原生的jdbc来连接(需要lib/mysql-connector-java-5.0.4-bin.jar);javax.sql

	public static Connection getConnection() throws Exception {
		Class.forName("com.mysql.jdbc.Driver");
		String url = "jdbc:mysql://localhost:3306/web08";
		return DriverManager.getConnection(url, "root", "root");
	}

---------------------------------------------------------
@Test
	public void query() {
		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			con = getConnection();
			stmt = con.createStatement();
			String sql = "select * from user";
			rs = stmt.executeQuery(sql);
			while(rs.next()) {
				String username = rs.getString(1);//从1开始
				String password = rs.getString(2);//参数改为列名更好
				System.out.println(username + ", " + password);
			}
		} catch(Exception e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if(rs != null) rs.close();
				if(stmt != null) stmt.close();
				if(con != null) con.close();
			} catch(SQLException e) {}
		}
	}
	//有被注入的风险
---------------------------------------------------------------------------------
//改进
String sql = “select * from tab_student where s_number=?”;
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, “S_1001”);
ResultSet rs = pstmt.executeQuery();
rs.close();
pstmt.clearParameters();
pstmt.setString(1, “S_1002”);
rs = pstmt.executeQuery();

2.自定义数据库连接池,实现DateSource接口
2.1装饰者设计模式,扩展
后期再去补充

3.使用第三方的C3P0
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。
在项目的src目录下创建c3p0-config.xml文件,当然你也可以创建一个c3p0.properties文件

public class JDBCUtils2 {
	private static final ComboPooledDataSource DATA_SOURCE =new ComboPooledDataSource();
	/**
	 * 获得连接的方法
	 */
	public static Connection getConnection(){
		Connection conn = null;
		try {
			conn = DATA_SOURCE.getConnection();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return conn;
	}


BeanUtils位于org.apache.commons.beanutils.BeanUtils下面,其方法populate的作用解释如下:
完整方法:
BeanUtils.populate( Object bean, Map properties ),
这个方法会遍历map<key, value>中的key,如果bean中有这个属性,就把这个key对应的value值赋给bean的属性。

4.使用第三方的DBCP
DBCP(DataBase connection pool),数据库连接池。是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。
单独使用dbcp需要2个包:commons-dbcp.jar,commons-pool.jar由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。

/**
	 * 手动方式:
	 */
	public void demo1(){
		Connection conn = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql:///web_07");
		dataSource.setUsername("root");
		dataSource.setPassword("123");
		try{
			// 获得连接:
			conn = dataSource.getConnection();
			// 编写SQL:
			String sql = "select * from category";
			// 预编译SQL:
			stmt = conn.prepareStatement(sql);
			// 执行SQL:
			rs = stmt.executeQuery();
			while(rs.next()){
				System.out.println(rs.getInt("cid")+"   "+rs.getString("cname"));
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtils.release(rs,stmt, conn);
		}
	}
	
	@Test
	/**
	 * 配置文件方式:
	 */
	public void demo2(){
		Connection conn = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		Properties properties = new Properties();
		
		try{
			properties.load(new FileInputStream("src/dbcpconfig.properties"));
			DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);
			// 获得连接:
			conn = dataSource.getConnection();
			// 编写SQL:
			String sql = "select * from category";
			// 预编译SQL:
			stmt = conn.prepareStatement(sql);
			// 执行SQL:
			rs = stmt.executeQuery();
			while(rs.next()){
				System.out.println(rs.getInt("cid")+"   "+rs.getString("cname"));
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtils.release(rs,stmt, conn);
		}
	}



5.使用第三方的Druid
dbconfig.properties配置文件

public class DruidUtil {
// 得到一个Druid的数据源
private static DruidDataSource dataSource = null;

static{
    Properties properties = new Properties();
    try {
        //加载配置文件
        //properties.load(new FileInputStream("build/classes/dbconfig.properties"));
        //下面这种写法会从classpath下来查找配置文件
        properties.load(DruidUtil.class.getClassLoader().getResourceAsStream("dbconfig.properties"));
        //得到一个数据源 
        dataSource = (DruidDataSource)DruidDataSourceFactory.createDataSource(properties);
    } catch (Exception e) {
        e.printStackTrace();
    }
}


// 从数据源中得到一个连接对象
// 这个返回的connection实际上是Druid经过装饰之后的connection
public static Connection getConnection() {
    try {
        return dataSource.getConnection();
    } catch (SQLException e) {
        throw new RuntimeException("服务器错误");
    }
}

}
package com.monkey1024.jdbc.test;

import java.sql.Connection;
import java.sql.PreparedStatement;

import com.monkey1024.jdbc.util.DruidUtil;

public class DruidTest {

public static void main(String[] args) {
    insert();
    try {
        //睡眠一下方便查看状态
        Thread.sleep(100);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public static void insert() {

    String sql = "insert into t_user(id,name) values('12012','jack')";
    try (Connection conn = DruidUtil.getConnection(); 
            PreparedStatement ps = conn.prepareStatement(sql)) {
        ps.executeUpdate();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

}


6.返回结果处理
6.1ResultSetHandler
DBUtils提供了一个接口ResultSetHandler,它就是用来ResultSet转换成目标类型的工具。你可以自己去实现这个接口,把ResultSet转换成你想要的类型。
DBUtils提供了很多个ResultSetHandler接口的实现,这些实现已经基本够用了,我们通常不用自己去实现ResultSet接口了。
ResultSetHandler接口使用讲解
该接口用于处理java.sql.ResultSet,将数据按要求转换为另一种形式。
ResultSetHandler接口提供了一个单独的方法:Object handle (java.sql.ResultSet .rs)
6.1.1	MapHandler:单行处理器!把结果集转换成Map<String,Object>,其中列名为键!
6.1.2	MapListHandler:多行处理器!把结果集转换成List<Map<String,Object>>;
6.1.3	BeanHandler:单行处理器!把结果集转换成Bean,该处理器需要Class参数,即Bean的类型;
6.1.4	BeanListHandler:多行处理器!把结果集转换成List<Bean>;
6.1.5ArrayHandler:把结果集中的第一行数据转成对象数组。
6.1.6ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
6.1.7BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
6.1.8BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
6.1.9ColumnListHandler:将结果集中某一列的数据存放到List中。
6.1.10KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
6.1.11 scalarHandler();    //针对Long 只返回一行一列数据

6.2QueryRunner

public <T> T query(String sql, ResultSetHandler<T> rh, Object… params)

@Test
public void fun1() throws SQLException {
	DataSource ds = JdbcUtils.getDataSource();
	QueryRunner qr = new QueryRunner(ds);
	String sql = "select * from tab_student where number=?";
	Map<String,Object> map = qr.query(sql, new MapHandler(), "S_2000");
	System.out.println(map);
}

@Test
public void fun2() throws SQLException {
	DataSource ds = JdbcUtils.getDataSource();
	QueryRunner qr = new QueryRunner(ds);
	String sql = "select * from tab_student";
	List<Map<String,Object>> list = qr.query(sql, new MapListHandler());
	for(Map<String,Object> map : list) {
		System.out.println(map);
	}
}

@Test
public void fun3() throws SQLException {
	DataSource ds = JdbcUtils.getDataSource();
	QueryRunner qr = new QueryRunner(ds);
	String sql = "select * from tab_student where number=?";
	Student stu = qr.query(sql, new BeanHandler<Student>(Student.class), "S_2000");
	System.out.println(stu);
}

@Test
public void fun4() throws SQLException {
	DataSource ds = JdbcUtils.getDataSource();
	QueryRunner qr = new QueryRunner(ds);
	String sql = "select * from tab_student";
	List<Student> list = qr.query(sql, new BeanListHandler<Student>(Student.class));
	for(Student stu : list) {
		System.out.println(stu);
	}
}

@Test
public void fun5() throws SQLException {
	DataSource ds = JdbcUtils.getDataSource();
	QueryRunner qr = new QueryRunner(ds);
	String sql = "select * from tab_student";
	List<Object> list = qr.query(sql, new ColumnListHandler("name"));
	for(Object s : list) {
		System.out.println(s);
	}
}

@Test

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值