java技术_JAVA-JDBC技术
![](/assets/blank.gif)
1 什么是 JDBC
• JDBC(Java DataBase Connectivity)java 数据库连接
• 是 JavaEE 平台下的技术规范
• 定义了在 Java 语言中连接数据,执行 SQL 语句的标准
• 可以为多种关系数据库提供统一访问
2 什么是数据库驱动程序
• 数据库厂商对 JDBC 规范的具体实现
• 不同数据产品的数据库驱动名字有差异
• 在程序中需要依赖数据库驱动来完成对数据库的操作
3 程序操作数据库流程
![](/assets/blank.gif)
二、 JDBC3.0 标准中常用接口与类
1 Driver 接口
Driver 接口的作用是来定义数据库驱动对象应该具备的一些能力。比如与数据库建立连
接的方法的定义所有支持 java 语言连接的数据库都实现了该接口,实现该接口的类我们称
之为数据库驱动类。在程序中要连接数据库,必须先通过 JDK 的反射机制加载数据库驱动
类,将其实例化。不同的数据库驱动类的类名有区别。
加载 MySql 驱动:Class.forName("com.mysql.jdbc.Driver");
加载 Oracle 驱动:Class.forName("oracle.jdbc.driver.OracleDriver");
2 DriverManager 类
DriverManager 通过实例化的数据库驱动对象,能够建立应用程序与数据库之间建立连
接。并返回 Connection 接口类型的数据库连接对象。
2.1常用方法
• getConnection(String jdbcUrl, String user, String password)
该方法通过访问数据库的 url、用户以及密码,返回对应的数据库的 Connection 对象。
2.2JDBC URL
与数据库连接时,用来连接到指定数据库标识符。在 URL 中包括了该数据库的类型、
地址、端口、库名称等信息。不同品牌数据库的连接 URL 不同。
3 Connection 接口
Connection 与数据库的连接(会话)对象。我们可以通过该对象执行 sql 语句并返回结
果。
连接 MySql 数据库:
Connection conn = DriverManager.getConnection("jdbc:mysql://host:port/database", "user",
"password");
连接 Oracle 数据库:
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:port:database",
"user", "password");
连接 SqlServer 数据库:
Connection conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://host:port;
DatabaseName=database", "user", "password");
3.1常用方法
• createStatement():创建向数据库发送 sql 的 Statement 接口类型的对象。
• preparedStatement(sql) :创建向数据库发送预编译 sql 的 PrepareSatement 接口类型的
对象。
• prepareCall(sql):创建执行存储过程的 CallableStatement 接口类型的对象。
• setAutoCommit(boolean autoCommit):设置事务是否自动提交。
• commit() :在链接上提交事务。
• rollback() :在此链接上回滚事务。
4 Statement 接口
用于执行静态 SQL 语句并返回它所生成结果的对象。
由 createStatement 创建,用于发送简单的 SQL 语句(不支持动态绑定)。
4.1常用方法
• execute(String sql):执行参数中的 SQL,返回是否有结果集。
• executeQuery(String sql):运行 select 语句,返回 ResultSet 结果集。
• executeUpdate(String sql):运行 insert/update/delete 操作,返回更新的行数。
• addBatch(String sql) :把多条 sql 语句放到一个批处理中。
• executeBatch():向数据库发送一批 sql 语句执行。
5 PreparedStatement 接口
继承自 Statement 接口,由 preparedStatement 创建,用于发送含有一个或多个参数的 SQL
语句。PreparedStatement 对象比 Statement 对象的效率更高,并且可以防止 SQL 注入,所以
我们一般都使用 PreparedStatement。
5.1常用方法
• addBatch()把当前 sql 语句加入到一个批处理中。
• execute() 执行当前 SQL,返回个 boolean 值
• executeUpdate()运行 insert/update/delete 操作,返回更新的行数。
• executeQuery() 执行当前的查询,返回一个结果集对象
• setDate(int parameterIndex, Date x)向当前 SQL 语句中的指定位置绑定一个 java.sql.Date
值。
• setDouble(int parameterIndex, double x)向当前 SQL 语句中的指定位置绑定一个 double
值
• setFloat(int parameterIndex, float x)向当前 SQL 语句中的指定位置绑定一个 float 值
• setInt(int parameterIndex, int x)向当前 SQL 语句中的指定位置绑定一个 int 值
• setString(int parameterIndex, String x)向当前 SQL 语句中的指定位置绑定一个 String 值
6 ResultSet 接口
ResultSet 提供检索不同类型字段的方法。
6.1常用方法
• getString(int index)、getString(String columnName)
获得在数据库里是 varchar、char 等类型的数据对象。
• getFloat(int index)、getFloat(String columnName)
获得在数据库里是 Float 类型的数据对象。
• getDate(int index)、getDate(String columnName)
获得在数据库里是 Date 类型的数据。
• getBoolean(int index)、getBoolean(String columnName)
获得在数据库里是 Boolean 类型的数据。
• getObject(int index)、getObject(String columnName)
获取在数据库里任意类型的数据。
6.2ResultSet 对结果集进行滚动的方法
• next():移动到下一行。
• Previous():移动到前一行。
• absolute(int row):移动到指定行。
• beforeFirst():移动 resultSet 的最前面。
• afterLast() :移动到 resultSet 的最后面。
7 CallableStatement 接口
继承自 PreparedStatement 接口,由方法 prepareCall 创建,用于调用数据库的存储过程。
三、 JDBC 的使用
加 载 数 据 库 驱 动 程 序 → 建 立 数 据 库 连 接 Connection → 创 建 执 行 SQL 的 语 句
Statement → 处理执行结果 ResultSet → 释放资源
1 下载数据库驱动
1.1MySQL 驱动
Download Connector/J
1.2Oracle 驱动
数据库安装目录oracleproduct11.2.0dbhome_1jdbclib
![](/assets/blank.gif)
2 创建项目添加驱动
![](/assets/blank.gif)
3 通过 Statement 向表中插入数据
![](/assets/blank.gif)
3.1注册驱动
Class.forName("com.mysql.jdbc.Driver");
3.2获取连接
Connection conn
=DriverManager.getConnection("jdbc:mysql://localhost:
3306/bjsxt?useUnicode=true&characterEncoding=utf-8",
"root", "root");
3.3执行 SQL
String sql="insert into departments
values(default,'"+department_name+"'"+location_id+")"
;
Statement state = conn.createStatement();
3.4释放资源
if(state != null){
try {
state.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
4 通过 Statement 对象修改表中的数据
4.1代码
//更新 departments 表中的 department_id 为 6 的数据,将
部门名称修改为教学部,location_id 修改为 6
public void updateDempartments(String
department_name,int location_id,int department_id){
Connection conn = null;
Statement state = null;
try{
Class.forName("com.mysql.jdbc.Driver");
conn
=DriverManager.getConnection("jdbc:mysql://localhost:
3306/bjsxt?useUnicode=true&characterEncoding=utf-8",
"root", "root");
state = conn.createStatement();
String sql = "update departments d set
d.department_name = '"+department_name+"',d.location_id
= "+location_id+" where d.department_id
="+department_id;
int flag = state.executeUpdate(sql);
System.out.println(flag);
}catch(Exception e){
e.printStackTrace();
}finally{
if(state != null){
try {
state.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
5 封装 JDBC 工具类
5.1普通版
5.1.1工具类代码
/**
* jdbc 工具类
* @author Administrator
*
*/
public class JdbcUtil {
private static String driver =
"com.mysql.jdbc.Driver";
private static String
jdbcUrl="jdbc:mysql://localhost:3306/bjsxt?useUnicode
=true&characterEncoding=utf-8";
private static String username ="root";
private static String userpassword="root";
static{
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取 Connection 对象
public static Connection getConnection(){
Connection conn = null;
try {
conn = DriverManager.getConnection(jdbcUrl,
username, userpassword);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
//关闭 Statement
public static void closeStatement(Statement
state){
try {
if(state != null){
state.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//关闭 Connection
public static void closeConnection(Connection
conn){
try {
if(conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//關閉資源
public static void closeResource(Statement
state,Connection conn){
closeStatement(state);
closeConnection(conn);
}
}
5.2升级版
5.2.1工模具类代码
/**
* jdbc 工具类
* @author Administrator
*
*/
public class JdbcUtil {
private static String driver;
private static String jdbcUrl;
private static String username;
private static String userpassword;
static{
//读取 Properties 文件
ResourceBundle bundle =
ResourceBundle.getBundle("jdbc");
driver = bundle.getString("driver");
jdbcUrl= bundle.getString("jdbcUrl");
username = bundle.getString("username");
userpassword =
bundle.getString("userpassword");
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取 Connection 对象
public static Connection getConnection(){
Connection conn = null;
try {
conn = DriverManager.getConnection(jdbcUrl,
username, userpassword);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
//关闭 Statement
public static void closeStatement(Statement
state){
try {
if(state != null){
state.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//关闭 Connection
public static void closeConnection(Connection
conn){
try {
if(conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//關閉資源
public static void closeResource(Statement
state,Connection conn){
closeStatement(state);
closeConnection(conn);
}
}
6 通过 Statement 对象查询数据
6.1代码
//查询 Departmetns 表中部门 ID 为 6 的部门信息
public void selectDepartmentsById(int
departmentId){
Connection conn = null;
Statement state = null;
ResultSet rs = null;
try{
conn= JdbcUtil.getConnection();
state = conn.createStatement();
String sql = "select * from departments d where
d.department_id = "+departmentId;
//执行查询返回结果
rs=state.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getInt("department_id")+"
"+rs.getString("department_name")+" "+rs.getInt(3));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(state, conn,rs);
}
}
7 ResultSet 讲解
注意 ResultSet 中封装的并不是我们查询到的所有的结果集,而是返回了查询到的结果
集的数据库游标。通过 ResultSet 中的 next()方法操作游标的位置获取结果集。
8 通过 ResultSet 实现逻辑分页
8.1代码
//查询 departments 表中的所有的数据,并且通过 ResultSet 实现逻辑分
页
public void selectDeptPage(int currentPage,int pageRows){
Connection conn = null;
Statement state = null;
ResultSet rs = null;
try{
conn = JdbcUtil.getConnection();
state = conn.createStatement();
String sql = "select * from departments";
rs = state.executeQuery(sql);
//开始位置与结束位置
int begin = (currentPage -1)*pageRows;
int end = currentPage * pageRows;
//当前位置的计数器
int currentNum = 0;
while(rs.next()){
//什么情况下获取结果集中的数据
if(currentNum >= begin && currentNum < end){
System.out.println(rs.getInt("department_id")+"
"+rs.getString("department_name"));
//结束操作 ResultSet 的边界条件
if(currentNum == end -1){
break;
}
}
currentNum++;
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(state, conn, rs);
}
}
9 SQL 注入问题
9.1什么是 SQL 注入
所谓 SQL 注入,就是通过把含有 SQL 语句片段的参数插入到需要执行的 SQL 语句中,
最终达到欺骗数据库服务器执行恶意操作的 SQL 命令。
9.2SQL 注入案例
//sql 注入
public void sqlInject(String departmentName,int
locationId){
Connection conn = null;
Statement state = null;
ResultSet rs = null;
try{
conn = JdbcUtil.getConnection();
state = conn.createStatement();
String sql = "select * from departments where
department_name ='"+departmentName+"' and location_id =
"+locationId;
System.out.println(sql);
rs = state.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getInt("department_id")+"
"+rs.getString("department_name")+"
"+rs.getInt("location_id"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(state, conn, rs);
}
}
10 PreparedStatement 对象的使用(重点)
10.1PreparedStatement 特点:
• PreparedStatement 接口继承 Statement 接口
• PreparedStatement 效率高于 Statement
• PreparedStatement 支持动态绑定参数
• PreparedStatement 具备 SQL 语句预编译能力
• 使用 PreparedStatement 可防止出现 SQL 注入问题
10.2通过 PreparedStatement 对象向表中插入数据
10.2.1 代码
//向 Departments 表中插入一条数据
public void insertDempartments(String departmentName,int
locationId){
Connection conn = null;
PreparedStatement ps = null;
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("insert into departments
values(default,?,?)");
ps.setString(1, departmentName);
ps.setInt(2, locationId);
ps.execute();
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
}
11 PreparedStatement 的预编译能力
11.1什么是预编译
11.1.1 SQL 语句的执行步骤
• 语法和语义解析
• 优化 sql 语句,制定执行计划
• 执行并返回结果
但是很多情况,我们的一条 sql 语句可能会反复执行,或者每次执行的时候只有个别的
值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。
如果每次都需要经过上面的词法语义解析、语句优化、制定执行计划等,则效率就明显不行
了。
所谓预编译语句就是将这类语句中的值用占位符替代,可以视为将 sql 语句模板化或者
说参数化
预编译语句的优势在于:一次编译、多次运行,省去了解析优化等过程;此外预编译语
句能防止 sql 注入
11.1.2 解析过程
11.1.2.1 硬解析
在不开启缓存执行计划的情况下,每次 SQL 的处理都要经过:语法和语义的解析,优
化器处理 SQL,生成执行计划。整个过程我们称之为硬解析。
11.1.2.2 软解析
如果开启了缓存执行计划,数据库在处理 sql 时会先查询缓存中是否含有与当前 SQL
语句相同的执行计划,如果有则直接执行该计划。
11.2预编译方式
开始数据库的日志
show VARIABLES like '%general_log%'
set GLOBAL general_log = on
set GLOBAL log_output='table'
11.2.1 依赖数据库驱动完成预编译
如果我们没有开启数据库服务端编译,那么默认的是使用数据库驱动完成 SQL 的预编
译处理。
11.2.2 依赖数据库服务器完成预编译
我们可以通过修改连接数据库的 URL 信息,添加 useServerPrepStmts=true 信息开启服
务端预编译。
12 通过 PreparedStatement 对象完成数据的更新
12.1代码
//更新数据
public void updateDepartment(int departmentId,String
departmentName,int localhostId){
Connection conn= null;
PreparedStatement ps = null;
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("update departments set
department_name = ?,location_id = ? where department_id = ?");
ps.setString(1, departmentName);
ps.setInt(2, localhostId);
ps.setInt(3, departmentId);
ps.execute();
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
}
13 通过 PreparedStatement 对象完成数据的查询
13.1查询返回单条结果集
13.1.1 代码
//完成数据查询
public Departments selectDepartmentsById(int
departmentId){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
Departments dept = null;
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("select * from
departments where department_id = ?");
ps.setInt(1, departmentId);
rs = ps.executeQuery();
while(rs.next()){
dept=new Departments();
dept.setDepartmentId(rs.getInt("department_id"));
dept.setDepartmentName(rs.getString("department_name"));
dept.setLocationId(rs.getInt("location_id"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, rs);
}
return dept;
}
13.2查询返回多条结果集
13.2.1 代码
//查询部门表中的部门名称,找到那些包含“人力”的部门信息
public List<Departments>
selectDepartmentByLikeName(String departmentName){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<Departments> list = new ArrayList<>();
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("select * from
departments where department_name like ?");
ps.setString(1, "%"+departmentName+"%");
rs = ps.executeQuery();
while(rs.next()){
Departments dept = new Departments();
dept.setDepartmentId(rs.getInt("department_id"));
dept.setDepartmentName(rs.getString("department_name"));
dept.setLocationId(rs.getInt("location_id"));
list.add(dept);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, rs);
}
return list;
}
14 PreparedStatement 批处理操作
批处理:在与数据库的一次连接中,批量的执行条 SQL 语句。
14.1代码
//批量添加
public void addBatch(List<Departments> list){
Connection conn = null;
PreparedStatement ps = null;
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("insert into departments
values(default,?,?)");
for(int i=0;i<list.size();i++){
ps.setString(1,
list.get(i).getDepartmentName());
ps.setInt(2, list.get(i).getLocationId());
//添加批处理
ps.addBatch();
}
int[] arr =ps.executeBatch();
for(int i=0;i<arr.length;i++){
System.out.println(i);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
}
15 JDBC 中的事务处理
在 JDBC 操作中数据库事务默认为自动提交。如果事务需要修改为手动提交,那么我们
需 要 使 用 Connection 对 象 中 的 setAutoCommit 方 法 来 关 闭 事 务 自 动 提 交 。 然 后 通 过
Connection 对象中的 commit 方法与 rollback 方法进行事务的提交与回滚。
15.1代码
//事务处理
public void deleteDempartments(String depratmentName){
Connection conn = null;
PreparedStatement ps = null;
try{
conn = JdbcUtil.getConnection();
//关闭事务的自动提交
conn.setAutoCommit(false);
ps = conn.prepareStatement("delete from departments
where department_name like ?");
ps.setString(1, "%"+depratmentName+"%");
ps.executeUpdate();
ps = conn.prepareStatement("insert into departments
values(default,'开发部',2)");
ps.executeUpdate();
String str = null;
str.length();
conn.commit();
}catch(Exception e){
e.printStackTrace();
JdbcUtil.rollback(conn);
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
}
四、 JDBC 进阶
1 动态查询
动态查询:根据用户给定的条件来决定执行什么样的查询。
1.1代码
//动态查询
public List<Departments> selectDeptByProperty(Departments
departments){
Connection conn =null;
PreparedStatement ps =null;
ResultSet rs = null;
List<Departments> list = new ArrayList<>();
try{
conn =JdbcUtil.getConnection();
String sql = genSQL(departments);
System.out.println(sql);
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while(rs.next()){
Departments dept = new Departments();
dept.setDepartmentId(rs.getInt("department_id"));
dept.setDepartmentName(rs.getString("department_name"));
dept.setLocationId(rs.getInt("location_id"));
list.add(dept);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, rs);
}
return list;
}
//拼接需要执行的 sql 语句
private String genSQL(Departments dept){
StringBuffer sb = new StringBuffer("select * from
departments where 1=1 ");
if(dept.getDepartmentId() > 0){
sb.append(" and department_id =
").append(dept.getDepartmentId());
}
if(dept.getDepartmentName() != null &&
dept.getDepartmentName().length() > 0){
sb.append(" and department_name =
'").append(dept.getDepartmentName()).append("'");
}
if(dept.getLocationId() > 0){
sb.append(" and location_id =
").append(dept.getLocationId());
}
return sb.toString();
}
2 应用程序分层
2.1什么是应用程序分层
应用程序通过创建不同的包来实现项目的分层,将项目中的代码根据功能做具体划分,
并存放在不同的包下。
2.2分层优点
1、分层结构将应用系统划分为若干层,每一层只解决问题的一部分,通过各层的协作
提供整体解决方案。大的问题被分解为一系列相对独立的子问题,局部化在每一层中,这样
就有效的降低了单个问题的规模和复杂度,实现了复杂系统的第一步也是最为关键的一步分
解。
2、分层结构具有良好的可扩展性,为应用系统的演化增长提供了一个灵活的支持,具
有良好的可扩展性。增加新的功能时,无须对现有的代码做修改,业务逻辑可以得到最大限
度的重用。
3、分层架构易于维护。在对系统进行分解后,不同的功能被封装在不同的层中,层与
层之间的耦合显著降低。因此在修改某个层的代码时,只要不涉及层与层之间的接口,就不
会对其他层造成严重影响。
2.3三层结构
三层结构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑层
(Business Logic Layer)、数据访问层(Data access layer)。区分层次的目的即为了“高内
聚低耦合”的思想。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。
2.4项目分层
![](/assets/blank.gif)
2.5在分层结构中实现业务
2.5.1持久层
2.5.1.1 接口
接口
public interface DepartmentsDao {
public List<Departments> selectDeptByName(String
deptName);
public void insertDept(Departments dept);
}
接口实现类
public class DepartmentsDaoImpl implements DepartmentsDao {
@Override
public List<Departments> selectDeptByName(String deptName)
{
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<Departments> list = new ArrayList<>();
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("select * from
departments where department_name = ?");
ps.setString(1, deptName);
rs = ps.executeQuery();
while(rs.next()){
Departments d = new Departments();
d.setDepartmentId(rs.getInt("department_id"));
d.setDepartmentName(rs.getString("department_name"));
d.setLocationId(rs.getInt("location_id"));
list.add(d);
}
}catch(Exception e){
e.printStackTrace();
JdbcUtil.rollback(conn);
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
return list;
}
@Override
public void insertDept(Departments dept) {
Connection conn = null;
PreparedStatement ps = null;
try{
conn = JdbcUtil.getConnection();
conn.setAutoCommit(false);
ps = conn.prepareStatement("insert into departments
values(default,?,?)");
ps.setString(1, dept.getDepartmentName());
ps.setInt(2, dept.getLocationId());
ps.execute();
conn.commit();
}catch(Exception e){
e.printStackTrace();
JdbcUtil.rollback(conn);
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
}
}
2.5.2业务层
2.5.2.1 代码
接口
public interface DepartmentsService {
public void addDepartments(Departments dept);
}
接口实现类
public class DepartmensServiceImpl implements
DepartmentsService {
@Override
public void addDepartments(Departments dept) {
DepartmentsDao deptDao = new DepartmentsDaoImpl();
deptDao.insertDept(dept);
}
}
2.5.3测试层
2.5.3.1 代码
public class Test {
public static void main(String[] args) {
Departments dept = new Departments();
dept.setDepartmentName("研发部");
dept.setLocationId(30);
DepartmentsService ds = new DepartmensServiceImpl();
ds.addDepartments(dept);
}
}
3 封装通用的 BaseDao
3.1封装更新操作
3.1.1代码
接口
public interface BaseDao {
public int executeUpdate(String sql,Object[] param);
}
接口实现类
public class BaseDaoImpl implements BaseDao {
/**
* 封装通用的 DML 操作
*/
@Override
public int executeUpdate(String sql, Object[] param) {
Connection conn =null;
PreparedStatement ps = null;
int rows = 0;
try{
conn = JdbcUtil.getConnection();
conn.setAutoCommit(false);
ps = conn.prepareStatement(sql);
//得到参数的个数
ParameterMetaData pmd = ps.getParameterMetaData();
//绑定参数
for(int i=0;i<pmd.getParameterCount();i++){
ps.setObject(i+1, param[i]);
}
rows = ps.executeUpdate();
conn.commit();
}catch(Exception e){
e.printStackTrace();
JdbcUtil.rollback(conn);
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
return rows;
}
}
Dao 层代码 接口
public interface DepartmentsDao extends BaseDao {
public List<Departments> selectDeptByName(String
deptName);
public void insertDept(Departments dept);
public int updateDept(Departments dept);
public int deleteDeptById(int departmentId);
}
Dao 层接口实现类
public class DepartmentsDaoImpl extends BaseDaoImpl implements
DepartmentsDao {
@Override
public List<Departments> selectDeptByName(String deptName)
{
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<Departments> list = new ArrayList<>();
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement("select * from
departments where department_name = ?");
ps.setString(1, deptName);
rs = ps.executeQuery();
while(rs.next()){
Departments d = new Departments();
d.setDepartmentId(rs.getInt("department_id"));
d.setDepartmentName(rs.getString("department_name"));
d.setLocationId(rs.getInt("location_id"));
list.add(d);
}
}catch(Exception e){
e.printStackTrace();
JdbcUtil.rollback(conn);
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
return list;
}
@Override
public void insertDept(Departments dept) {
Connection conn = null;
PreparedStatement ps = null;
try{
conn = JdbcUtil.getConnection();
conn.setAutoCommit(false);
ps = conn.prepareStatement("insert into departments
values(default,?,?)");
ps.setString(1, dept.getDepartmentName());
ps.setInt(2, dept.getLocationId());
ps.execute();
conn.commit();
}catch(Exception e){
e.printStackTrace();
JdbcUtil.rollback(conn);
}finally{
JdbcUtil.closeResource(ps, conn, null);
}
}
//更新部门信息
@Override
public int updateDept(Departments dept) {
String sql = "update departments set department_name
= ? ,location_id = ? where department_id = ?";
Object[] param = new
Object[]{dept.getDepartmentName(),dept.getLocationId(),dept.ge
tDepartmentId()};
return this.executeUpdate(sql, param);
}
//删除部门信息
@Override
public int deleteDeptById(int departmentId) {
String sql = "delete from departments where department_id
= ?";
Object[] param = new Object[]{departmentId};
return this.executeUpdate(sql, param);
}
}
3.2封装查询操作
3.2.1代码
BaseDao 接口
public interface BaseDao {
public int executeUpdate(String sql,Object[] param);
public <T> List<T> find(String sql,Object[] param,Class<T>
clazz);
}
BaseDaoImpl 接口实现类
@Override
public <T> List<T> find(String sql, Object[] param, Class<T>
clazz) {
Connection conn =null;
PreparedStatement ps =null;
ResultSet rs = null;
List<T> list = new ArrayList<>();
try{
conn = JdbcUtil.getConnection();
ps = conn.prepareStatement(sql);
//得到参数的个数
ParameterMetaData pmd = ps.getParameterMetaData();
//绑定参数
for(int i=0;i<pmd.getParameterCount();i++){
ps.setObject(i+1, param[i]);
}
//处理结果集
rs = ps.executeQuery();
//获取结果集的信息
ResultSetMetaData rsmd = rs.getMetaData();
while(rs.next()){
//完成 ORM 处理:通过 jdk 的反射
T bean =clazz.newInstance();//Departmens d = new
Department();
for(int i=0;i<rsmd.getColumnCount();i++){
//得到列名
String columnName = rsmd.getColumnName(i+1);
//获取列的值
Object value = rs.getObject(columnName);
//通过 BeanUtil 工具类将值当如到对象中
BeanUtils.setProperty(bean, columnName,
value);
}
list.add(bean);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.closeResource(ps, conn, rs);
}
return list;
}
DepartmentDao 接口
public interface DepartmentsDao extends BaseDao {
public List<Departments> selectDeptByName(String
deptName);
public void insertDept(Departments dept);
public int updateDept(Departments dept);
public int deleteDeptById(int departmentId);
public List<Dept> selectDeptByLikeName(String deptName);
}
DepartmentDaoImpl 接口实现类
@Override
public List<Dept> selectDeptByLikeName(String deptName) {
String sql ="select * from departments where
department_name like ?";
Object[] param = new Object[]{"%"+deptName+"%"};
return this.find(sql, param, Dept.class);
}
4 JDBC 驱动加载原理
4.1创建对象的方式
![](/assets/blank.gif)
4.2创建对象时三个重要的步骤
•通过类加载器加载 class
•初始化所有静态部分
•为新生对象分配内存
4.3MySQL 驱动类的实例化过程
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
java技术_JAVA-JDBC技术相关推荐
- JAVA数据库编程(JDBC技术)-入门笔记
本菜鸟才介入Java,我现在不急着去看那些基本的语法或者一些Java里面的版本的特征或者是一些晋级的知识,因为有一点.Net的OOP编程思想,所以对于Java的这些语法以及什么的在用到的时候在去发现学 ...
- java反射技术_java反射技术,逆向开发必备技能
相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java反射影响性能,所以被运行时注解APT替代了, ...
- java 压缩技术_Java压缩技术(三) ZIP解压缩——Java原生实现
JavaEye的朋友跟我说:"你一口气把ZIP压缩和解压缩都写到一个帖子里,我看起来很累,不如分开好阅读".ok,面向读者需求,我做调整,这里单说ZIP解压缩! 相关链接: Jav ...
- gzip java 压缩_Java压缩技术(四) GZIP——Java原生实现
熟悉linux的朋友可能都用过文件压缩命令,譬如最为简单的gzip命令. 相关链接: Java压缩技术(一) ZLib Java压缩技术(二) ZIP压缩--Java原生实现 Java压缩技术(三) ...
- java 沙箱_Java沙箱技术
自从Java技术出现以来,有关Java平台的安全性及由Java技术发展所引发的新的安全性问题,引起了越来越多的关注.目前,Java已经大量应用在各个领域,研究Java的安全 性对于更好地使用Java具 ...
- java数据库技术_JAVA数据库技术
2016-11-03 JDBC(java Database connection,)是一种用于执行SQL语句的API,他是有一些java语言写的类和界面组成,他提供了了标准的应用程序接口,是开发人员可 ...
- java缓存技术_java缓存技术
最近在做java缓存,了解了一下. 以下仅是对map对方式讨论.没有对点阵图阵讨论. 作缓存要做以下2点: 1:清理及更新缓存时机的处理: . 虚拟机内存不足,清理缓存 .. 缓存时间超时,或访问次数 ...
- java 日志技术_java 日志技术汇总(log4j , Commons-logging,.....)
前言 在系列一 中, 有一个问题一直没有解决,就是部署到weblogic 中应用程序如何通过log4j写日志到文件中? 这里仅仅使用log4j, 而不使用 commons-logging, 关于log ...
- 常用java技术_java常用技术
struts2基本包commons-logging-*.jar Apache旗下commons项目的log日志包 freemarker-*.jar 一种前台页面模板,应用比较广泛 ognl-*.jar ...
- java语言体系的技术简介之JSP、Servlet、JDBC、JavaBean(Application)
前言 Java语言 Java语言体系比较庞大,包括多个模块.从WEB项目应用角度讲有JSP.Servlet.JDBC.EJB四部分技术.其中还有其他的9个技术规范(JNDI,) 正文 (1).Java ...
最新文章
- 2022-2028年中国企业核心路由交换机行业市场前瞻与投资分析报告
- 联手IBM布局云计算,王健林如何再造一个新万达?
- 陶哲轩实分析 定理 8.2.2 (无限和的富比尼定理) 证明
- HighNewTech:20190824上海人工智能大会(2019SHAI)暨第二届图像视频处理与人工智能国际会议参会感悟记录
- boost::hana模块在无限可迭代对象上测试 hana::index_if
- IOS之截取特定字符串
- 散列算法,Remal使用散列算法
- Spring boot actuator端点启用和暴露
- 老男孩和门户网站学生聊天整理
- 设计灵感|移动应用的可视化数据图表都是怎么设计的?
- Arduino抢答器
- [转载] Python中numpy.clip();numpy.fabs()的用法;以及math.pow()的说明
- oracle 报错06502,求助!!ORA-06502错误
- Python被誉为神奇的“胶水语言”,到底神奇在哪?
- eclipse 使用问题
- 使用git第一次成功,记录
- cholesky分解java代码_cholesky分解
- Windows下设置Tomcat自启动
- 出色的社区网站_《最后的我们》中出色的制作系统
- seacms海洋cms漏洞
热门文章
- 008_Redis的ZSet数据类型
- 087_html5表单元素
- 017_html图像
- xml签名和普通数字签名
- 场效应与三极管 电路标识符_看懂这6个提示,轻松搞定恒流源电源电路设计!...
- day06 : 01 Oracle 体系结构概念,内存结构,内存结构(服务器进程和用户进程)
- vncview 多屏_OpenStack中VNC协议实现多屏共享(多屏不踢访问)
- 牛客java面试题总结版(二)
- html复选框对齐文字,input【type=checkbox】标签与字体对齐
- linux以非root身份运行,以非root用户身份在linux中运行mono-service