28.javaEE-JDBC/sql注入/数据库连接池(c3p0/druid)

JDBC

JDBC( Java DataBase Connectivity ) 翻译过来就是Java数据库连接,其实就是通过Java语言操作数据库的一门技术。

一.JDBC连接步骤

连接步骤:
1.注册相关数据库的驱动,也就是将相关数据库厂商实现的Driver加载到JVM中;
2.获取数据库连接对象,Connection;
3.获取传输器对象Statement;
4.编写/得到sql语句,执行sql语句,得到结果集对象ResultSet;
5.处理结果Result.next();
6.释放资源;

具体代码如下.

public static void main(String[] args) throws Exception {
		//1.注册数据库驱动,将mysql实现的JDMC类加载到元数据区
		Class.forName("com.mysql.jdbc.Driver");
		
		//2.获取数据库连接(jdbc:mysql数据库->本地计算机:端口是3306->数据库名称->编码格式)
		Connection conn = DriverManager.getConnection(
				"jdbc:mysql://localhost:3306/jt_db?characterEncoding=utf-8",
				"root", "123456");
		
		//3.获取传输器
		Statement stat = conn.createStatement();
		
		//4.执行sql语句,返回执行结果
		String sql = "select * from account;";
		ResultSet rs = stat.executeQuery(sql);
		
		//5.处理结果
		while(rs.next()) {
			System.out.print("id:" + rs.getInt("id") + " ");
			System.out.print("name:" + rs.getString("name") + " ");
			System.out.print("money:" + rs.getDouble("money"));
			System.out.println();
		}
		
		//6.释放资源
		rs.close();
		stat.close();
		conn.close();
		
		System.out.println("JdbcDemo1.main()");
	}

二.JDBC连接详解.

1、注册数据库驱动 Class.forName(“com.mysql.jdbc.Driver”);

所谓的注册驱动,就是让JDBC程序加载mysql驱动程序,并管理驱动 驱动程序实现了JDBC API定义的接口以及和数据库服务器交互的功能,加载驱动是为了方便使用这些功能。

2、获取连接之数据库URL

Connection conn = DriverManager.getConnection(
“jdbc:mysql://localhost:3306/jt_db?characterEncoding=utf-8”,
“root”, “root” ); DriverManager.getConnection() 用于获取数据连接,
返回的Connection连接对象是JDBC程序连接数据库至关重要的一个对象。

参数2和参数3分别是所连接数据库的用户名和密码。 参数1:“jdbc:mysql://localhost:3306/jt_db”
是连接数据库的URL,用于指定访问哪一个位置上的数据库服务器及服务器中的哪一个数据库,其写法为:

当连接本地数据库,并且端口为3306,可以简写为如下形式: jdbc:mysql:///jt_db

3、Statement传输器对象

Statement stat = conn.createStatement();
Statement传输器对象用于向数据库服务器发送sql语句,该对象上提供了发送sql的方法: executeQuery(String
sql) – 用于向数据库发送查询类型的sql语句,返回一个ResultSet对象中 executeUpdate(String sql) –
用于向数据库发送更新(增加、删除、修改)类型的sql语句,返回一个int值,表示影响的记录行数

4、ResultSet结果集对象

ResultSet对象用于封装sql语句查询的结果,也是一个非常重要的对象。该对象上提供了遍历数据及获取数据的方法。
(1)遍历数据行的方法
next() – 使指向数据行的索引向下移动一行

(2)获取数据的方法:
getInt(int columnIndex)
getInt(String columnLable)
getString(int columnIndex)
getString(String columnLable)
getDouble(int columnIndex)
getDouble(String columnLable)
getObject(int columnIndex)
getObject(String columnLable)

5、释放资源

rs.close(); stat.close(); conn.close();
此处释放资源必须按照一定的顺序释放,越晚获取的越先关闭。所以先关闭 rs对象,再关闭stat对象,最后关闭conn对象。
另,为了避免上面的程序抛出异常,释放资源的代码不会执行,应该把释放资源的代码放在finally块中.

正确关闭资源的姿势.

try{
	...
}catch(Exception e){
	...
}finally{
	if (rs != null) {
		try {
			rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			rs = null;
		}
	}
	if (stat != null) {
		try {
			stat.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			stat = null;
		}
	}
	if (conn != null) {
		try {
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			conn = null;
		}
	}
}

三.SQL注入
sql注入:
后台接收到前台传入的参数,做sql字符串拼接时,可能会被前台的一个特殊符号攻击,改变了原有设计的sql的意思,导致数据库资料泄露或者损坏.故使用prepareStatement骨架对象来替换Statement执行sql语句.
例如:

public class LoginUser2 {
	public static void main(String[] args) throws Exception {
			//1.提示用户登录,输入用户名和密码,并接收
			Scanner sc = new Scanner(System.in);
			System.out.println("登录信息!!");
			System.out.println("请输入用户名:");
			String username = sc.nextLine();
			System.out.println("请输入密码:");
			String password = sc.nextLine();
			
			sc.close();
			//2.根据用户名和密码查询User
			LoginUser2.login(username, password);
	}

	/**
	 * 执行数据库操作的方法.用占位符号?代替参数,
	 * 后期将参数传入即可,可避免sql注入攻击
	 * @param username
	 * @param password
	 */
	private static void login(String username,String password) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			//1.获取连接器
			conn = JdbcUtil.getConnection();
			
			//2.确定sql语句的骨架,用问号来占位
			String sql = "select * from user where username=? and password=?";
			ps = conn.prepareStatement(sql);
			
			//3.设置sql语句的参数,用来替代?的位置
			ps.setString(1, username);//给第一个问号,设置的值username
			ps.setString(2, password);//给第二个问号,传入的值password
			
			//4.执行sql语句
			rs = ps.executeQuery();
			
			//5.结果处理
			if(rs.next()) {
				System.out.println("登录成功");
			}else {
				System.out.println("登录失败,用户名和密码不匹配!");
			}
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			JdbcUtil.close(conn, ps, rs);
		}

	}
}

四.数据库连接池(Datasource)
在开发中,所谓的池就是一个容器,来存储程序的中的数据.
而数据库连接池就是用来存储数据库连接的池子,用于在整个程序中共享连接,减少连接开关的次数,实现连接的复用,从而提高程序执行的效率.在这里插入图片描述
常用数据库连接池.
c3p0连接池
使用C3P0连接池开发步骤:
1.导入开发包或者pom文件引入依赖
在这里插入图片描述
或者导入依赖

<dependency>
        <groupId>com.mchange</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.5.2</version>
 </dependency>

2、创建数据库连接池

ComboPooledDataSource pool = new ComboPooledDataSource();		

3、设置数据库连接的基本信息
(1)方式一:(不推荐)

			//给pool初始化赋值,这种把代码写死的不好,运用配置文件,构建连接池更好
			pool.setDriverClass("com.mysql.jdbc.Driver");
			pool.setJdbcUrl("jdbc:mysql://localhost:3306/jt_db?characterEncoding=utf-8");
			pool.setUser("root");
			pool.setPassword("123456");

(2)方式二:(推荐)
在类目录下(开发时可以放在src或者类似的源码目录下), 添加一个c3p0.properties文件, 配置内容如下:

c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///jt_db
c3p0.user=root
c3p0.password=123456

(3)方式二:(推荐)
在类目录下(开发时可以放在src或者类似的源码目录下), 添加一个c3p0-config.xml文件, 配置内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<default-config>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql:///jt_db?characterEncoding=utf-8</property>
		<property name="user">root</property>
		<property name="password">123456</property>
	</default-config>
</c3p0-config>

druid连接池
druid是由阿里巴巴开发的一个开源数据库连接池框架,他不仅支持数据库连接,还支持监控,后期我们很多项目都是用的druid连接池.

发布了42 篇原创文章 · 获赞 0 · 访问量 657

猜你喜欢

转载自blog.csdn.net/weixin_45449911/article/details/104537821