jdbc
什么是jdbc
JDBC就是由sun公司定义的一套操作所有关系型数据库的规则(接口),而数据库厂商需要实现这套接口,提供数据库驱动jar包, 我们可以使用这套接口编程,真正执行的代码是对应驱动包中的实现类。
## jdbc初尝试
需要的对象
connection 连接 statement 语句 resultset结果集(只有查询是会用)
public static void main ( String[ ] args) throws Exception {
Class. forName ( "com.mysql.jdbc.Driver" ) ;
Connection co = DriverManager. getConnection ( "jdbc:mysql://localhost:3306/lianxi01?characterEncoding=UTF-8" , "root" , "root" ) ;
Statement statement = co. createStatement ( ) ;
String sql= "insert into jdbc_user value(6,'潘耀1','123456','1998-9-20')" ;
int i = statement. executeUpdate ( sql) ;
System. out. println ( i) ;
}
JDBCutils的编写
public class JDBCutils {
public static final String DRIVERNAME= "com.mysql.jdbc.Driver" ;
public static final String URL= "jdbc:mysql://localhost:3306/lianxi01?characterEncoding=UTF-8" ;
public static final String username= "root" ;
public static final String password= "root" ;
static {
try {
Class. forName ( DRIVERNAME) ;
} catch ( ClassNotFoundException e) {
e. printStackTrace ( ) ;
}
}
public static Connection getConnection ( ) {
Connection connection = null;
try {
connection = DriverManager. getConnection ( URL, username, password) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
return connection;
}
public static void close ( Connection connection, Statement statement) {
if ( connection!= null&& statement!= null) {
try {
statement. close ( ) ;
connection. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
public static void close ( Connection connection, Statement statement, ResultSet resultSet) {
if ( connection!= null&& statement!= null&& resultSet!= null) {
try {
statement. close ( ) ;
connection. close ( ) ;
resultSet. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
}
JDBC的DML DQL 操作使用
public static void main ( String[ ] args) {
Connection connection = JDBCutils. getConnection ( ) ;
Statement statement= null;
try {
statement = connection. createStatement ( ) ;
String sql= "SELECT * FROM jdbc_user WHERE username='test2'" ;
ResultSet resultSet = statement. executeQuery ( sql) ;
while ( resultSet. next ( ) ) {
System. out. println ( resultSet. getInt ( "id" ) ) ;
System. out. println ( resultSet. getString ( "username" ) ) ;
System. out. println ( resultSet. getString ( "password" ) ) ;
System. out. println ( resultSet. getDate ( "birthday" ) ) ;
}
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
JDBCutils. close ( connection, statement) ;
}
sql注入问题
SELECT * FROM jdbc_user WHERE username='ojbk' AND PASSWORD='123456' OR '1'='1'
这条sql语句 false or true ,因此不管前面用户名密码正确与否都能查到数据
因此 不能使用Statement而使用prepareStatement 也就是 要解决 SQL 注入就不能让用户输入的密码和我们的 SQL 语句进 行简单的字符串拼接。
"where username = " + " '" + name + "' " + " and password = " + " '" + pass + "'" ; -- -- 禁止使用
public static void main ( String[ ] args) {
Connection connection = JDBCutils. getConnection ( ) ;
PreparedStatement ps= null;
ResultSet resultSet= null;
try {
String sql= "SELECT * FROM jdbc_user WHERE username=?" ;
ps = connection. prepareStatement ( sql) ;
ps. setString ( 1 , "潘耀" ) ;
resultSet = ps. executeQuery ( ) ;
while ( resultSet. next ( ) ) {
System. out. println ( resultSet. getInt ( "id" ) ) ;
System. out. println ( resultSet. getString ( "username" ) ) ;
System. out. println ( resultSet. getString ( "password" ) ) ;
System. out. println ( resultSet. getDate ( "birthday" ) ) ;
}
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
JDBCutils. close ( connection, ps, resultSet) ;
}
Statement 与 PreparedStatement的区别?
1. Statement用于执行静态SQL语句,在执行时,必须指定一个事先准备好的SQL语句。
2. PrepareStatement是预编译的SQL语句对象,语句中可以包含动态参数“?”,在执行时可以为“?”动态设置参数
值。
3. PrepareStatement可以减少编译次数提高数据库性能。
jdbc事务操作
public static void main ( String[ ] args) {
Connection con = null;
PreparedStatement ps = null;
try {
con = JDBCutils. getConnection ( ) ;
con. setAutoCommit ( false ) ;
ps = con. prepareStatement ( "update account set money = money - ? where name = ? " ) ;
ps. setDouble ( 1 , 500.0 ) ;
ps. setString ( 2 , "tom" ) ;
ps. executeUpdate ( ) ;
ps = con. prepareStatement ( "update account set money = money + ? where name = ? " ) ;
ps. setDouble ( 1 , 500.0 ) ;
ps. setString ( 2 , "jack" ) ;
ps. executeUpdate ( ) ;
con. commit ( ) ;
System. out. println ( "转账成功!" ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
try {
con. rollback ( ) ;
} catch ( SQLException ex) {
ex. printStackTrace ( ) ;
}
} finally {
JDBCutils. close ( con, ps) ;
}
}
数据库连接池
1) 什么是连接池
实际开发中“获得连接”或“释放资源”是非常消耗系统资源的两个过程,为了解决此类性能问题,通常情况我们采用连接池技术,来共享连接Connection。这样我们就不需要每次都创建连接、释放连接了,这些操作都交给了连接池.
2) 连接池的好处
用池来管理Connection,这样可以重复使用Connection。 当使用完Connection后,调用Connection的
close()方法也不会真的关闭Connection,而是把Connection“归还”给池。
3)常见的连接池有
DBCP连接池, C3P0连接池, Druid连接池
4)我这块主要分享下Druid连接池
Druid(德鲁伊)是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是目前最好的数据库连接池。在功能、性能、扩展性方面,都超过其他数据库连接池,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况。
1. 导入jar包及配置文件
2.导入配置文件
是properties形式的
可以叫任意名称,可以放在任意目录下,我们统一放到 resources资源目录
3.编写Druid工具类
获取数据库连接池对象
通过工厂来来获取 DruidDataSourceFactory类的createDataSource方法
createDataSource(Properties p) 方法参数可以是一个属性集对象
public class DruidUtils {
public static DataSource dataSource;
static {
try {
Properties p = new Properties ( ) ;
InputStream inputStream =
DruidUtils. class . getClassLoader ( ) . getResourceAsStream ( "druid.properties" ) ;
p. load ( inputStream) ;
dataSource = DruidDataSourceFactory. createDataSource ( p) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
}
}
public static void close ( Connection con, Statement statement) {
if ( con != null && statement != null) {
try {
statement. close ( ) ;
con. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
public static void close ( Connection con, Statement statement, ResultSet resultSet) {
if ( con != null && statement != null && resultSet != null) {
try {
resultSet. close ( ) ;
statement. close ( ) ;
con. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
}
4. 使用 Druid连接池
public class TestDruid {
public static void main ( String[ ] args) throws SQLException {
Connection con = DruidUtils. getConnection ( ) ;
Statement statement = con. createStatement ( ) ;
ResultSet resultSet = statement. executeQuery ( "select ename from employee where salary between 3000 and 5000" ) ;
while ( resultSet. next ( ) ) {
String ename = resultSet. getString ( "ename" ) ;
System. out. println ( ename) ;
}
DruidUtils. close ( con, statement, resultSet) ;
}
}
DBUtils工具类
1.DBUtils简介
使用JDBC我们发现冗余的代码太多了,为了简化开发 我们选择使用 DbUtils
Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程
序的开发,同时也不会影响程序的性能。
2.使用方式:
DBUtils就是JDBC的简化开发工具包。需要项目导入 commons-dbutils-1.6.jar。
3.Dbutils核心功能介绍
1. QueryRunner 中提供对sql语句操作的API.
2. ResultSetHandler接口,用于定义select操作后,怎样封装结果集.
3. DbUtils类,他就是一个工具类,定义了关闭资源与事务处理相关方法.
4.QueryRunner核心类
构造方法QueryRunner()
QueryRunner(DataSource ds) ,提供数据源(连接池),DBUtils底层自动维护连接connection常用方法
update(Connection conn, String sql, Object... params) ,用来完成表数据的增加、删除、更新操作
query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) ,用来完成表
数据的查询操作
5.DBUtils CRUD操作
添加
@Test
public void testInsert ( ) throws SQLException {
QueryRunner qr = new QueryRunner ( ) ;
String sql = "insert into employee values(?,?,?,?,?,?)" ;
Object[ ] param = { null, "张百万" , 20 , "女" , 10000 , "1990-12-26" } ;
Connection con = DruidUtils. getConnection ( ) ;
int i = qr. update ( con, sql, param) ;
DbUtils. closeQuietly ( con) ;
}
@Test
public void testUpdate ( ) throws SQLException {
QueryRunner qr = new QueryRunner ( DruidUtils. getDataSource ( ) ) ;
String sql = "update employee set salary = ? where ename = ?" ;
Object[ ] param = { 0 , "张百万" } ;
qr. update ( sql, param) ;
}
@Test
public void testDelete ( ) throws SQLException {
QueryRunner qr = new QueryRunner ( DruidUtils. getDataSource ( ) ) ;
String sql = "delete from employee where eid = ?" ;
qr. update ( sql, 1 ) ;
}
QueryRunner实现查询操作
ResultSetHandler接口简介
ResultSetHandler可以对查询出来的ResultSet结果集进行处理,达到一些业务上的需求。
@Test
public void testFindByIdJavaBean ( ) throws SQLException {
QueryRunner qr = new QueryRunner ( DruidUtils. getDataSource ( ) ) ;
String sql = "select * from employee where eid = ?" ;
Employee employee = qr. query ( sql, new BeanHandler < Employee> ( Employee. class ) , 3 ) ;
System. out. println ( employee) ;
}