Statement 操作流程
//1 导入并加载驱动
Class.forName("com.mysql.jdbc.Driver") ;
//8.0及以上数据库为 Class.forName("com.mysql.cj.jdbc.Driver");
//2 获取数据库的连接对象
Connnection connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/库名",
//如果mysql8.0以上则需要在库名后追加 ?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
"root",
"登录数据库的密码"
) ;
//3 准备sql语句
String sql = "select * from 表名" ;
//4 获取执行对象Statement
Statement statement = connection.createStatement() ;
//5 执行dql语句
ResultSet rs = statement.executeQuery(sql) ;
//6 返回执行语句后的所获取到的结果
while(rs.next()){
//将返回到的结果的值赋给变量 并在控制台中输出。
字段类型 变量名= rs.getXXX("字段名称") ;
//或是 字段类型 变量名 = rs.getXXX(列的索引值) ; //列的索引值1..开始
//使用这个变量名
}
//7 释放资源
rs.close();
statement .close() ;
connection .close() ;
PreparedStatement 操作流程
其实操作流程具体与 Statement 流程大同小异
//1 导包并注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//2 获取数据库的连接对象
Connection connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/库名",
"root",
"登录mysql的密码"
) ;
//3 准备好参数化的sql语句 DML语句
String sql = "insert into 表名 values(?,?,?...)" ;
String sql2 = "update 表名 set 字段名称1 = ?,字段名称2 = ?,字段名称3 = ? where 字段名称 = ?" ;
String sql3 = "delete from 表名 where 字段名称 = ?" ;
//sql语句:参数化的DQL语句
String sql4 = "select * from 表名 " ;
String sql5 = "select * from 表名 where 字段名称 = ?" ;
//4 获取预编译对象,同时将sql发送给数据库
PreparedStatement ps = connection.prepareStatement(sql) ;
//5 通过预编译对象,参数赋值
ps.setXXX(占位符号的索引值,XXX类型的实际参数) ;
//6 执行DML语句
int count = ps.executeUpdate() ;
//影响的行数 count
//要执行的DQL语句
ResultSet rs = ps.executeQuery() ;
while(rs.next()){
//获取结果数据
XXX 变量名 = rs.getXXX("列的名称,列的索引值") ;
}
//7 释放资源
rs.close();
ps.close();
connection.close() ;
Statement 与 PreparedStatement 的区别:
1. PreparedStatement可以写参数化查询,比Statement能获得更好的性能。
2. 对于PreparedStatement来说,数据库可以使用已经编译过及定义好的执行语句,这种预处理语句查询比普通的查询运行速度更快。
3. PreparedStatement可以阻止常见的SQL注入式攻击。
4. PreparedStatement可以写动态查询语句
5. Statement 执行的是静态sql语句,存在字符拼接,可能会出现sql注入,会导致数据库陷入不安全的处境。 PreparedStatement预编译对象:每次是在自己内存中直接赋值对应的值,sql语句永远是占位符号? 此种不会造成sql注入问题,会比较安全。
Druid 德鲁伊数据库连接池
druid 数据库连接池:
可以分配,释放,管理数据库连接对象,当某个连接对象释放之后,会归还到连接池中,更有利于管理与操作数据库
弊端:不易维护 (需要更新druid版本以及监控它的连接数量)
好处:可以设置参数,将数据库连接池进行调优;
操作步骤:
//1 导包
//2 加入连接池的配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/库名
username=root
password=123456
initialSize=5 //初始化连接池数量
maxActive=10 //最大连接数量
maxWait=3000 //连接等待时间,超时自动断开
//3读取配置文件
InputStream inputStream = 当前类.class.getClassLoader().getResourceAsStream("xxx.properties") ;//xxx.properties 中为连接池配置文件,也可以在此设置连接池的配置
//4 创建属性集合列表
Properties prop = new Properties() ;
prop.load(inputStream) ;
//5获取数据源----DruidDataSourceFactory
DataSource ds = DruidDataSourceFactory.createDataSource( prop) ;
//DataSource替代了DriverManager: Connection getConnection() ;
//6获取连接对象
Connection conn = ds.getConnection() ;
//使用连接对象
Commons-dbutils 工具类库
DbUtils :提供如关闭连接、装载JDBC驱动程序等常规工作的工具类,里面的所有方法都是静态的(关闭资源、加载驱动)。将jdbc的操作进行简单封装,操作数据库的代码更加简便高效。
使用步骤:
1 导入核心的jar包 commons-dbtils.jar
mysql驱动jar包
连接池--druid的jar包
junit单元测试:核心包junit.jar以及依赖包
2 有关commons-dbtils.jar 核心接口以及核心类有哪些
执行对象:操作数据库
org.apache.commons.dbutils.QueryRunner 里面封装就是PreparedStatement 两个通用的方法
query(xxx,ResultSetHandler rsh):针对dql语句来完成查询操作
update(xxx,xx):针对dml域操作: insert into,update,delete from .... 核心接口:ResultSetHandler:针对结果集的处理
有很多实现类:
BeanListHandler:将查询的多条记录封装到list集合中
BeanHandler:将查询的结果其中某条记录封装到一个java实体类中
ScalarHandler:查询单行数据/查询总记录数 可以使用聚合函数:
select count(id字段) from 表名 ;
查询总记录数的返回值使用int 和long都可以
使用QueryRunner 查询数据库中表所有数据 :
@Override public List<Employee> findAll() throws SQLException { //使用Commons-dbutils 包 导入 //创建数据库连接对象 QueryRunner queryRunner = new QueryRunner((DataSource) DruidUtils.getDs()); //准备sql语句 String sql = "select * from employee"; //执行通用方法 //query(String sql,ResultSetHandler rsh) //参数1:sql语句 //参数2:结果集的处理对象:接口 //将所有记录封装到List<Employee>中 //public BeanListHandler<T>(Class<T> type) :参数是存储当前类型的字节码文件对象 List<Employee> list = queryRunner.query(sql,new BeanListHandler<Employee>(Employee.class)); return list; }
使用PreparedStatement与Commons-dbutils查询与更新数据
@Override public Employee select(int id) throws SQLException { QueryRunner queryRunner =new QueryRunner(DruidUtils.getDs()); String sql = "select from employee where id = ?"; //执行sql:将查询的这条记录封装到Employee类中 // public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params) //参数1:sql语句 //参数2:结果集的处理:BeanHandler对象 //有参构造 public BeanHandler<T>(Class<T> class) //参数3:给占位符号 赋值 Employee emp = queryRunner.query(sql,new BeanHandler<Employee>(Employee.class),id); return emp; } @Override public void add(Employee employee) { QueryRunner queryRunner =new QueryRunner(DruidUtils.getDs()); String sql = "insert into employee(name,age,gender,address,salary) values(?,?,?,?,?)"; //执行更新 //通用的方法 //update(String sql,Object...params) //参数1:sql //参数2:给占位符号赋值 try { int count = queryRunner.update(sql, employee.getName(), employee.getAge(), employee.getGender(), employee.getAddress(), employee.getSalary()); System.out.println("影响了" +count+"行"); } catch (SQLException throwables) { throwables.printStackTrace(); } } @Override public void updateEmp(Employee employee) { QueryRunner queryRunner =new QueryRunner(DruidUtils.getDs()); String sql = "update employee set name=?,age=?,gender=?,address=?,salary=? where id=?"; try { int count = queryRunner.update(sql,employee.getName() ,employee.getAge(),employee.getGender() ,employee.getAddress(),employee.getSalary() ,employee.getId()); System.out.println("影响了" +count+"行"); } catch (SQLException throwables) { throwables.printStackTrace(); } }