目录
1. db.properties配置
driver=com.mysql.jdbc.Driver
url="jdbc:mysql://localhost:3306/[数据库名]useUnicode=true&characterEncoding=utf8&useSSL=true"
username=[用户名];
password=[密码];
2. 创建JdbcUtils类
src下创建utils目录
创建JdbcUtils类
public class JdbcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
static{
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
try {
properties.load(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static java.sql.Connection getConnection() throws SQLException{
return DriverManager.getConnection(url,username,password);
}
//释放资源
public static void release(Connection conn,Statement st,ResultSet rs) throws SQLException{
if(conn!=null) conn.close();
if(st!=null) st.close();
if(rs!=null) rs.close();
}
}
2.1使用 JdbcUtils类
Connection conn = null;
Statement st = null;
ResultSet rs = null;
//这里会报异常,try-catch它
conn = JdbcUtils.getConnection();
st = conn.createStatement();
String sql = "";
rs = st.execute(sql);
//释放放在try-catch的finally中,即无论执不执行try都会释放
JdbcUtils.release(conn,st,rs);
3. 使用占位符实现sql语句动态更改
//使用?占位符
String sql = "insert into users(id,'name','password','email') values(?,?,?,?)";
st = conn.createStatement();
//赋值
st.setInt(1,1);
st.setString(2,"olarian");
st.setString(3,"123456");
st.setString(4,"12431324325312@qq.com");
//执行sql,括号里不需要参数
st.executeUpdate();
4. SQL注入
SQL存在漏洞,例如:"" or “1=1” 被判断为真,通过了系统的检验
5. PreparedStatement
优点:
- 防止SQL注入
原理:把传入的参数默认当作字符,假设其中存在转义字符,比如说 ',会被直接转义 - 效率更高
使用方法:
//为了在try外使用conn,提前定义
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
//这里会报异常
conn = JdbcUtils.getConnection();
//编写SQL语句
String sql = "";
//预编译SQL
st = conn.preparedStatement(sql);
//执行,获取结果
rs = st.execute();
6. 数据库连接池
产生原因(即解决了什么问题):
因为getConnecion后需要release,获得连接再到释放的过程是非常浪费系统资源的,所以诞生了池化技术。
池化技术:提前准备一些连接,等待被使用,使用后放回
名词:最小连接数、最大连接数、等待超时
数据源:DBCP、C3P0等
如何实现?
需要实现一个接口:DataSource,这是数据源底层机制实现的
使用DBCP:
-
导入 commons-dbcp-1.4.jar和commons-pool-1.6.jar
-
配置 dbcpconfig.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/3306?useUnicode=true&characterEncoding=utf8&setSSL=true // 驱动注册
username=[用户名]
password=[密码]
defaultAutoCommit=true:// 设置是否自动提交,默认为true
defaultReadOnly=false: // 是否为只读 默认为false
defaultTransactionIsolation=3:// 设置数据库的事务隔离级别默认为1,READ_UNCOMMITTED,推荐设置为3
initialSize=10: // 初始化数据库连接池拥有的连接数量
maxActive=50: /池中最多可容纳的活着的连接数量,当达到这个数量不在创建连接
maxIdle=20: // 最大空闲等待,也就是连接等待队列超过这个值会自动回收未使用的连接,直到达到20
minIdle=5: // 最小空闲等待 ,数据池中最少保持的连接
maxWait=10000 // 最大等待时间(ms),超过这个时间等待队列中的连接就会失效
testOnBorrow=true //从池中取出连接时完成校验 ,验证不通过销毁这个connection,默认为true,
testOnReturn=false //放入池中时完成校验,默认为fasle
validationQuery=[sql语句] // 校验语句,必须是查询语句,至少查询一列,设置了它onBorrow才会生效
validationQueryTimeout=1 // 校验查询时长,如果超过,认为校验失败
testWhileIdle=false // 清除一个连接时是否需要校验
timeBetweenEvictionRunsMillis=1 // DBCP默认有个回收器Eviction,这个为设置它的回收时间周期
numTestsPerEvictionRun=3 // Eviction在运行时一次处理几个连接
poolPreparedStatements=true //是否缓存PreparedStatements
maxOpenPreparedStatements=1 // 缓存PreparedStatements的最大个数
- 创建工具类 JdbcUtils_DBCP
public class JdbcUtils_DBCP {
private static Datasource datasource;
static{
try {
InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties properties = new Properties();
properties.load(in);
//创建数据源,使用了工厂模式
datasource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static java.sql.Connection getConnection() throws SQLException{
//从数据源中获取连接
return datasource.getConnection();
}
//释放资源
public static void release(Connection conn,Statement st,ResultSet rs) throws SQLException{
if(conn!=null) conn.close();
if(st!=null) st.close();
if(rs!=null) rs.close();
}
}