Java Web]JDBC综合实践"/>
[Java Web]JDBC综合实践
目录
1、需求
2、工程目录
2.1、工程目录说明
2.2、src文件
3、准备工作
3.1、⭐开启MySQL
3.2、数据初始化
3.3、导入驱动包
3.4、驱动包介绍
3.5、回顾JDBC代码步骤
3.5.1、原先步骤
3.5.2、🔺🔺改进步骤
4、代码实现
4.1、druid.properties
4.2、com.sql
4.2.1、information
4.2.2、sqlInitialForMySQL
4.3、com.operation
4.3.1、encapsulationTool
4.3.2、🔺operations完整源码
4.3.3、⭐selectAll()
4.3.4、insert()
4.3.5、update()
4.3.6、delete()
5、注意事项
5.1、空指针
5.2、🔺🔺包名格式异常
5.3、junit异常
5.4、图解IDEA中配置MySQL
5.5、SQL语句警告
本文介绍JDBC的实践案例,是对JDBC的综合操作讲解(文中附有详细代码)
了解并熟悉JDBC,请看我的另一篇文章:
JDBC->Java操作MySQL数据库_︶ㄣ释然的博客-CSDN博客JDBC->超一万字文章带你详细了解Java操作MySQL数据库的各种步骤,后续会更新一篇关于JDBC综合实践案例说明文章,敬请期待。
1、需求
需求:完成商品品牌数据的增删改查操作(增删改查)
①查询:查询所有数据
②添加:添加品牌
③修改:根据id修改
④删除:根据id删除
2、工程目录
最终完成后的工程目录如下:
2.1、工程目录说明
该工程下的JDBC模块存放此次实践案例的相关文件。
模块下创建了两个文件:lib和src。
lib放的是需要的驱动jar包
src放的是主要实现代码和Druid框架的配置文件druid.properties。
2.2、src文件
src下有两个二级包,分别为com.operation和com.sql。
①operation包下有两个类:分别是encapsulationTool封装工具类和operations操作类。
encapsulationTool的内容是把表单信息添加进实体类,后续有详细说明
operations是本次的主体,里面包含了所有本次需求的实现代码
②sql包下有两个类:分别是information表单信息类和sqlInitialForMySQL初始化类
information是MySQL中的commodity数据库中的information表的实体类
sqlInitialForMySQL是将JDBC的八个步骤中一些相同的步骤提取出来单独成类来实现,
以达到简化代码量的效果
3、准备工作
3.1、⭐开启MySQL
本次的实践案例连接的是本地的MySQL数据库,所以要记得开启本地的MySQL服务。
如果不开启服务,所有的操作一律报错。
操作:
win+R,cmd,按住Ctrl+Shift+Enter,以管理员模式打开终端。
命令->开启:net start mysql
关闭:net stop mysql
3.2、数据初始化
接下来要先创建一个commodity商品类型的数据库,在该数据库中创建一个information表单来存储信息,在information表单中创建具体的表存储信息。如下:
information表中依次存放六种信息:
id:唯一标识,使用主键约束(primary key),设置自动增长(auto_increment);
brand:品牌名称
company:公司名称
sort:排序字段 (注:在本次实践案例中暂时没用上)
description:描述信息
status:状态信息,只有0和1两种,分别代表禁用、启用。 (注:在本次实践案例中暂时没用上)
3.3、导入驱动包
本次案例实践的驱动包一共有四个:
druid-1.1.12.jar
hamcrest-core-1.3.jar
junit-4.13.1.jar
mysql-connector-java-5.1.48.jar
将上述四个驱动包导入到lib文件夹,并添加到项目依赖中。
3.4、驱动包介绍
Druid和MySQL驱动包的解释,详细查看我的另一篇文章中的 "5、数据库连接池" :
JDBC->Java操作MySQL数据库_︶ㄣ释然的博客-CSDN博客JDBC->超一万字文章带你详细了解Java操作MySQL数据库的各种步骤,后续会更新一篇关于JDBC综合实践案例说明文章,敬请期待。
junit驱动主要是用来编写单元测试类,代替实践案例中所需要的main方法。
如果不导入hamcrest驱动,使用junit的测试注解会出现问题:
3.5、回顾JDBC代码步骤
3.5.1、原先步骤
3.5.2、🔺🔺改进步骤
说明:
在原来的JDBC八个步骤中,第一步导入jar包的操作,在一开始已经完成了;
第二部注册驱动,在MySQL 5开始的驱动包中不需要手动注册,会自动扫描驱动
第三步获取连接,原来的获取方式有造成资源浪费的明显缺点,所以由连接池代替
第五步获取执行对象,存在SQL注入漏洞,所以由获取预编译执行对象代替
所以,改进完成之后的JDBC操作为十个步骤:
- 导入相关jar包
- 定义Druid的druid.properties配置文件
- 加载配置文件
- 获取连接池对象
- 获取连接
- 定义SQL
- 获取预编译SQL执行对象
- 执行SQL
- 处理结果
- 释放资源
4、代码实现
4.1、druid.properties
关于这个配置文件的书写,详细查看我另一篇文章中的 "5.3.2、定义配置文件":
JDBC->Java操作MySQL数据库_︶ㄣ释然的博客-CSDN博客JDBC->超一万字文章带你详细了解Java操作MySQL数据库的各种步骤,后续会更新一篇关于JDBC综合实践案例说明文章,敬请期待。
4.2、com.sql
4.2.1、information
编写src下的com.sql.information实体类,该实体类为一个标准JavaBeen格式。
总共六个参数,分别对应数据库中information表中六列数据。
package com.sql;public class information {private int id;private String brand;private String company;private int sort;private String description;private int status;public information() { }public information(int id, String brand, String company, int sort, String description, int status) {this.id = id;this.brand = brand;thispany = company;this.sort = sort;this.description = description;this.status = status;}@Overridepublic String toString() {return "information{" +"id=" + id +", brand='" + brand + '\'' +", company='" + company + '\'' +", sort=" + sort +", description='" + description + '\'' +", status=" + status +'}';}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public String getCompany() {return company;}public void setCompany(String company) {thispany = company;}public int getSort() {return sort;}public void setSort(int sort) {this.sort = sort;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public int getStatus() {return status;}public void setStatus(int status) {this.status = status;}
}
4.2.2、sqlInitialForMySQL
sqlInitialForMySQL即是在本文目录中的2.2部分提到过的,将JDBC的实现步骤中一些相同的步骤提取出来单独成类来实现,以达到简化代码量的效果。
sqlInitialForMySQL类实现的是,在本文目录中3.5.2部分提到的"改进后的JDBC步骤"中的第三步到第五步-->加载配置文件、获取连接池对象、获取连接:
package com.sql;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;public class sqlInitialForMySQL {public Connection InitialOfOperation() throws Exception {//注册驱动//MySQL 5之后的驱动包,可以省略注册驱动的步骤,//自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类//获取Connection,加载配置文件(MySQL的url,username,password均在其中)Properties properties = new Properties();properties.load(new FileInputStream("src/druid.properties"));//获取连接池对象DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);//获取数据库连接Connection connection;connection = dataSource.getConnection();return connection;}}
最终这个类返回的是Connection对象,方便接着调用或者作参传入。
4.3、com.operation
4.3.1、encapsulationTool
此工具类主要作用是将传进来的六种参数封装成一个information实例对象,方便添加进list集合,使用于selectAll()方法中。
package com.operation;import com.sql.information;public class encapsulationTool {public information tool(information ifm, int id,String brand,String company, int sort, String description,int status){ifm.setId(id);ifm.setBrand(brand);ifm.setCompany(company);ifm.setSort(sort);ifm.setDescription(description);ifm.setStatus(status);return ifm;}
}
4.3.2、🔺operations完整源码
operations操作类中是实现了本次需求的增删改查操作。
在这个类里边使用到了com.sql.sqlInitialForMySQL和com.sql.information两个自己编写的类。
下面是operations的全部实现代码。
package com.operation;import com.sql.sqlInitialForMySQL;
import com.sql.information;import org.junit.Test;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;/*** JDBC各种操作*/
public class operations {public static Connection connection;/*** 重点*/public encapsulationTool TOOL = new encapsulationTool();static {//导入写好的类try {connection = new sqlInitialForMySQL().InitialOfOperation();} catch (Exception e) {e.printStackTrace();}}/*** 查询所有* 1. SQL:select * from information;* 2. 参数:不需要* 3. 结果:List<Brand>*/@Testpublic void selectAll() throws Exception {//定义SQLString sql = "select * from information";//获取preparedStatementPreparedStatement preparedStatement = connection.prepareStatement(sql);//执行SQLResultSet resultSet = preparedStatement.executeQuery();//处理结果information information = new information();List<information> list = new ArrayList<>();while (resultSet.next()) {int id = resultSet.getInt("id");String brand = resultSet.getString("brand");String company = resultSet.getString("company");int sort = resultSet.getInt("sort");String description = resultSet.getString("description");int status = resultSet.getInt("status");//封装information对象information = TOOL.tool(information, id, brand, company, sort, description, status);list.add(information);System.out.println(list);}resultSet.close();preparedStatement.close();connection.close();}/*** 添加数据* 1. SQL:insert into information(brand_name,company_name,* ordered, description, status) values(?,?,?,?,?);* 2. 参数:需要,除了id之外的所有参数信息* 3. 结果:boolean*/@Testpublic void insert() throws Exception {String brand = "香飘飘";String company = "香飘飘公司";int sort = 1;String description = "香飘飘是香飘飘食品股份有限公司旗下杯装奶茶品牌,成立于2005年";int status = 1;String sql = "insert into information(brand,company,sort,description,status) " +"values (?,?,?,?,?)";PreparedStatement preparedStatement = connection.prepareStatement(sql);try (preparedStatement) {preparedStatement.setString(1, brand);preparedStatement.setString(2, company);preparedStatement.setInt(3, sort);preparedStatement.setString(4, description);preparedStatement.setInt(5, status);connection.setAutoCommit(false);preparedStatement.executeUpdate();connectionmit();selectAll();} catch (Exception e) {connection.rollback();e.printStackTrace();} finally {connection.close();}}/*** 修改数据* 1. SQL:update information set* brand_name = ?,company_name= ?,* ordered = ?,description = ?,status = ?* where id = ?* 2. 参数:需要,所有数据* 3. 结果:boolean*/@Testpublic void update() throws Exception {int id = 4;String brand = "香飘飘";String company = "香飘飘";//作出修改int sort = 1000;//做出修改String description = "绕地球三圈";int status = 1;String sql = "update information set brand=?,company=?,sort=?,description=?,status=?" +" where id=? ";PreparedStatement preparedStatement = connection.prepareStatement(sql);try (preparedStatement) {preparedStatement.setString(1, brand);preparedStatement.setString(2, company);preparedStatement.setInt(3, sort);preparedStatement.setString(4, description);preparedStatement.setInt(5, status);preparedStatement.setInt(6, id);connection.setAutoCommit(false);preparedStatement.executeUpdate();connectionmit();selectAll();} catch (Exception e) {connection.rollback();e.printStackTrace();} finally {connection.close();}}/*** 删除数据* 1. SQL:delete from information where id = ?* 2. 参数:需要,id* 3. 结果:boolean*/@Testpublic void delete() throws Exception {//删除第四条数据"香飘飘"int id = 4;String sql = "delete from information where id = ?";PreparedStatement preparedStatement = connection.prepareStatement(sql);try (preparedStatement) {preparedStatement.setInt(1, id);connection.setAutoCommit(false);preparedStatement.executeUpdate();connectionmit();selectAll();} catch (Exception e) {connection.rollback();e.printStackTrace();} finally {connection.close();}}
}
在operations中的各个方法,使用了事务管理机制。使用try-with-resource,自动释放资源,在try中设置事务管理,在catch中设置事务回滚,在finally中设置资源释放,避免出现死锁占用资源
在operations类中的开头部分,使用静态代码块加载connection连接,跟随本类一起加载,自始至终只有一个对象,节约了性能
4.3.3、⭐selectAll()
该方法是获取commodity数据库中information表中的信息。
/*** 查询所有* 1. SQL:select * from information;* 2. 参数:不需要* 3. 结果:List<Brand>*/
@Test
public void selectAll() throws Exception {//定义SQLString sql = "select * from information";//获取preparedStatementPreparedStatement preparedStatement = connection.prepareStatement(sql);//执行SQLResultSet resultSet = preparedStatement.executeQuery();//处理结果information information = new information();List<information> list = new ArrayList<>();while (resultSet.next()) {int id = resultSet.getInt("id");String brand = resultSet.getString("brand");String company = resultSet.getString("company");int sort = resultSet.getInt("sort");String description = resultSet.getString("description");int status = resultSet.getInt("status");//封装information对象information = TOOL.tool(information, id, brand, company, sort, description, status);list.add(information);System.out.println(list);}resultSet.close();preparedStatement.close();connection.close();
}
4.3.4、insert()
该方法是往commodity数据库中information表中添加信息,可批量添加也可依次添加。
/*** 添加数据* 1. SQL:insert into information(brand_name,company_name,* ordered, description, status) values(?,?,?,?,?);* 2. 参数:需要,除了id之外的所有参数信息* 3. 结果:boolean*/
@Test
public void insert() throws Exception {String brand = "香飘飘";String company = "香飘飘公司";int sort = 1;String description = "香飘飘是香飘飘食品股份有限公司旗下杯装奶茶品牌,成立于2005年";int status = 1;String sql = "insert into information(brand,company,sort,description,status) " +"values (?,?,?,?,?)";PreparedStatement preparedStatement = connection.prepareStatement(sql);try (preparedStatement) {preparedStatement.setString(1, brand);preparedStatement.setString(2, company);preparedStatement.setInt(3, sort);preparedStatement.setString(4, description);preparedStatement.setInt(5, status);connection.setAutoCommit(false);preparedStatement.executeUpdate();connectionmit();selectAll();} catch (Exception e) {connection.rollback();e.printStackTrace();} finally {connection.close();}
}
4.3.5、update()
该方法是修改commodity数据库中information表中的信息,以唯一标识id号为限制条件
/*** 修改数据* 1. SQL:update information set* brand_name = ?,company_name= ?,* ordered = ?,description = ?,status = ?* where id = ?* 2. 参数:需要,所有数据* 3. 结果:boolean*/
@Test
public void update() throws Exception {int id = 4;String brand = "香飘飘";String company = "香飘飘";//作出修改int sort = 1000;//做出修改String description = "绕地球三圈";int status = 1;String sql = "update information set brand=?,company=?,sort=?,description=?,status=?" +" where id=? ";PreparedStatement preparedStatement = connection.prepareStatement(sql);try (preparedStatement) {preparedStatement.setString(1, brand);preparedStatement.setString(2, company);preparedStatement.setInt(3, sort);preparedStatement.setString(4, description);preparedStatement.setInt(5, status);preparedStatement.setInt(6, id);connection.setAutoCommit(false);preparedStatement.executeUpdate();connectionmit();selectAll();} catch (Exception e) {connection.rollback();e.printStackTrace();} finally {connection.close();}
}
4.3.6、delete()
该方法是删除commodity数据库中information表中的信息,以唯一标识id号为限制条件
/*** 删除数据* 1. SQL:delete from information where id = ?* 2. 参数:需要,id* 3. 结果:boolean*/
@Test
public void delete() throws Exception {//删除第四条数据"香飘飘"int id = 4;String sql = "delete from information where id = ?";PreparedStatement preparedStatement = connection.prepareStatement(sql);try (preparedStatement) {preparedStatement.setInt(1, id);connection.setAutoCommit(false);preparedStatement.executeUpdate();connectionmit();selectAll();} catch (Exception e) {connection.rollback();e.printStackTrace();} finally {connection.close();}
}
5、注意事项
5.1、空指针
关于自己编写的封装工具类TOOL的使用,一开始写的是:
public encapsulationTool TOOL;
即只声明了对象,但是没有初始化,此时调用Tool.tool会报空指针异常,初始化Tool对象后则解决:
5.2、🔺🔺包名格式异常
在创建包的时候,出现了如下的现象:
即:com.operation.selectAll本来应该创建的是一个在二级包下的Java类selectAll,但是这个地方却出现了三级包名,并未创建Java类。
解决方法:
将此处的Compact Middle Packages取消勾选,即可解决。
5.3、junit异常
在使用junit时,要同时导入hamcrest驱动包,否则报异常。
5.4、图解IDEA中配置MySQL
IDEA左侧有一个database,点开可以看到:
点击"+":
如图选择MySQL。
配置MySQL:
设置驱动:
打开控制台:
可以开始编写SQL操作MySQL数据库:
5.5、SQL语句警告
可以看到,在代码中的SQL语句提示:未配置SQL方言
解决方式:
File->Settings->SQL Dialects->设置MySQL
更多推荐
[Java Web]JDBC综合实践
发布评论