赞
踩
(1)使用DOS命令窗口,输入“mysql -hlocalhost -u数据库用户名 -p数据库密码”命令连接数据库,编写SQL语句(SQL语句以分号;或者\g结尾),回车运行,查看操作结果(受影响行数或结果集)
(2)使用MySQL数据库自带的命令窗口,输入数据库密码连接数据库,编写SQL语句(SQL语句以分号;或者\g结尾),回车运行,查看操作结果(受影响行数或结果集)
(3)使用数据库连接软件(SQLyog)连接数据库,通过图形化界面或者在查询编辑器中编写SQL语句,运行SQL语句查看操作结果(受影响行数或结果集)
在实际开发中,当用户的数据发生变化时,不会也不可能通过客户端连接数据库去操作SQL语句,因为在实际开发中,数据的操作量很大,如果使用客户端操作数据库,无法保证SQL语句的正确性和执行效率。
(1)JDBC(Java DataBase Connectivity)Java连接数据库的规范(标准),可以使用Java语言连接数据库,从而对数据进行增删改查(CURD)操作。
Java中定义了访问数据库的接口,可以为多种关系型数据库提供统一的访问方式。由数据库厂商提供驱动实现类(Driver数据库驱动)。
mysql-connector-java-5.1.x 适用于5.x版本
mysql-connector-java-8.1.x 适用于8.x版本
JDBC是由多个接口和类进行功能实现的。
类型 | 权限定名 | 功能 |
---|---|---|
class | java.sql.DriverManager | 管理多个数据库驱动类,提供了获取数据库连接的方法 |
interface | java.sql.Connection | 代表一个数据库连接(当connection不为null时,表示已连接数据库) |
interface | java.sql.Statement | 发送SQL语句到数据库工具 |
interface | java.sql.PreparedStatement | 发送SQL语句到数据库工具 |
interface | java.sql.ResultSet | 保存SQL查询语句的结果数据(结果集) |
class | java.sql.SQLException | 处理数据库应用程序时所发生的异常 |
(1)在项目下创建lib文件夹,用于存放jar文件。
(2)将mysql驱动mysql-connector-java-5.1.x复制到项目的lib文件夹中。
(3)将选中lib文件中的jar文件配置到项目中。
创建数据库jdbcdatabase,专门用来存储学习jdbc要用的表
CREATE TABLE IF NOT EXISTS `student`(
`tid` INT(10) AUTO_INCREMENT COMMENT '学号',
`name` VARCHAR(20) NOT NULL COMMENT '姓名',
`age` INT(2) NOT NULL COMMENT '年龄',
`gender` VARCHAR(5) NOT NULL COMMENT '性别',
`phone` VARCHAR(11) UNIQUE NOT NULL COMMENT '手机号码',
`identitycard` VARCHAR(18) UNIQUE NOT NULL COMMENT '身份证号码',
`address` VARCHAR(20) NOT NULL COMMENT '住址',
PRIMARY KEY (`tid`)
);
INSERT INTO `student`(`tid`,`name`,`age`,`gender`,`phone`,`identitycard`,`address`) VALUES (1001,'张三',20,'男','13112345678','340825200212241936','安徽合肥蜀山区');
INSERT INTO `student`(`tid`,`name`,`age`,`gender`,`phone`,`identitycard`,`address`) VALUES (1002,'李红',18,'女','13111223344','340825200408151936','安徽合肥庐阳区');
使用Class.forName(“包含完整路径的驱动类”);//手动加载字节码文件到JVM中。
// 1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
通过DriverManager.getConnection(url,user,password)获取数据库连接对象
url:mysql数据库的路径
user:mysql数据库用户名
password:mysql数据库密码
// 2 、获取数据库连接对象
String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase";
String user = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url, user, password);
通过Connection对象获取Statement对象,用于发送SQL语句,实现对数据库进行访问。
//3、获取发送SQL语句的对象
Statement statement = connection.createStatement();
// 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误,这里sid是自增长,所以不需要写
String sql = "INSERT INTO `student`(`name`,`age`,`gender`,`phone`,`identitycard`,`address`)
VALUES ('王五',21,'男','13825869876','340825200109151928','安徽合肥包河区');";
// 5、执行SQL语句
//DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型)
//DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型)
int result = statement.executeUpdate(sql);
处理第5步返回的数据。对返回的受影响行数结果进行逻辑判断
// 6、处理结果,如果返回的受影响行数不为0,说明数据插入成功
if (result != 0) {
System.out.println("数据插入成功");
} else {
System.out.println("数据插入失败");
}
释放(关闭)所使用到的所有资源对象,遵循”先开的后关,后开的先关“原则。
// 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } //查询操作中多一个关闭resultSet if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } }
综合上述7个步骤,实现向student表中插入一条数据。
package com.cxyzxc.www.examples01; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现向数据库jdbcdatabase里student表中插入一条数据 * */ public class Jdbc01InsertStudent { public static void main(String[] args) { Connection connection = null; Statement statement = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误,这里sid是自增长,所以不需要写 String sql = "INSERT INTO `student`(`name`,`age`,`gender`,`phone`,`identitycard`,`address`) VALUES ('王五',21,'男','13825869876','340825200109151928','安徽合肥包河区');"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = statement.executeUpdate(sql); // 6、处理结果,如果返回的受影响行数不为0,说明数据插入成功 if (result != 0) { System.out.println("数据插入成功"); } else { System.out.println("数据插入失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
综合上述7个步骤,实现根据学号sid删除数据库表中一条数据。
package com.cxyzxc.www.examples01; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现删除数据库jdbcdatabase里student表中的一条数据 * */ public class Jdbc02DeleteStudent { public static void main(String[] args) { Connection connection = null; Statement statement = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "DELETE FROM `student` WHERE `tid` = 1003;"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = statement.executeUpdate(sql); // 6、处理结果,如果返回的受影响行数不为0,说明数据删除成功 if (result != 0) { System.out.println("数据删除成功"); } else { System.out.println("数据删除失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
综合上述7个步骤,实现根据学号sid修改数据库表中一条数据。
package com.cxyzxc.www.examples01; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现修改数据库jdbcdatabase里student表中的一条数据 * */ public class Jdbc03UpdateStudent { public static void main(String[] args) { Connection connection = null; Statement statement = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "UPDATE `student` SET `name`='李红',`age`=19,`gender`='女',`phone`='13111223344',`identitycard`='340825200308151936',`address`='安徽合肥高新区' WHERE `sid`=1002;"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = statement.executeUpdate(sql); // 6、处理结果,如果返回的受影响行数不为0,说明数据修改成功 if (result != 0) { System.out.println("数据修改成功"); } else { System.out.println("数据修改失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
JDBC中执行DQL查询语句后,使用ResultSet存放查询到的结果集数据。
ResultSet resultSet = statement.executeQuery(String sql);
// 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误
String sql = "SELECT * FROM `student` WHERE `sid`= 1002;";
// 5、执行SQL语句
// DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型)
// DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型)
ResultSet resultSet = statement.executeQuery(sql);
ResultSet以表(table)结构进行临时结果的存储,需要通过JDBC API将其中的数据依次获取。
数据行指针:初始位置在第一行数据前,每调用一次boolean next()方法ResultSet的指针向下移动一行,结果为true,表示当前行有数据。
// 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 //查询一条数据,根据记录中字段的索引获取字段数据 if (resultSet.next()) { //根据记录中字段的索引获取字段数据,字段索引从1开始 int sid = resultSet.getInt(1); String name = resultSet.getString(2); int age = resultSet.getInt(3); String gender = resultSet.getString(4); String phone = resultSet.getString(5); String identitycard = resultSet.getString(6); String address = resultSet.getString(7); System.out.println(sid + "-" + name + "-" + age + "-" + gender+ "-" + phone + "-" + identitycard + "-" + address); } //查询一条数据,根据记录中字段的名称获取字段数据 if (resultSet.next()) { //根据记录中字段的名称获取字段数据 int sid = resultSet.getInt("sid"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); String gender = resultSet.getString("gender"); String phone = resultSet.getString("phone"); String identitycard = resultSet.getString("identitycard"); String address = resultSet.getString("address"); System.out.println(sid + "-" + name + "-" + age + "-" + gender+ "-" + phone + "-" + identitycard + "-" + address); } //查询所有数据,根据记录中字段的索引获取字段数据 while (resultSet.next()) { //根据记录中字段的索引获取字段数据,字段索引从1开始 int sid = resultSet.getInt(1); String name = resultSet.getString(2); int age = resultSet.getInt(3); String gender = resultSet.getString(4); String phone = resultSet.getString(5); String identitycard = resultSet.getString(6); String address = resultSet.getString(7); System.out.println(sid + "-" + name + "-" + age + "-" + gender+ "-" + phone + "-" + identitycard + "-" + address); } //查询所有数据,根据记录中字段的名称获取字段数据 while (resultSet.next()) { //根据记录中字段的名称获取字段数据 int sid = resultSet.getInt("sid"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); String gender = resultSet.getString("gender"); String phone = resultSet.getString("phone"); String identitycard = resultSet.getString("identitycard"); String address = resultSet.getString("address"); System.out.println(sid + "-" + name + "-" + age + "-" + gender+ "-" + phone + "-" + identitycard + "-" + address); }
int getInt(int columnIndex) throws SQLException //获得当前行第N列的int值
int getInt(String columnLabel) throws SQLException //获得当前行名为cloumnLabel列的int值
int getDouble(int columnIndex) throws SQLException //获得当前行第N列的double值
int getDouble(String columnLabel) throws SQLException //获得当前行名为cloumnLabel列的double值
int getString(int columnIndex) throws SQLException //获得当前行第N列的String值
int getString(String columnLabel) throws SQLException //获得当前行名为cloumnLabel列的String值
根据学号sid查询student表中的一条学生记录。
package com.cxyzxc.www.examples01; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现根据学号sid查询数据库jdbcdatabase里student表中的一条数据 * */ public class Jdbc04SelectOneStudent01 { public static void main(String[] args) { Connection connection = null; Statement statement = null; ResultSet resultSet = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "SELECT * FROM `student` WHERE `sid`= 1002;"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = statement.executeQuery(sql); // 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 if (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int sid = resultSet.getInt(1); String name = resultSet.getString(2); int age = resultSet.getInt(3); String gender = resultSet.getString(4); String phone = resultSet.getString(5); String identitycard = resultSet.getString(6); String address = resultSet.getString(7); System.out.println(sid + "-" + name + "-" + age + "-" + gender + "-" + phone + "-" + identitycard + "-" + address); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples01; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现根据学号sid查询数据库jdbcdatabase里student表中的一条数据 * */ public class Jdbc04SelectOneStudent02 { public static void main(String[] args) { Connection connection = null; Statement statement = null; ResultSet resultSet = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "SELECT * FROM `student` WHERE `sid`= 1002;"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = statement.executeQuery(sql); // 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 if (resultSet.next()) { // 根据记录中字段的名称获取字段数据 int sid = resultSet.getInt("sid"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); String gender = resultSet.getString("gender"); String phone = resultSet.getString("phone"); String identitycard = resultSet.getString("identitycard"); String address = resultSet.getString("address"); System.out.println(sid + "-" + name + "-" + age + "-" + gender + "-" + phone + "-" + identitycard + "-" + address); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
查询student表中所有的学生记录。
package com.cxyzxc.www.examples01; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现查询数据库jdbcdatabase里student表中的所有数据 * */ public class Jdbc05SelectAllStudent01 { public static void main(String[] args) { Connection connection = null; Statement statement = null; ResultSet resultSet = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "SELECT * FROM `student`;"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = statement.executeQuery(sql); // 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 while (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int sid = resultSet.getInt(1); String name = resultSet.getString(2); int age = resultSet.getInt(3); String gender = resultSet.getString(4); String phone = resultSet.getString(5); String identitycard = resultSet.getString(6); String address = resultSet.getString(7); System.out.println(sid + "-" + name + "-" + age + "-" + gender + "-" + phone + "-" + identitycard + "-" + address); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples01; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现查询数据库jdbcdatabase里student表中的所有数据 * */ public class Jdbc05SelectAllStudent02 { public static void main(String[] args) { Connection connection = null; Statement statement = null; ResultSet resultSet = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "SELECT * FROM `student`;"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = statement.executeQuery(sql); // 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 while (resultSet.next()) { // 根据记录中字段的名称获取字段数据 int sid = resultSet.getInt("sid"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); String gender = resultSet.getString("gender"); String phone = resultSet.getString("phone"); String identitycard = resultSet.getString("identitycard"); String address = resultSet.getString("address"); System.out.println(sid + "-" + name + "-" + age + "-" + gender + "-" + phone + "-" + identitycard + "-" + address); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
(1)ORM(Object Relational Mapping),对象关系映射。
(2)从数据库查询到的结果集(ResultSet)在进行遍历时,逐行遍历,然后一个字段一个字段的读取数据,取出的都是零散的数据,然后将零散数据一个一个输出,这样比较麻烦,不利于操作。在实际应用开发中,我们需要将零散的数据进行封装整理。
(3)在Java中,将一个封装好的对象插入到数据库的student表中,也可以将查询出来的数据封装成一个对象。
package com.cxyzxc.www.examples02; /** * entity实体类Student * */ public class Student { /** 学号 */ private int sid; /** 姓名 */ private String name; /** 年龄 */ private int age; /** 性别 */ private String gender; /** 手机号码 */ private String phone; /** 身份证号码 */ private String identitycard; /** 住址 */ private String address; // 无参构造方法 public Student() { super(); } // 有参构造方法 public Student(String name, int age, String gender, String phone, String identitycard, String address) { super(); this.name = name; this.age = age; this.gender = gender; this.phone = phone; this.identitycard = identitycard; this.address = address; } // 有参构造方法 public Student(int sid, String name, int age, String gender, String phone, String identitycard, String address) { super(); this.sid = sid; this.name = name; this.age = age; this.gender = gender; this.phone = phone; this.identitycard = identitycard; this.address = address; } // getXxx()/setXxx()方法 public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getIdentitycard() { return identitycard; } public void setIdentitycard(String identitycard) { this.identitycard = identitycard; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } // 重写toString()方法 @Override public String toString() { return "Student [sid=" + sid + ", name=" + name + ", age=" + age + ", gender=" + gender + ", phone=" + phone + ", identitycard=" + identitycard + ", address=" + address + "]"; } }
package com.cxyzxc.www.examples02; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现向数据库jdbcdatabase里student表中插入一条数据 * */ public class Jdbc01ORMInsertStudent { public static void main(String[] args) { Connection connection = null; Statement statement = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); //创建Student类对象 Student student = new Student("李二牛", 28, "男", "13844556633", "340825199409192345", "安徽合肥经开区"); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误,这里sid是自增长,所以不需要写 String sql = "INSERT INTO `student`(`name`,`age`,`gender`,`phone`,`identitycard`,`address`) VALUES ('"+student.getName()+"',"+student.getAge()+",'"+student.getGender()+"','"+student.getPhone()+"','"+student.getIdentitycard()+"','"+student.getAddress()+"');"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = statement.executeUpdate(sql); // 6、处理结果,如果返回的受影响行数不为0,说明数据插入成功 if (result != 0) { System.out.println("数据插入成功"); } else { System.out.println("数据插入失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples02; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现删除数据库jdbcdatabase里student表中的一条数据 * */ public class Jdbc02ORMDeleteStudent { public static void main(String[] args) { Connection connection = null; Statement statement = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); //创建Student类对象 Student student = new Student(1003,"李二狗", 28, "男", "13844556644", "340825199409192345", "安徽合肥高新区"); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "DELETE FROM `student` WHERE `sid` = "+student.getSid()+";"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = statement.executeUpdate(sql); // 6、处理结果,如果返回的受影响行数不为0,说明数据删除成功 if (result != 0) { System.out.println("数据删除成功"); } else { System.out.println("数据删除失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples02; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现修改数据库jdbcdatabase里student表中的一条数据 * */ public class Jdbc03ORMUpdateStudent { public static void main(String[] args) { Connection connection = null; Statement statement = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); //创建Student类对象 Student student = new Student(1003,"李二狗", 28, "男", "13844556644", "340825199409192345", "安徽合肥高新区"); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "UPDATE `student` SET `name`='"+student.getName()+"',`age`="+student.getAge()+",`gender`='"+student.getGender()+"',`phone`='"+student.getPhone()+"',`identitycard`='"+student.getIdentitycard()+"',`address`='"+student.getAddress()+"' WHERE `sid`="+student.getSid()+";"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = statement.executeUpdate(sql); // 6、处理结果,如果返回的受影响行数不为0,说明数据修改成功 if (result != 0) { System.out.println("数据修改成功"); } else { System.out.println("数据修改失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples02; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现根据学号sid查询数据库jdbcdatabase里student表中的一条数据 * */ public class Jdbc04ORMSelectOneStudent { public static void main(String[] args) { Connection connection = null; Statement statement = null; ResultSet resultSet = null; Student student = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "SELECT * FROM `student` WHERE `sid`= 1002;"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = statement.executeQuery(sql); // 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 if (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int sid = resultSet.getInt(1); String name = resultSet.getString(2); int age = resultSet.getInt(3); String gender = resultSet.getString(4); String phone = resultSet.getString(5); String identitycard = resultSet.getString(6); String address = resultSet.getString(7); // System.out.println(sid + "-" + name + "-" + age + "-" +gender + "-" + phone + "-" + identitycard + "-" + address); // 创建实体类对象 student = new Student(); // 给实体类对象属性赋值,也可以通过有参构造方法创建实体类对象并给对象属性赋值 student.setSid(sid); student.setName(name); student.setAge(age); student.setGender(gender); student.setPhone(phone); student.setIdentitycard(identitycard); student.setAddress(address); //输出对象 System.out.println(student); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples02; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; /** * JDBC连接数据 实现查询数据库jdbcdatabase里student表中的所有数据 * */ public class Jdbc05ORMSelectAllStudent { public static void main(String[] args) { Connection connection = null; Statement statement = null; ResultSet resultSet = null; Student student = null; List<Student> studentList = new ArrayList<Student>(); try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "SELECT * FROM `student`;"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = statement.executeQuery(sql); // 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 while (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int sid = resultSet.getInt(1); String name = resultSet.getString(2); int age = resultSet.getInt(3); String gender = resultSet.getString(4); String phone = resultSet.getString(5); String identitycard = resultSet.getString(6); String address = resultSet.getString(7); // System.out.println(sid + "-" + name + "-" + age + "-" + gender + "-" + phone + "-" + identitycard + "-" + address); // 通过有参构造方法创建实体类对象 student = new Student(sid, name, age, gender, phone, identitycard, address); // 输出对象 studentList.add(student); } // 遍历输出studentList集合中的数据 for (Student student2 : studentList) { System.out.println(student2); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
表的字段如下:
id,用户编号,主键、自动增长。
username,用户名,字符串类型、唯一、非空。
password,密码,字符串类型、非空。
phone,手机号码,字符串类型
CREATE TABLE IF NOT EXISTS `user`(
`uid` INT PRIMARY KEY AUTO_INCREMENT,
`username` VARCHAR(10) UNIQUE NOT NULL,
`password` VARCHAR(10) NOT NULL,
`phone` VARCHAR(11)
);
向user表中插入两条数据:
INSERT INTO `user`(`uid`,`username`,`password`,`phone`) VALUES(1001,'zhangsan','123456','13112345678');
INSERT INTO `user`(`uid`,`username`,`password`,`phone`) VALUES(1002,'lisi','123456','13844445555');
使用JDBC+ORM技术点实现对user表增删改查操作,巩固知识点。
package com.cxyzxc.www.examples03; /** * entity类User类 * */ public class User { /** 用户编号 */ private int uid; /** 用户名 */ private String name; /** 密码 */ private String password; /** 手机号码 */ private String phone; // 无参构造方法 public User() { super(); } // 有参构造方法 public User(String name, String password, String phone) { super(); this.name = name; this.password = password; this.phone = phone; } // 有参构造方法 public User(int uid, String name, String password, String phone) { super(); this.uid = uid; this.name = name; this.password = password; this.phone = phone; } // getXxx()/setXxx()方法 public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } // 重写toString()方法 @Override public String toString() { return "User [uid=" + uid + ", name=" + name + ", password=" + password + ", phone=" + phone + "]"; } }
package com.cxyzxc.www.examples03; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现向数据库jdbcdatabase里user表中插入一条数据 * */ public class Jdbc01ORMInsertUser { public static void main(String[] args) { Connection connection = null; Statement statement = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); //创建User对象 User user2 = new User("王五", "123456", "13966669999"); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误,这里sid是自增长,所以不需要写 String sql = "INSERT INTO `user`(`username`,`password`,`phone`) VALUES('"+user2.getName()+"','"+user2.getPassword()+"','"+user2.getPhone()+"');"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = statement.executeUpdate(sql); // 6、处理结果,如果返回的受影响行数不为0,说明数据插入成功 if (result != 0) { System.out.println("数据插入成功"); } else { System.out.println("数据插入失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples03; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现删除数据库jdbcdatabase里user表中的一条数据 * */ public class Jdbc02ORMDeleteUser { public static void main(String[] args) { Connection connection = null; Statement statement = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); //创建对象 User user2 = new User(1003, "王五", "123456", "13966669999"); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "DELETE FROM `user` WHERE `uid` = "+user2.getUid()+";"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = statement.executeUpdate(sql); // 6、处理结果,如果返回的受影响行数不为0,说明数据删除成功 if (result != 0) { System.out.println("数据删除成功"); } else { System.out.println("数据删除失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples03; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现修改数据库jdbcdatabase里user表中的一条数据 * */ public class Jdbc03ORMUpdateUser { public static void main(String[] args) { Connection connection = null; Statement statement = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、获取发送SQL语句对象 statement = connection.createStatement(); //创建User对象 User user2 = new User(1002, "李四", "112233", "13999998888"); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "UPDATE `user` SET `username`='"+user2.getName()+"',`password`='"+user2.getPassword()+"',`phone`='"+user2.getPhone()+"' WHERE `uid`="+user2.getUid()+";"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = statement.executeUpdate(sql); // 6、处理结果,如果返回的受影响行数不为0,说明数据修改成功 if (result != 0) { System.out.println("数据修改成功"); } else { System.out.println("数据修改失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples03; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * JDBC连接数据 实现根据学号uid查询数据库jdbcdatabase里user表中的一条数据 * */ public class Jdbc04ORMSelectOneUser { public static void main(String[] args) { Connection connection = null; Statement statement = null; ResultSet resultSet = null; User user = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String name = "root"; String pwd = "123456"; connection = DriverManager.getConnection(url, name, pwd); // 3、获取发送SQL语句对象 statement = connection.createStatement(); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "SELECT * FROM `user` WHERE `uid`= 1002;"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = statement.executeQuery(sql); // 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 if (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int uid = resultSet.getInt(1); String username = resultSet.getString(2); String password = resultSet.getString(3); String phone = resultSet.getString(4); //使用有参构造方法创建user对象 user = new User(uid, username, password, phone); //输出对象 System.out.println(user); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples03; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; /** * JDBC连接数据 实现根据学号uid查询数据库jdbcdatabase里user表中的一条数据 * */ public class Jdbc05ORMSelectAllUser { public static void main(String[] args) { Connection connection = null; Statement statement = null; ResultSet resultSet = null; User user = null; List<User> userList = new ArrayList<User>(); try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String name = "root"; String pwd = "123456"; connection = DriverManager.getConnection(url, name, pwd); // 3、获取发送SQL语句对象 statement = connection.createStatement(); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "SELECT * FROM `user`;"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = statement.executeQuery(sql); // 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 while (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int uid = resultSet.getInt(1); String username = resultSet.getString(2); String password = resultSet.getString(3); String phone = resultSet.getString(4); //使用有参构造方法创建user对象 user = new User(uid, username, password, phone); //将创建的对象添加到集合中 userList.add(user); } //遍历集合,输出所有user对象 for (User user2 : userList) { System.out.println(user2); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
需求:
package com.cxyzxc.www.examples03; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Scanner; /** * 登录类:Login类 * */ public class Login { public static void main(String[] args) { Connection connection = null; Statement statement = null; ResultSet resultSet = null; //创建Scanner对象,获取用户名和密码 Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String username = sc.nextLine(); System.out.println("请输入密码:"); String password = sc.nextLine(); try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String name = "root"; String pwd = "123456"; connection = DriverManager.getConnection(url, name, pwd); // 3、获取发送SQL语句对象 statement = connection.createStatement(); // 4、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "SELECT * FROM `user` WHERE `username`='"+username+"' AND `password` = '"+password+"';"; // 5、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = statement.executeQuery(sql); // 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 if(resultSet.next()){ System.out.println("用户名和密码正确,登录成功"); }else{ System.out.println("用户名或密码不正确,登录失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } sc.close(); } } }
参照上面的登录代码
输入错误的用户名和密码,提示登录失败:
输入错误的用户名和密码,提示登录成功:产生了SQL注入
![在这里插入图片描述](https://img-blog.csdnimg.cn/9f4a36654b5a45e28a001d2798729500.png#pic_center
在用户输入的数据中有SQL关键字或语法,并且关键字或语法参与了SQL语句的编译。导致SQL语句编译后的条件为true,一直得到正确的结果。这种现象就是SQL注入。
上面案例代码中,当你的用户名为 qwert’ or 1=1;# 密码为123,拼接到SQL语句中,变成如下效果:
SELECT * FROM USER WHERE `username`='qwert' OR 1=1;#' AND `password` = '123';
此SQL语句or 后面1=1永远正确,#后面的成了注释,所以这条语句会将表中所有的数据查询出来,然后再做数据判断的时候,就会得到正确结果,从而说用户名和密码正确,登录成功
由于SQL注入产生的原因是在用户输入数据对SQL整合,整合后再发送到数据库进行编译产生的。所以为了避免SQL注入,就需要SQL语句在用户输入数据前就进行编译,成为完整的SQL语句,编译完成后再进行数据填充。这个操作需要使用PrepareStatement实现。
PreparedStatement接口继承了Statement接口,执行SQL语句的方法与Statement执行SQL语句的方法相同。
PreparedStatement的作用:
//预编译SQL语句,SQL中的所有参数由?符号占位,这被称为参数标记。在执行SQL语句之前,必须为每个参数提供值。
String sql = "select * from user where `username` = ? and `password`=?;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.sexXxx(下标,值):参数下标从1开始,为指定参数下标绑定值。Xxx表示数据类型。
//绑定参数,有多少个?绑定多少个参数值
preparedStatement.setString(1, username);
preparedStatement.setString(2, pwd);
package com.cxyzxc.www.examples04; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; /** * JDBC连接数据 实现向数据库jdbcdatabase里user表中插入一条数据 * */ public class Jdbc01PreparedStatementInsertUser { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement =null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "INSERT INTO `user`(`username`,`password`,`phone`) VALUES(?,?,?);"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); //创建对象 User user2 = new User("如花", "123456", "13311112222"); //5、绑定参数,给?赋值 preparedStatement.setString(1, user2.getName()); preparedStatement.setString(2, user2.getPassword()); preparedStatement.setString(3, user2.getPhone()); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = preparedStatement.executeUpdate(); // 7、处理结果,如果返回的受影响行数不为0,说明数据插入成功 if (result != 0) { System.out.println("数据插入成功"); } else { System.out.println("数据插入失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples04; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; /** * JDBC连接数据 实现删除数据库jdbcdatabase里user表中的一条数据 * */ public class Jdbc02PreparedStatementDeleteUser { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement =null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "DELETE FROM `user` WHERE `uid` = ?;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); //5、绑定参数,给?赋值 preparedStatement.setInt(1, 1003); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = preparedStatement.executeUpdate(); // 7、处理结果,如果返回的受影响行数不为0,说明数据删除成功 if (result != 0) { System.out.println("数据删除成功"); } else { System.out.println("数据删除失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples04; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; /** * JDBC连接数据 实现修改数据库jdbcdatabase里user表中的一条数据 * */ public class Jdbc03PreparedStatementUpdateUser { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement =null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "UPDATE `user` SET `username`=?,`password`=?,`phone`=? WHERE `uid`=?;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); //创建User对象 User user2 = new User(1002, "李四", "112233", "13955661133"); //5、绑定参数,给?赋值 preparedStatement.setString(1,user2.getName()); preparedStatement.setString(2,user2.getPassword()); preparedStatement.setString(3,user2.getPhone()); preparedStatement.setInt(4, user2.getUid()); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = preparedStatement.executeUpdate(); // 7、处理结果,如果返回的受影响行数不为0,说明数据修改成功 if (result != 0) { System.out.println("数据修改成功"); } else { System.out.println("数据修改失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples04; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * JDBC连接数据 实现根据学号uid查询数据库jdbcdatabase里user表中的一条数据 * */ public class Jdbc04PreparedStatementSelectOneStudent { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; User user = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String name = "root"; String pwd = "123456"; connection = DriverManager.getConnection(url, name, pwd); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "SELECT * FROM `user` WHERE `uid`= ?;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); // 5、绑定参数,给?赋值 preparedStatement.setInt(1, 1002); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = preparedStatement.executeQuery(); // 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 if (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int uid = resultSet.getInt(1); String username = resultSet.getString(2); String password = resultSet.getString(3); String phone = resultSet.getString(4); //使用有参构造方法创建user对象 user = new User(uid, username, password, phone); //输出对象 System.out.println(user); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples04; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; /** * JDBC连接数据 实现根据学号uid查询数据库jdbcdatabase里user表中的一条数据 * */ public class Jdbc05PreparedStatementSelectAllStudent { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; User user = null; List<User> userList = new ArrayList<User>(); try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String name = "root"; String pwd = "123456"; connection = DriverManager.getConnection(url, name, pwd); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "SELECT * FROM `user`;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); // 5、绑定参数,给?赋值,这里不需要绑定参数 // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = preparedStatement.executeQuery(); // 7、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 while (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int uid = resultSet.getInt(1); String username = resultSet.getString(2); String password = resultSet.getString(3); String phone = resultSet.getString(4); //使用有参构造方法创建user对象 user = new User(uid, username, password, phone); //将创建的对象添加到集合中 userList.add(user); } //遍历集合,输出所有user对象 for (User user2 : userList) { System.out.println(user2); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples04; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Scanner; /** * PreparedStatement实现登录,解决SQL注入问题 * */ public class PreparedStatementLogin { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; //创建Scanner对象,获取用户名和密码 Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String username = sc.nextLine(); System.out.println("请输入密码:"); String password = sc.nextLine(); try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String name = "root"; String pwd = "123456"; connection = DriverManager.getConnection(url, name, pwd); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "SELECT * FROM `user` WHERE `username`=? AND `password` = ?;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); //5、绑定参数,给?赋值 preparedStatement.setString(1, username); preparedStatement.setString(2, password); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = preparedStatement.executeQuery(); // 7、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 if(resultSet.next()){ System.out.println("用户名和密码正确,登录成功"); }else{ System.out.println("用户名或密码不正确,登录失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } sc.close(); } } }
学完使用JDBC连接数据库并使用PrepareStatement类对表中数据进行增删改查后,我们做一个练习,对下列people表进行增删改查操作。
创建一张用户表peopler,表的字段如下:
pid,编号,主键、自动增长
name,姓名,varchar(20)、非空
age,年龄,int(3),非空
gender,性别,varchar(3),非空
birthday,出生日期,Date类型,非空
identitycard,身份证号码,varchar(18) ,唯一,非空
phone,手机号码,字符串类型,唯一,非空
address,住址,varchar(20),非空
CREATE TABLE IF NOT EXISTS `people`(
`pid` INT PRIMARY KEY AUTO_INCREMENT COMMENT '编号',
`name` VARCHAR(20) NOT NULL COMMENT '姓名',
`age` INT(3) NOT NULL COMMENT '年龄',
`gender` VARCHAR(3) NOT NULL COMMENT '性别',
`birthday` DATE NOT NULL COMMENT '出生日期',
`identitycrd` VARCHAR(18) NOT NULL UNIQUE COMMENT '身份证号码',
`phone` VARCHAR(11) NOT NULL UNIQUE COMMENT '手机号码',
`address` VARCHAR(20) NOT NULL COMMENT '住址'
);
向people表中插入两条数据:
INSERT INTO `people`(`pid`,`name`,`age`,`gender`,`birthday`,`identitycrd`,`phone`,`address`)
VALUES
(1001,'张三',30,'男','1992-04-05','340825199204051920','13888885555','安徽合肥庐阳区');
INSERT INTO `people`(`pid`,`name`,`age`,`gender`,`birthday`,`identitycrd`,`phone`,`address`)
VALUES
(1002,'李红',28,'女','1994-04-15','340825199204151922','13888886666','安徽合肥瑶海区');
在上述操作过程中发现如下问题:
数据库中存储的日期时间类型为java.sql.Date类型,Java应用层存储的日期时间类型为java.util.Date类型。
从数据库获取的日期时间类型数据可以直接赋值给Java应用层的日期时间类型变量,因为java.sql.Date类是java.util.Date类的子类,向上转型(父类引用指向子类对象)是可以直接赋值的。
Java应用层的日期时间类型数据不能直接存储在数据库中,需要进行相应的转换。
preparedStatement.setDate(int parameterIndex, Date x)中Date为java.sql.Date类型。
(1)Java语言常规应用层面的日期时间类型,可以通过字符串创建对应的日期时间对象,但是已经过时。常用构造方法如下(很多构造方法已经过时):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O3LfZxvU-1690879270297)(img/09java.util.date类的构造方法.png)]
(2)不能直接通过JDBC将java.util.Date类型数据插入到数据库中。
(1)不可以通过字符串创建对应的时间对象,只能通过毫秒值创建对象(1970年1月1日0点0分0秒至今的毫秒值),常用构造方法如下:
(2)可以直接通过JDBC将java.util.Date类型数据插入到数据库中。
(1)SimpleDateFormat是一个以与语言环境有关的方式来格式化和解析日期的具体类。它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)和规范化。
(2)SimpleDateFormat使得可以选择任何用户定义的日期-时间格式的模式。
(3)SimpleDateFormat应用如下:
package com.cxyzxc.www.examples05; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /** * SimpleDateFormat类应用 * */ public class SimpleDateFormatTest { public static void main(String[] args) { // 指定日期格式 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { String strDate1 = "2022-10-22"; // 将字字符串解析成日期类型(java.util.Date) java.util.Date date1 = sdf.parse(strDate1); System.out.println("字符串解析成日期:" + date1); Date date2 = new Date(); String strDate2 = sdf.format(date2); System.out.println("日期解析成字符串:" + strDate2); } catch (ParseException e) { e.printStackTrace(); } } }
package com.cxyzxc.www.examples05; import java.text.ParseException; import java.text.SimpleDateFormat; /** * 日期时间工具类DateUtils * */ public class DateUtils { private static final SimpleDateFormat SIMPLEDATEFORMAT = new SimpleDateFormat("yyyy-MM-dd"); // 字符串转换为java.util.Date类型日期时间 public static java.util.Date strDateToUtilDate(String strDate) { try { return SIMPLEDATEFORMAT.parse(strDate); } catch (ParseException e) { e.printStackTrace(); } return null; } // java.util.Date类型日期时间转换为java.sql.Date类型日期时间 public static java.sql.Date utilDateToSqlDate(java.util.Date date) { // long date.getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT以来此 Date对象表示的毫秒数 return new java.sql.Date(date.getTime()); } // java.util.Date类转换为字符串类型 public static String utilDateToString(java.util.Date date) { return SIMPLEDATEFORMAT.format(date); } }
package com.cxyzxc.www.examples05; import java.util.Date; /** * entity实体类People类 * */ public class People { /** 编号 */ private int pid; /** 姓名 */ private String name; /** 年龄 */ private int age; /** 性别 */ private String gender; /** 出生日期 */ private Date birthday; /** 身份证号码 */ private String identitycard; /** 手机号码 */ private String phone; /** 住址 */ private String address; // 无参构造方法 public People() { super(); } // 有参构造方法 public People(String name, int age, String gender, Date birthday, String identitycard, String phone, String address) { super(); this.name = name; this.age = age; this.gender = gender; this.birthday = birthday; this.identitycard = identitycard; this.phone = phone; this.address = address; } // 有参构造方法 public People(int pid, String name, int age, String gender, Date birthday, String identitycard, String phone, String address) { super(); this.pid = pid; this.name = name; this.age = age; this.gender = gender; this.birthday = birthday; this.identitycard = identitycard; this.phone = phone; this.address = address; } // getXxx()/setXxx()方法 public int getPid() { return pid; } public void setPid(int pid) { this.pid = pid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getIdentitycard() { return identitycard; } public void setIdentitycard(String identitycard) { this.identitycard = identitycard; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } // 重写toString()方法 @Override public String toString() { return "People [pid=" + pid + ", name=" + name + ", age=" + age + ", gender=" + gender + ", birthday=" + birthday + ", identitycard=" + identitycard + ", phone=" + phone + ", address=" + address + "]"; } }
package com.cxyzxc.www.examples05; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; /** * JDBC连接数据 实现向数据库jdbcdatabase里people表中插入一条数据 * */ public class Jdbc01PreparedStatementInsertPeople { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement =null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "INSERT INTO `people`(`name`,`age`,`gender`,`birthday`,`identitycard`,`phone`,`address`) VALUES(?,?,?,?,?,?,?);"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); //创建People对象 People people = new People("王五", 30, "男", DateUtils.strDateToUtilDate("1992-04-05"), "340825199204051926", "13845691236", "安徽合肥庐阳区"); //5、绑定参数,给?赋值 preparedStatement.setString(1, people.getName()); preparedStatement.setInt(2,people.getAge()); preparedStatement.setString(3,people.getGender()); //setDate(Date date)方法中需要的参数date类型是java.sql.Date类型,People对象中的Date类型是java.util.Date,需要进行转换 preparedStatement.setDate(4,DateUtils.utilDateToSqlDate(people.getBirthday())); preparedStatement.setString(5,people.getIdentitycard()); preparedStatement.setString(6, people.getPhone()); preparedStatement.setString(7, people.getAddress()); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = preparedStatement.executeUpdate(); // 7、处理结果,如果返回的受影响行数不为0,说明数据插入成功 if (result != 0) { System.out.println("数据插入成功"); } else { System.out.println("数据插入失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples05; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; /** * JDBC连接数据 实现删除数据库jdbcdatabase里people表中的一条数据 * */ public class Jdbc02PreparedStatementDeletePeople { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement =null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "DELETE FROM `people` WHERE `pid` = ?;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); //5、绑定参数,给?赋值 preparedStatement.setInt(1, 1003); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = preparedStatement.executeUpdate(); // 7、处理结果,如果返回的受影响行数不为0,说明数据删除成功 if (result != 0) { System.out.println("数据删除成功"); } else { System.out.println("数据删除失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples05; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; /** * JDBC连接数据 实现修改数据库jdbcdatabase里people表中的一条数据 * */ public class Jdbc03PreparedStatementUpdatePeople { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement =null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String user = "root"; String password = "123456"; connection = DriverManager.getConnection(url, user, password); // 3、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "UPDATE `people` SET `name`=?,`age`=?,`gender`=?,`birthday`=?,`identitycard`=?,`phone`=?,`address`=? WHERE `pid`=?;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); //创建对象 People people = new People(1002, "李花花", 28, "女", DateUtils.strDateToUtilDate("1994-04-15"), "340825199404151922", "13122337788", "安徽合肥政务区"); //5、绑定参数,给?赋值 preparedStatement.setString(1,people.getName()); preparedStatement.setInt(2, people.getAge()); preparedStatement.setString(3,people.getGender()); preparedStatement.setDate(4, DateUtils.utilDateToSqlDate(people.getBirthday())); preparedStatement.setString(5,people.getIdentitycard()); preparedStatement.setString(6,people.getPhone()); preparedStatement.setString(7,people.getAddress()); preparedStatement.setInt(8, people.getPid()); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = preparedStatement.executeUpdate(); // 7、处理结果,如果返回的受影响行数不为0,说明数据修改成功 if (result != 0) { System.out.println("数据修改成功"); } else { System.out.println("数据修改失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples05; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; /** * JDBC连接数据 实现根据学号uid查询数据库jdbcdatabase里people表中的一条数据 * */ public class Jdbc04PreparedStatementSelectOnePeople { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; People people = null; try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String name = "root"; String pwd = "123456"; connection = DriverManager.getConnection(url, name, pwd); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "SELECT * FROM `people` WHERE `pid`= ?;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); // 5、绑定参数,给?赋值 preparedStatement.setInt(1, 1002); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = preparedStatement.executeQuery(); // 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 if (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int pid = resultSet.getInt(1); String peopleName = resultSet.getString(2); int age = resultSet.getInt(3); String gender = resultSet.getString(4); Date birthday = resultSet.getDate(5); String identitycard=resultSet.getString(6); String phone =resultSet.getString(7); String address=resultSet.getString(8); //使用有参构造方法创建People对象 people = new People(pid, peopleName, age, gender, birthday, identitycard, phone, address); //输出对象 System.out.println(people); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package com.cxyzxc.www.examples05; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * JDBC连接数据 实现根据编号pid查询数据库jdbcdatabase里people表中的一条数据 * */ public class Jdbc05PreparedStatementSelectAllPeople { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; People people = null; List<People> peopleList = new ArrayList<People>(); try { // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2 、获取数据库连接对象 String url = "jdbc:mysql://127.0.0.1:3306/jdbcdatabase"; String name = "root"; String pwd = "123456"; connection = DriverManager.getConnection(url, name, pwd); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "SELECT * FROM `people`;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); // 5、绑定参数,给?赋值,这里不需要绑定参数 // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = preparedStatement.executeQuery(); // 7、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 while (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int pid = resultSet.getInt(1); String peopleName = resultSet.getString(2); int age = resultSet.getInt(3); String gender = resultSet.getString(4); Date birthday = resultSet.getDate(5); String identitycard=resultSet.getString(6); String phone =resultSet.getString(7); String address=resultSet.getString(8); //使用有参构造方法创建People对象 people = new People(pid, peopleName, age, gender, birthday, identitycard, phone, address); //将创建的对象添加到集合中 peopleList.add(people); } //遍历集合,输出所有People对象 for (People People2 : peopleList) { System.out.println(People2); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
(1)新建一个工具类DBUtils。
(2)在工具类DBUtils类中封装获取连接、释放资源两个方法。
package com.cxyzxc.www.examples01; import java.sql.*; /** * 重用性方案 注册驱动 获取连接 释放资源 * */ public class DBUtils { // 类加载,执行一次! static { try { // 注册驱动 Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } // 获取连接 public static Connection getConnection() { Connection connection = null; try { connection = DriverManager.getConnection( "jdbc:mysql://localhost:3306/jdbcdatabase", "root", "123456"); } catch (SQLException e) { e.printStackTrace(); } return connection; } // 释放资源 public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) { try { if (resultSet != null) { resultSet.close(); } if (statement != null) { statement.close(); } if (connection != null) { connection.close(); } } catch (SQLException e) { e.printStackTrace(); } } }
(1)在重用性方案中数据库的相关信息写在Java代码中,如果要修改数据库的相关信息,需要修改Java代码,比较麻烦,所以需要将数据库相关信息抽取出来放到一个专门的文件中存储。
(2)在项目src文件夹下创建db.properties文件,在文件中编写数据库驱动、数据库url、用户名、密码相关数据。
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/java2217
username=root
password=123456
(2)在工具类DBUtils类中读取db.properties配置文件数据。
定义private static final Properties PROPERTIES = new Properties();//读取配置文件的Map 定义static{ //通过复用本类自带流,读取配置文件中的数据 InputStream is = DBUtils.class.getResourceAsStream("配置文件路径"); // 通过prop对象将流中的配置信息分隔成键值对 PROPERTIES.load(is); //通过driverName的键获取对应的值(com.mysql.jdbc.Driver) String driverName=PROPERTIES.getProperty("driver"); //注册驱动 Class.forName(driverName); }
(3)在工具类DBUtils类中封装获取连接、释放资源两个方法。
package com.cxyzxc.www.examples02; import java.io.IOException; import java.io.InputStream; import java.sql.*; import java.util.Properties; /** * 跨平台方案 注册驱动 获取连接 释放资源 * */ public class DBUtils { // //读取配置文件的Map private static final Properties PROPERTIES = new Properties(); static { // 通过复用本类自带流,读取配置文件中的数据 InputStream is = DBUtils.class.getResourceAsStream("/db.properties"); try { // 通过prop对象将流中的配置信息分隔成键值对,将配置文件内容加载到properties集合 PROPERTIES.load(is); // 注册驱动,通过driverName的键获取对应的值(com.mysql.jdbc.Driver) Class.forName(PROPERTIES.getProperty("driver")); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } // 获取连接对象 public static Connection getConnection() { Connection connection = null; try { connection = DriverManager.getConnection( PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password")); } catch (SQLException e) { e.printStackTrace(); } return connection; } // 释放所有资源 public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) { try { if (resultSet != null) { resultSet.close(); } if (statement != null) { statement.close(); } if (connection != null) { connection.close(); } } catch (SQLException e) { e.printStackTrace(); } } }
CREATE TABLE IF NOT EXISTS `animal`(
`aid` INT PRIMARY KEY AUTO_INCREMENT COMMENT '宠物编号',
`type` VARCHAR(10) NOT NULL COMMENT '类型',
`name` VARCHAR(10) NOT NULL COMMENT '名字',
`age` INT NOT NULL COMMENT '年龄',
`gender` VARCHAR(3) NOT NULL COMMENT '性别',
`birthday` DATE NOT NULL COMMENT '出生日期'
);
INSERT INTO `animal`(`aid`,`type`,`name`,`age`,`gender`,`birthday`)
VALUES
(1001,'狗','旺财',3,'公','2019-12-18');
INSERT INTO `animal`(`aid`,`type`,`name`,`age`,`gender`,`birthday`)
VALUES
(1002,'猫','阿狸',2,'母','2020-03-27');
package com.cxyzxc.www.examples01; import java.util.Date; public class Animal { /** 宠物编号 */ private int aid; /** 类型 */ private String type; /** 名字 */ private String name; /** 年龄 */ private int age; /** 性别 */ private String gender; /** 出生日期 */ private Date birthday; // 无参构造方法 public Animal() { super(); } // 有参构造方法 public Animal(String type, String name, int age, String gender, Date birthday) { super(); this.type = type; this.name = name; this.age = age; this.gender = gender; this.birthday = birthday; } // 有参构造方法 public Animal(int aid, String type, String name, int age, String gender, Date birthday) { super(); this.aid = aid; this.type = type; this.name = name; this.age = age; this.gender = gender; this.birthday = birthday; } // getXxx()/setXxx()方法 public int getAid() { return aid; } public void setAid(int aid) { this.aid = aid; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } // 重写toString()方法 @Override public String toString() { return "Animal [aid=" + aid + ", type=" + type + ", name=" + name + ", age=" + age + ", gender=" + gender + ", birthday=" + birthday + "]"; } }
package com.cxyzxc.www.examples01; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /** * JDBC连接数据 实现向数据库jdbcdatabase里animal表中插入一条数据 * */ public class Jdbc01PreparedStatementInsertAnimal { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement = null; try { // 2、获取连接对象 connection = DBUtils.getConnection(); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "INSERT INTO `animal`(`type`,`name`,`age`,`gender`,`birthday`) VALUES(?,?,?,?,?);"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); // 创建People对象 Animal animal = new Animal("狗", "来福", 2, "公",DateUtils.strDateToUtilDate("2020-11-02")); // 5、绑定参数,给?赋值 preparedStatement.setString(1, animal.getType()); preparedStatement.setString(2, animal.getName()); preparedStatement.setInt(3, animal.getAge()); preparedStatement.setString(4, animal.getGender()); // setDate(Date // date)方法中需要的参数date类型是java.sql.Date类型,animal对象中的Date类型是java.util.Date,需要进行转换 preparedStatement.setDate(5,DateUtils.utilDateToSqlDate(animal.getBirthday())); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = preparedStatement.executeUpdate(); // 7、处理结果,如果返回的受影响行数不为0,说明数据插入成功 if (result != 0) { System.out.println("数据插入成功"); } else { System.out.println("数据插入失败"); } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } } }
package com.cxyzxc.www.examples01; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /** * JDBC连接数据 实现删除数据库jdbcdatabase里people表中的一条数据 * */ public class Jdbc02PreparedStatementDeleteAnimal { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement =null; try { connection = DBUtils.getConnection(); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "DELETE FROM `animal` WHERE `aid` = ?;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); //5、绑定参数,给?赋值 preparedStatement.setInt(1, 1003); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = preparedStatement.executeUpdate(); // 7、处理结果,如果返回的受影响行数不为0,说明数据删除成功 if (result != 0) { System.out.println("数据删除成功"); } else { System.out.println("数据删除失败"); } } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 DBUtils.closeAll(connection, preparedStatement, null); } } }
package com.cxyzxc.www.examples01; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /** * JDBC连接数据 实现修改数据库jdbcdatabase里animal表中的一条数据 * */ public class Jdbc03PreparedStatementUpdateAnimal { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement =null; try { connection = DBUtils.getConnection(); // 3、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "UPDATE `animal` SET `type`=?,`name`=?,`age`=?,`gender`=?,`birthday`=? WHERE `aid`=?;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); //创建对象 Animal animal = new Animal(1002,"猫","Tom",2,"公",DateUtils.strDateToUtilDate("2020-06-11")); //5、绑定参数,给?赋值 preparedStatement.setString(1,animal.getType()); preparedStatement.setString(2, animal.getName()); preparedStatement.setInt(3,animal.getAge()); preparedStatement.setString(4,animal.getGender()); preparedStatement.setDate(5, DateUtils.utilDateToSqlDate(animal.getBirthday())); preparedStatement.setInt(6,animal.getAid()); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = preparedStatement.executeUpdate(); // 7、处理结果,如果返回的受影响行数不为0,说明数据修改成功 if (result != 0) { System.out.println("数据修改成功"); } else { System.out.println("数据修改失败"); } } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 DBUtils.closeAll(connection, preparedStatement, null); } } }
package com.cxyzxc.www.examples01; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; /** * JDBC连接数据 实现根据学号uid查询数据库jdbcdatabase里animal表中的一条数据 * */ public class Jdbc04PreparedStatementSelectOneAnimal { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Animal animal = null; try { connection = DBUtils.getConnection(); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "SELECT * FROM `animal` WHERE `aid`= ?;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); // 5、绑定参数,给?赋值 preparedStatement.setInt(1, 1001); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = preparedStatement.executeQuery(); // 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 if (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int aid = resultSet.getInt(1); String type = resultSet.getString(2); String name = resultSet.getString(3); int age = resultSet.getInt(4); String gender=resultSet.getString(5); Date birthday = resultSet.getDate(6); //使用有参构造方法创建Animal对象 animal = new Animal(aid, type, name, age, gender, birthday); //输出对象 System.out.println(animal); } } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 DBUtils.closeAll(connection, preparedStatement, resultSet); } } }
package com.cxyzxc.www.examples01; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * JDBC连接数据 实现根据编号pid查询数据库jdbcdatabase里animal表中的一条数据 * */ public class Jdbc05PreparedStatementSelectAllAnimal { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Animal animal = null; List<Animal> animalList = new ArrayList<Animal>(); try { connection = DBUtils.getConnection(); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "SELECT * FROM `animal`;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); // 5、绑定参数,给?赋值,这里不需要绑定参数 // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = preparedStatement.executeQuery(); // 7、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 while (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int aid = resultSet.getInt(1); String type = resultSet.getString(2); String name = resultSet.getString(3); int age = resultSet.getInt(4); String gender=resultSet.getString(5); Date birthday = resultSet.getDate(6); //使用有参构造方法创建Animal对象 animal = new Animal(aid, type, name, age, gender, birthday); //将创建的对象添加到集合中 animalList.add(animal); } //遍历集合,输出所有People对象 for (Animal animal2 : animalList) { System.out.println(animal2); } } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 DBUtils.closeAll(connection, preparedStatement, resultSet); } } }
CREATE TABLE IF NOT EXISTS `car`(
`cid` INT PRIMARY KEY AUTO_INCREMENT COMMENT '编号',
`brand` VARCHAR(10) NOT NULL COMMENT '品牌',
`type` VARCHAR(10) NOT NULL COMMENT '型号',
`color` VARCHAR(10) NOT NULL COMMENT '颜色',
`birthday` DATE NOT NULL COMMENT '出厂日期',
`vin` VARCHAR(20) UNIQUE NOT NULL COMMENT '车架号',
`price` DOUBLE NOT NULL COMMENT '价格'
);
INSERT INTO `car`(`cid`,`brand`,`type`,`color`,`birthday`,`vin`,`price`)
VALUES
(1001,'吉利','星越L','蓝色','2021-11-19','34091564784664WK45',156800);
INSERT INTO `car`(`cid`,`brand`,`type`,`color`,`birthday`,`vin`,`price`)
VALUES
(1002,'奔驰','E300','黑色','2021-11-19','35291579654688BC45',352800);
package com.cxyzxc.www.examples02; import java.util.Date; public class Car { /** 编号 */ private int cid; /** 品牌 */ private String brand; /** 型号 */ private String type; /** 颜色 */ private String color; /** 出厂日期 */ private Date birthday; /** 车架号 */ private String vin; /** 价格 */ private String price; // 无参构造方法 public Car() { super(); } // 有参构造方法 public Car(String brand, String type, String color, Date birthday, String vin, String price) { super(); this.brand = brand; this.type = type; this.color = color; this.birthday = birthday; this.vin = vin; this.price = price; } // 有参构造方法 public Car(int cid, String brand, String type, String color, Date birthday, String vin, String price) { super(); this.cid = cid; this.brand = brand; this.type = type; this.color = color; this.birthday = birthday; this.vin = vin; this.price = price; } // getXxx()/setXxx()方法 public int getCid() { return cid; } public void setCid(int cid) { this.cid = cid; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getVin() { return vin; } public void setVin(String vin) { this.vin = vin; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } // 重写toString()方法 @Override public String toString() { return "Car [cid=" + cid + ", brand=" + brand + ", type=" + type + ", color=" + color + ", birthday=" + birthday + ", vin=" + vin + ", price=" + price + "]"; } }
package com.cxyzxc.www.examples02; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /** * JDBC连接数据 实现向数据库jdbcdatabase里car表中插入一条数据 * */ public class Jdbc01PreparedStatementInsertCar { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement = null; try { // 2、获取连接对象 connection = DBUtils.getConnection(); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "INSERT INTO `car`(`brand`,`type`,`color`,`birthday`,`vin`,`price`) VALUES(?,?,?,?,?,?);"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); // 创建People对象 Car car = new Car("奥迪", "A8", "黑色", DateUtils.strDateToUtilDate("2021-12-17"), "452915723546EYBC45", 1365200); // 5、绑定参数,给?赋值 preparedStatement.setString(1, car.getBrand()); preparedStatement.setString(2, car.getType()); preparedStatement.setString(3, car.getColor()); // setDate(Date date)方法中需要的参数date类型是java.sql.Date类型,car对象中的Date类型是java.util.Date,需要进行转换 preparedStatement.setDate(4, DateUtils.utilDateToSqlDate(car.getBirthday())); preparedStatement.setString(5, car.getVin()); preparedStatement.setDouble(6, car.getPrice()); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = preparedStatement.executeUpdate(); // 7、处理结果,如果返回的受影响行数不为0,说明数据插入成功 if (result != 0) { System.out.println("数据插入成功"); } else { System.out.println("数据插入失败"); } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } } }
package com.cxyzxc.www.examples02; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /** * JDBC连接数据 实现删除数据库jdbcdatabase里car表中的一条数据 * */ public class Jdbc02PreparedStatementDeleteCar { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement =null; try { connection = DBUtils.getConnection(); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "DELETE FROM `car` WHERE `cid` = ?;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); //5、绑定参数,给?赋值 preparedStatement.setInt(1, 1003); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = preparedStatement.executeUpdate(); // 7、处理结果,如果返回的受影响行数不为0,说明数据删除成功 if (result != 0) { System.out.println("数据删除成功"); } else { System.out.println("数据删除失败"); } } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 DBUtils.closeAll(connection, preparedStatement, null); } } }
package com.cxyzxc.www.examples02; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /** * JDBC连接数据 实现修改数据库jdbcdatabase里car表中的一条数据 * */ public class Jdbc03PreparedStatementUpdateCar { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement =null; try { connection = DBUtils.getConnection(); // 3、编写SQL语句,SQL语句最好是先在SQLyog里面写一遍并运行一下,保证SQL语句没有语法错误 String sql = "UPDATE `car` SET `brand`=?,`type`=?,`color`=?,`birthday`=?,`vin`=?,`price`=? WHERE `cid`=?;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); //创建对象 Car car = new Car(1002, "奔驰", "E330", "黑色", DateUtils.strDateToUtilDate("2022-01-11"), "45291579664688WD45", 415600); //5、绑定参数,给?赋值 preparedStatement.setString(1,car.getBrand()); preparedStatement.setString(2, car.getType()); preparedStatement.setString(3,car.getColor()); preparedStatement.setDate(4, DateUtils.utilDateToSqlDate(car.getBirthday())); preparedStatement.setString(5,car.getVin()); preparedStatement.setDouble(6,car.getPrice()); preparedStatement.setInt(7,car.getCid()); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) int result = preparedStatement.executeUpdate(); // 7、处理结果,如果返回的受影响行数不为0,说明数据修改成功 if (result != 0) { System.out.println("数据修改成功"); } else { System.out.println("数据修改失败"); } } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 DBUtils.closeAll(connection, preparedStatement, null); } } }
package com.cxyzxc.www.examples02; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; /** * JDBC连接数据 实现根据学号uid查询数据库jdbcdatabase里car表中的一条数据 * */ public class Jdbc04PreparedStatementSelectOneCar { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Car car = null; try { connection = DBUtils.getConnection(); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "SELECT * FROM `car` WHERE `cid`= ?;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); // 5、绑定参数,给?赋值 preparedStatement.setInt(1, 1002); // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = preparedStatement.executeQuery(); // 6、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 if (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int cid = resultSet.getInt(1); String brand = resultSet.getString(2); String type = resultSet.getString(3); String color = resultSet.getString(4); Date birthday=resultSet.getDate(5); String vin = resultSet.getString(6); double price =resultSet.getDouble(7); //使用有参构造方法创建Animal对象 car = new Car(cid, brand, type, color, birthday, vin, price); //输出对象 System.out.println(car); } } catch (SQLException e) { e.printStackTrace(); } finally { // 7、释放资源,遵循“先开后关,后开先关”的原则 DBUtils.closeAll(connection, preparedStatement, resultSet); } } }
package com.cxyzxc.www.examples02; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * JDBC连接数据 实现根据编号pid查询数据库jdbcdatabase里car表中的一条数据 * */ public class Jdbc05PreparedStatementSelectAllCar { public static void main(String[] args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Car car = null; List<Car> carList = new ArrayList<Car>(); try { connection = DBUtils.getConnection(); // 3、编写SQL语句,SQL语句中需要的数据先使用占位符?表示,然后在执行前给占位符赋值 String sql = "SELECT * FROM `car`;"; // 4、获取发送SQL语句对象 preparedStatement = connection.prepareStatement(sql); // 5、绑定参数,给?赋值,这里不需要绑定参数 // 6、执行SQL语句 // DML语句:对于插入数据、修改数据、删除数据操作,都调用executeUpdate()方法,返回受影响的行数(int类型) // DQL语句:对于查询数据,调用executeQuery()方法,返回一个结果集(ResultSet类型) resultSet = preparedStatement.executeQuery(); // 7、处理结果,对返回的resultSet结果集进行处理,需要将结果集中的数据取出来 // 查询一条数据时,使用if判断resultSet.next()为true,说明resultSet结果集中有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据。 // 查询所有数据时,使用while循环判断resultSet.next()为true,说明resultSet结果集中还有一条数据,如果resultSet.next()为false,说明resultSet结果集中没有数据了。 while (resultSet.next()) { // 根据记录中字段的索引获取字段数据,字段索引从1开始 int cid = resultSet.getInt(1); String brand = resultSet.getString(2); String type = resultSet.getString(3); String color = resultSet.getString(4); Date birthday=resultSet.getDate(5); String vin = resultSet.getString(6); double price =resultSet.getDouble(7); //使用有参构造方法创建Animal对象 car = new Car(cid, brand, type, color, birthday, vin, price); //将创建的对象添加到集合中 carList.add(car); } //遍历集合,输出所有People对象 for (Car car2 : carList) { System.out.println(car2); } } catch (SQLException e) { e.printStackTrace(); } finally { // 8、释放资源,遵循“先开后关,后开先关”的原则 DBUtils.closeAll(connection, preparedStatement, resultSet); } } }
(1)DAO(Data Access Object) ,数据访问对象,是一个数据访问接口,数据访问:顾名思义就是与数据库打交道。夹在业务逻辑与数据库资源中间。
(2)之前代码中,业务逻辑代码和对数据库的访问操作代码全部写在一个类中,比较混乱,使用DAO实现业务逻辑与数据库访问相分离。
1、创建一张教师表teacher,表的字段如下:
tid,教师编号,主键、自动增长。
name,教师姓名,字符串类型、非空。
age,年龄,int类型、非空。
bornDate,Date类型
email,邮箱,字符串类型,非空
address,住址,字符串类型,非空
CREATE TABLE IF NOT EXISTS `teacher`(
`tid` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(10) NOT NULL,
`age` INT NOT NULL,
`bornDate` DATE,
`email` VARCHAR(30) NOT NULL,
`address` VARCHAR(30) NOT NULL
);
2、向teacher表中插入两条数据:
INSERT INTO `teacher` VALUES(1001,'zhangsan',29,'1993-11-26','1319866976@qq.com','安徽合肥蜀山区长江西路132号');
INSERT INTO `teacher` VALUES(1002,'lisi',31,'1991-9-16','147589641@qq.com','安徽合肥新站区环城西路12号');
创建entity实体类Teacher类,封装属性,添加无参构造方法和有参构造方法,添加getXxx()/setXxx()方法
package com.cxyzxc.www.examples03; /** * entity实体类Teacher类 * */ import java.util.Date; public class Teacher { /** 教师编号 */ private int tid; /** 姓名 */ private String name; /** 年龄 */ private int age; /** 出生日期 */ private Date bornDate; /** 邮箱 */ private String email; /** 住址 */ private String address; // 无参构造方法 public Teacher() { super(); } // 有参构造方法 public Teacher(String name, int age, Date bornDate, String email, String address) { super(); this.name = name; this.age = age; this.bornDate = bornDate; this.email = email; this.address = address; } public Teacher(int tid, String name, int age, Date bornDate, String email, String address) { super(); this.tid = tid; this.name = name; this.age = age; this.bornDate = bornDate; this.email = email; this.address = address; } // getXxx()/setXxx()方法 public int getTid() { return tid; } public void setTid(int tid) { this.tid = tid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getBornDate() { return bornDate; } public void setBornDate(Date bornDate) { this.bornDate = bornDate; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } // 重写Object类中的toString()方法 @Override public String toString() { return "tid=" + tid + ", name=" + name + ", age=" + age + ", bornDate=" + bornDate + ", email=" + email + ", address=" + address; } }
编写TeacherDaoImpl类,提供增删改查方法,使用JDBC完成开发功能。
package com.cxyzxc.www.examples03; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * */ public class TeacherDaoImpl { /* * (1)该类中提供对teacher表进行增、删、改、查单个、查所有5个方法。 * * (2)该类中的代码只做数据库访问操作,不做任何业务逻辑操作。 * * (3)该类只对数据库一张表进行操作,从而实现复用 */ // 新增:向teacher表中插入一条数据(一条数据对应一个Teacher对象),插入成功,返回一个受影响行数值(int类型) public int insert(Teacher teacher) { Connection connection = null; PreparedStatement preparedStatement = null; String sql = "insert into `teacher`(name,age,bornDate,email,address) values(?,?,?,?,?);"; connection = DBUtils.getConnection(); try { preparedStatement = connection.prepareStatement(sql); // 绑定参数,赋值 preparedStatement.setString(1, teacher.getName()); preparedStatement.setInt(2, teacher.getAge()); // 将java.util.Date类型日期时间转换为java.sql.Date类型,然后插入到数据库中 preparedStatement.setDate(3,DateUtils.utilDateToSqlDate(teacher.getBornDate())); preparedStatement.setString(4, teacher.getEmail()); preparedStatement.setString(5, teacher.getAddress()); // 执行SQL语句,返回受影响的行数值 int result = preparedStatement.executeUpdate(); // 将结果返回给调用者 return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } return 0; } // 删除:根据教师tid删除一条数据,删除成功,返回一个受影响行数值(int类型) public int delete(int tid) { Connection connection = null; PreparedStatement preparedStatement = null; String sql = "delete from teacher where tid = ?;"; connection = DBUtils.getConnection(); try { preparedStatement = connection.prepareStatement(sql); // 绑定参数,赋值 preparedStatement.setInt(1, tid); // 执行SQL语句,返回受影响的行数值 int result = preparedStatement.executeUpdate(); // 将结果返回给调用者 return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } return 0; } // 修改:修改teacher表中的数据,可能对任意的一个字段进行修改,所以方法中直接传递一个对象进行修改,修改成功,返回一个受影响行数值(int类型) public int update(Teacher teacher) { Connection connection = null; PreparedStatement preparedStatement = null; String sql = "update teacher set name = ?,age = ?,bornDate = ?,email = ?,address = ? where tid = ?;"; connection = DBUtils.getConnection(); try { preparedStatement = connection.prepareStatement(sql); // 绑定参数,赋值 preparedStatement.setString(1, teacher.getName()); preparedStatement.setInt(2, teacher.getAge()); // 将java.util.Date类型日期时间转换为java.sql.Date类型,然后插入到数据库中 preparedStatement.setDate(3,DateUtils.utilDateToSqlDate(teacher.getBornDate())); preparedStatement.setString(4, teacher.getEmail()); preparedStatement.setString(5, teacher.getAddress()); preparedStatement.setInt(6, teacher.getTid()); // 执行SQL语句,返回受影响的行数值 int result = preparedStatement.executeUpdate(); // 将结果返回给调用者 return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } return 0; } // 查询单个:根据教师tid查询一条数据,查询成功返回一个结果集(ResultSet类型),从结果集中取出元素,封装成一个Teacher对象,将该对象返回 public Teacher select(int tid) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Teacher teacher = null; String sql = "select * from teacher where tid = ?;"; connection = DBUtils.getConnection(); try { preparedStatement = connection.prepareStatement(sql); // 绑定参数,赋值 preparedStatement.setInt(1, tid); resultSet = preparedStatement.executeQuery(); // 处理结果集,因为是查询单个数据,所以不需要循环遍历获取数据,集合中有数据就取出来 if (resultSet.next()) { teacher = new Teacher(); int teacherid = resultSet.getInt("tid"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); Date bornDate = resultSet.getDate("bornDate"); String email = resultSet.getString("email"); String address = resultSet.getString("address"); // 将获取的赋值给teacher对象 teacher.setTid(teacherid); teacher.setName(name); teacher.setAge(age); teacher.setBornDate(bornDate); teacher.setEmail(email); teacher.setAddress(address); } return teacher; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, resultSet); } return null; } // 查询所有:将teacher表中的所有数据全部查询出来,查询成功返回一个结果集(ResultSet类型),从结果集中取出元素,封装成多个Teacher对象,将多个对象存储在集合中,返回这个集合 public List<Teacher> selectAll() { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Teacher teacher = null; List<Teacher> teacherList = new ArrayList<Teacher>(); String sql = "select * from teacher;"; connection = DBUtils.getConnection(); try { preparedStatement = connection.prepareStatement(sql); resultSet = preparedStatement.executeQuery(); // 查询出来多个结果,存在resultSet结果集中,遍历该结果集 while (resultSet.next()) { int teacherid = resultSet.getInt("tid"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); Date bornDate = resultSet.getDate("bornDate"); String email = resultSet.getString("email"); String address = resultSet.getString("address"); teacher = new Teacher(teacherid, name, age, bornDate, email,address); teacherList.add(teacher); } return teacherList; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, resultSet); } return null; } }
package com.cxyzxc.www.examples03; public class TestTeacherDaoImpl01Insert { public static void main(String[] args) { // 创建TteacherDaoImpl类对象 TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl(); // 创建字符串类型的日期 String strDate = "1992-03-22"; // 创建Teacher类对象 // DateUtils.strDateToUtilDate(strDate):将字符串类型的日期时间转换为java.util.Date类型 Teacher teacher = new Teacher("王五", 32,DateUtils.strDateToUtilDate(strDate), "1319866123@qq.com","安徽合肥蜀山区淠河路200号"); // 将teacher对象插入到数据库teacher表中 int result = teacherDaoImpl.insert(teacher); if (result == 1) { System.out.println("数据插入成功"); } else { System.out.println("数据插入失败"); } } }
package com.cxyzxc.www.examples03; public class TestTeacherDaoImpl02Delete { public static void main(String[] args) { // 创建TteacherDaoImpl类对象 TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl(); int result = teacherDaoImpl.delete(1003); if (result == 1) { System.out.println("数据删除成功"); } else { System.out.println("数据删除失败"); } } }
package com.cxyzxc.www.examples03; public class TestTeacherDaoImpl03Update { public static void main(String[] args) { // 创建TteacherDaoImpl类对象 TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl(); //创建字符串类型日期时间 String strDate = "2000-03-22"; // 创建Teacher类对象 //DateUtils.strDateToUtilDate(strDate):将字符串类型的日期时间转换为java.util.Date类型 Teacher teacher = new Teacher(1002,"李四", 22, DateUtils.strDateToUtilDate(strDate), "1319869999@qq.com","安徽合肥蜀山区淠河路19号"); // 将teacher对象插入到数据库teacher表中 int result = teacherDaoImpl.update(teacher); if (result == 1) { System.out.println("数据修改成功"); } else { System.out.println("数据修改败"); } } }
package com.cxyzxc.www.examples03; public class TestTeacherDaoImpl04SelectOne { public static void main(String[] args) { // 创建TteacherDaoImpl类对象 TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl(); Teacher teacher = teacherDaoImpl.select(1001); if (teacher != null) { System.out.println(teacher); } else { System.out.println("没有这个老师"); } } }
package com.cxyzxc.www.examples03; import java.util.List; public class TestTeacherDaoImpl05SelectAll { public static void main(String[] args) { // 创建TteacherDaoImpl类对象 TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl(); List<Teacher> teacherList = teacherDaoImpl.selectAll(); // 遍历teacherList集合 for (Teacher teacher : teacherList) { System.out.println(teacher); } } }
(1)业务即用户完成的一个功能,可以有一个或者多个Dao的调用组成。(软件所提供的一个功能都叫业务)。
(2)你去银行取钱是一个业务,存钱是另一个业务,生活中你做的任何一件事都可以看成是一个业务。有的业务只需要一步就能完成,有的业务需要多个步骤才能完成。
(1)业务需求:
(2)业务逻辑:
CREATE TABLE IF NOT EXISTS `employee`(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(20) NOT NULL,
`age` INT NOT NULL,
`gender` VARCHAR(3),
`bornDate` DATE NOT NULL,
`identityCard` VARCHAR(18) UNIQUE NOT NULL,
`phone` VARCHAR(11) NOT NULL,
`email` VARCHAR(20) NOT NULL,
`address` VARCHAR(30) NOT NULL
);
INSERT INTO `employee` VALUES(1001,'zhangsan',24,'男','1998-12-16','340825199812161316','13845687890','1319866912@qq.com','安徽合肥蜀山区');
INSERT INTO `employee` VALUES(1002,'lisi',25,'男','1997-12-26','340825199712261396','13845682233','1396548732@qq.com','安徽合肥瑶海区');
package com.cxyzxc.www.examples04; import java.util.Date; /** * entity实体类Employee * */ public class Employee { /** 员工编号 */ private int id; /** 姓名 */ private String name; /** 年龄 */ private int age; /** 性别 */ private String gender; /** 出生日期 */ private Date bornDate; /** 身份证号码 */ private String identityCard; /** 手机号码 */ private String phone; /** 邮箱 */ private String email; /** 住址 */ private String address; // 无参构造方法 public Employee() { super(); } // 有参构造方法 public Employee(String name, int age, String gender, Date bornDate, String identityCard, String phone, String email, String address) { super(); this.name = name; this.age = age; this.gender = gender; this.bornDate = bornDate; this.identityCard = identityCard; this.phone = phone; this.email = email; this.address = address; } public Employee(int id, String name, int age, String gender, Date bornDate, String identityCard, String phone, String email, String address) { super(); this.id = id; this.name = name; this.age = age; this.gender = gender; this.bornDate = bornDate; this.identityCard = identityCard; this.phone = phone; this.email = email; this.address = address; } // getXxx()/setXxx()方法 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public Date getBornDate() { return bornDate; } public void setBornDate(Date bornDate) { this.bornDate = bornDate; } public String getIdentityCard() { return identityCard; } public void setIdentityCard(String identityCard) { this.identityCard = identityCard; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } // 重写Object类中的toString()方法 @Override public String toString() { return "id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + ", bornDate=" + bornDate + ", identityCard=" + identityCard + ", phone=" + phone + ", email=" + email + ", address=" + address; } }
package com.cxyzxc.www.examples04; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; public class EmployeeDaoImpl { /* * (1)该类中提供对teacher表进行增、删、改、查单个、查所有5个方法。 * * (2)该类中的代码只做数据库访问操作,不做任何业务逻辑操作。 * * (3)该类只对数据库一张表进行操作,从而实现复用 */ // 新增:向employee表中插入一条数据(一条数据对应一个Employee对象),插入成功,返回一个受影响行数值(int类型) public int insert(Employee employee) { Connection connection = null; PreparedStatement preparedStatement = null; String sql = "insert into `employee`(name,age,gender,bornDate,identityCard,phone,email,address) values(?,?,?,?,?,?,?,?);"; connection = DBUtils.getConnection(); try { preparedStatement = connection.prepareStatement(sql); // 绑定参数,赋值 preparedStatement.setString(1, employee.getName()); preparedStatement.setInt(2, employee.getAge()); preparedStatement.setString(3, employee.getGender()); // 将java.util.Date类型日期时间转换为java.sql.Date类型,然后插入到数据库中 preparedStatement.setDate(4,DateUtils.utilDateToSqlDate(employee.getBornDate())); preparedStatement.setString(5, employee.getIdentityCard()); preparedStatement.setString(6, employee.getPhone()); preparedStatement.setString(7, employee.getEmail()); preparedStatement.setString(8, employee.getAddress()); // 执行SQL语句,返回受影响的行数值 int result = preparedStatement.executeUpdate(); // 将结果返回给调用者 return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } return 0; } // 删除:根据员工id删除一条数据,删除成功,返回一个受影响行数值(int类型) public int delete(int id) { Connection connection = null; PreparedStatement preparedStatement = null; String sql = "delete from employee where id = ?;"; connection = DBUtils.getConnection(); try { preparedStatement = connection.prepareStatement(sql); // 绑定参数,赋值 preparedStatement.setInt(1, id); // 执行SQL语句,返回受影响的行数值 int result = preparedStatement.executeUpdate(); // 将结果返回给调用者 return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } return 0; } // 修改:修改employee表中的数据,可能对任意的一个字段进行修改,所以方法中直接传递一个对象进行修改,修改成功,返回一个受影响行数值(int类型) public int update(Employee employee) { Connection connection = null; PreparedStatement preparedStatement = null; String sql = "update employee set name = ?,age = ?,gender = ?,bornDate = ?,identityCard = ?,phone = ?,email = ?,address = ? where id = ?;"; connection = DBUtils.getConnection(); try { preparedStatement = connection.prepareStatement(sql); // 绑定参数,赋值 // 绑定参数,赋值 preparedStatement.setString(1, employee.getName()); preparedStatement.setInt(2, employee.getAge()); preparedStatement.setString(3, employee.getGender()); // 将java.util.Date类型日期时间转换为java.sql.Date类型,然后插入到数据库中 preparedStatement.setDate(4,DateUtils.utilDateToSqlDate(employee.getBornDate())); preparedStatement.setString(5, employee.getIdentityCard()); preparedStatement.setString(6, employee.getPhone()); preparedStatement.setString(7, employee.getEmail()); preparedStatement.setString(8, employee.getAddress()); preparedStatement.setInt(9, employee.getId()); // 执行SQL语句,返回受影响的行数值 int result = preparedStatement.executeUpdate(); // 将结果返回给调用者 return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } return 0; } // 查询单个:根据员工id查询一条数据,查询成功返回一个结果集(ResultSet类型),从结果集中取出元素,封装成一个Employee对象,将该对象返回 public Employee select(int id) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Employee employee = null; String sql = "select * from employee where id = ?;"; connection = DBUtils.getConnection(); try { preparedStatement = connection.prepareStatement(sql); // 绑定参数,赋值 preparedStatement.setInt(1, id); resultSet = preparedStatement.executeQuery(); // 处理结果集,因为是查询单个数据,所以不需要循环遍历获取数据,集合中有数据就取出来 if (resultSet.next()) { employee = new Employee(); int employeeid = resultSet.getInt("id"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); String gender = resultSet.getString("gender"); Date bornDate = resultSet.getDate("bornDate"); String identityCard = resultSet.getString("identityCard"); String phone = resultSet.getString("phone"); String email = resultSet.getString("email"); String address = resultSet.getString("address"); // 将获取的赋值给teacher对象 employee.setId(employeeid); employee.setName(name); employee.setAge(age); employee.setGender(gender); employee.setBornDate(bornDate); employee.setIdentityCard(identityCard); employee.setPhone(phone); employee.setEmail(email); employee.setAddress(address); } return employee; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } return null; } // 查询单个:根据员工身份证号码查询一条数据,查询成功返回一个结果集(ResultSet类型),从结果集中取出元素,封装成一个Employee对象,将该对象返回 public Employee select(String identityCard) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Employee employee = null; String sql = "select * from employee where identityCard = ?;"; connection = DBUtils.getConnection(); try { preparedStatement = connection.prepareStatement(sql); // 绑定参数,赋值 preparedStatement.setString(1, identityCard); resultSet = preparedStatement.executeQuery(); // 处理结果集,因为是查询单个数据,所以不需要循环遍历获取数据,集合中有数据就取出来 if (resultSet.next()) { employee = new Employee(); int employeeid = resultSet.getInt("id"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); String gender = resultSet.getString("gender"); Date bornDate = resultSet.getDate("bornDate"); String idCard = resultSet.getString("identityCard"); String phone = resultSet.getString("phone"); String email = resultSet.getString("email"); String address = resultSet.getString("address"); // 将获取的赋值给teacher对象 employee.setId(employeeid); employee.setName(name); employee.setAge(age); employee.setGender(gender); employee.setBornDate(bornDate); employee.setIdentityCard(idCard); employee.setPhone(phone); employee.setEmail(email); employee.setAddress(address); } return employee; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } return null; } // 查询所有:将employee表中的所有数据全部查询出来,查询成功返回一个结果集(ResultSet类型),从结果集中取出元素,封装成多个Employee对象,将多个对象存储在集合中,返回这个集合 public List<Employee> selectAll() { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Employee employee = null; List<Employee> employeeList = new ArrayList<Employee>(); String sql = "select * from employee;"; connection = DBUtils.getConnection(); try { preparedStatement = connection.prepareStatement(sql); resultSet = preparedStatement.executeQuery(); // 查询出来多个结果,存在resultSet结果集中,遍历该结果集 while (resultSet.next()) { int employeeid = resultSet.getInt("id"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); String gender = resultSet.getString("gender"); Date bornDate = resultSet.getDate("bornDate"); String identityCard = resultSet.getString("identityCard"); String phone = resultSet.getString("phone"); String email = resultSet.getString("email"); String address = resultSet.getString("address"); employee = new Employee(employeeid, name, age, gender,bornDate, identityCard, phone, email, address); employeeList.add(employee); } return employeeList; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } return null; } }
package com.cxyzxc.www.examples04; public class EmployeeServiceImpl { /* * 注册账号的业务逻辑: * 1、查询你要注册的员工是否存在(根据身份证号码进行查询) * * 2、如果要注册的员工不存在,就注册账号 * * 3、如果注册的员工已经存在,就返回已经注册该员工 */ public void register(Employee employee) { EmployeeDaoImpl employeeDaoImpl = new EmployeeDaoImpl(); // 1、查询你要注册的员工是否存在 Employee emp = employeeDaoImpl.select(employee.getIdentityCard()); // 2、如果要注册的员工不存在(emp为null),就注册账号 if (emp == null) { employeeDaoImpl.insert(employee); System.out.println("员工注册成功(数据插入成功)"); } else { System.out.println("该员工已经注册(数据插入失败)"); } } }
package com.cxyzxc.www.examples04;
public class TestRegister {
public static void main(String[] args) {
EmployeeServiceImpl employeeServiceImpl = new EmployeeServiceImpl();
Employee employee = new Employee("赵六", 30, "男",DateUtils.strDateToUtilDate("1992-11-29"),"340825199211291123", "13877884455", "13877884455@qq.com","安徽合肥肥西");
employeeServiceImpl.register(employee);
}
}
(1)业务需求:
(2)业务逻辑:
CREATE TABLE IF NOT EXISTS `account`(
`cardNo` VARCHAR(20) PRIMARY KEY COMMENT '卡号',
`password` VARCHAR(20) NOT NULL COMMENT '密码',
`name` VARCHAR(20) NOT NULL COMMENT '名称',
`balance` DOUBLE NOT NULL COMMENT '账户余额'
);
INSERT INTO account VALUES('6001','123456','zhangsan',10000);
INSERT INTO account VALUES('6002','123456','lisi',5000);
package com.cxyzxc.www.examples05; /** * entity实体类Account类 * */ public class Account { /** 账号 */ private String cardNo; /** 密码 */ private String password; /** 用户名 */ private String name; /** 账户余额 */ private double balance; // 无参构造方法 public Account() { super(); } // 有参构造方法 public Account(String cardNo, String password, String name, double balance) { super(); this.cardNo = cardNo; this.password = password; this.name = name; this.balance = balance; } // getXxx()/setXxx()方法 public String getCardNo() { return cardNo; } public void setCardNo(String cardNo) { this.cardNo = cardNo; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } // 重写Object类中的toString()方法 @Override public String toString() { return "cardNo=" + cardNo + ", password=" + password + ", name=" + name + ", balance=" + balance; } }
package com.cxyzxc.www.examples05; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class AccountDaoImpl { // 新增:插入一个Account对象到数据库中 public int insert(Account account) { Connection connection = null; PreparedStatement preparedStatement = null; connection = DBUtils.getConnection(); String sql = "insert into account values(?,?,?,?)"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, account.getCardNo()); preparedStatement.setString(2, account.getPassword()); preparedStatement.setString(3, account.getName()); preparedStatement.setDouble(4, account.getBalance()); // 执行SQL int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } return 0; } // 删除:根据卡号,删除账号 public int delete(String cardNo) { Connection connection = null; PreparedStatement preparedStatement = null; connection = DBUtils.getConnection(); String sql = "delete from account where cardNo = ?;"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, cardNo); // 执行SQL int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } return 0; } // 修改 public int update(Account account) { Connection connection = null; PreparedStatement preparedStatement = null; connection = DBUtils.getConnection(); String sql = "update account set password = ?,name = ?,balance = ? where cardNo=?;"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, account.getPassword()); preparedStatement.setString(2, account.getName()); preparedStatement.setDouble(3, account.getBalance()); preparedStatement.setString(4, account.getCardNo()); // 执行SQL int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, null); } return 0; } // 查询单个 public Account select(String cardNo) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Account account = null; connection = DBUtils.getConnection(); String sql = "select * from account where cardNo = ?"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, cardNo); // 执行SQL resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { String cardNumber = resultSet.getString("cardNo"); String password = resultSet.getString("password"); String name = resultSet.getString("name"); double balance = resultSet.getDouble("balance"); account = new Account(cardNumber, password, name, balance); } return account; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, resultSet); } return null; } // 查询所有 public List<Account> selectAll() { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Account account = null; List<Account> accountList = new ArrayList<Account>(); connection = DBUtils.getConnection(); String sql = "select * from account;"; try { preparedStatement = connection.prepareStatement(sql); // 执行SQL resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { String cardNumber = resultSet.getString("cardNo"); String password = resultSet.getString("password"); String name = resultSet.getString("name"); double balance = resultSet.getDouble("balance"); account = new Account(cardNumber, password, name, balance); accountList.add(account); } return accountList; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, preparedStatement, resultSet); } return null; } }
package com.cxyzxc.www.examples05; public class AccountServiceImpl { /** * 转账业务 * * @param fromNo * 转账人账号 * @param password * 转账人账号密码 * @param toNo * 收款人账号 * @param money * 转账金额 */ public void transfer(String fromNo, String password, String toNo, double money) { AccountDaoImpl accountDaoImpl = new AccountDaoImpl(); try { // 1.验证fromNo账号是否存在 Account fromAccount = accountDaoImpl.select(fromNo); if (fromAccount == null) { throw new RuntimeException("卡号不存在"); } // 2.验证fromNo的密码是否正确 if (!fromAccount.getPassword().equals(password)) { throw new RuntimeException("密码错误"); } // 3.验证余额是否充足 if (fromAccount.getBalance() < money) { throw new RuntimeException("余额不足"); } // 4.验证toNo账号是否存在 Account toAccount = accountDaoImpl.select(toNo); if (toAccount == null) { throw new RuntimeException("对方卡号不存在"); } // 5.减少fromNo账号的余额 fromAccount.setBalance(fromAccount.getBalance() - money); accountDaoImpl.update(fromAccount); // 6.增加toNo账号的余额 toAccount.setBalance(toAccount.getBalance() + money); accountDaoImpl.update(toAccount); System.out.println("转账成功"); } catch (Exception e) { System.out.println("转账失败"); e.printStackTrace(); } } }
package com.cxyzxc.www.examples05;
public class TestTransfer {
public static void main(String[] args) {
AccountServiceImpl AccountServiceImpl = new AccountServiceImpl();
AccountServiceImpl.transfer("6001", "123456", "6002", 2000);
}
}
在JDBC中,获得Connection对象来处理事务–提交或回滚事务–关闭连接。其事务策略是:
package com.cxyzxc.www.examples06; import java.sql.Connection; import java.sql.SQLException; public class AccountServiceImpl { /** * 转账业务 * * @param fromNo * 转账人账号 * @param password * 转账人账号密码 * @param toNo * 收款人账号 * @param money * 转账金额 */ public String transfer(String fromNo, String password, String toNo, double money) { String result = "转账失败"; AccountDaoImpl accountDaoImpl = new AccountDaoImpl(); // 创建一个连接对象 Connection connection = null; try { // 获取连接对象 connection = DBUtils.getConnection(); // 开启事务,关闭事务的自动提交,改为手动提交 connection.setAutoCommit(false); // 1.验证fromNo账号是否存在 Account fromAccount = accountDaoImpl.select(fromNo); if (fromAccount == null) { throw new RuntimeException("卡号不存在"); } // 2.验证fromNo的密码是否正确 if (!fromAccount.getPassword().equals(password)) { throw new RuntimeException("密码错误"); } // 3.验证余额是否充足 if (fromAccount.getBalance() < money) { throw new RuntimeException("余额不足"); } // 4.验证toNo账号是否存在 Account toAccount = accountDaoImpl.select(toNo); if (toAccount == null) { throw new RuntimeException("对方卡号不存在"); } // 5.减少fromNo账号的余额 fromAccount.setBalance(fromAccount.getBalance() - money); accountDaoImpl.update(fromAccount); // 程序出现异常 @SuppressWarnings("unused") int num = 10 / 0; // 6.增加toNo账号的余额 toAccount.setBalance(toAccount.getBalance() + money); accountDaoImpl.update(toAccount); // 代码执行到这里,说明转账成功,提交事务 connection.commit(); result = "转账成功"; return result; } catch (Exception e) { e.printStackTrace(); try { // 出现异常,回滚整个事务 System.out.println("出现异常,回滚整个事务,转账失败"); connection.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } } finally { DBUtils.closeAll(connection, null, null); } return result; } }
执行这个代码,观察account表中的数据发现,当程序出现异常,转账账号余额减少了,但是收款账户余额没有增加,事务控制失败了。失败的原因是:
为了解决AccountServiceImpl类中的connection连接对象与AccountDaoImpl类中给各个方法里的connection连接对象是不同步的问题,可以将Connection对象通过service传递给AccountDaoImpl类中的各个方法
AccountDaoImpl类中的每个方法参数列表里都要添加一个Connection类型的参数
package com.cxyzxc.www.examples07; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class AccountDaoImpl { // 新增:插入一个Account对象到数据库中 public int insert(Account account,Connection connection) { PreparedStatement preparedStatement = null; String sql = "insert into account values(?,?,?,?)"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, account.getCardNo()); preparedStatement.setString(2, account.getPassword()); preparedStatement.setString(3, account.getName()); preparedStatement.setDouble(4, account.getBalance()); // 执行SQL int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } finally{ DBUtils.closeAll(null, preparedStatement, null); } return 0; } // 删除:根据卡号,删除账号 public int delete(String cardNo,Connection connection) { PreparedStatement preparedStatement = null; String sql = "delete from account where cardNo = ?;"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, cardNo); // 执行SQL int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } finally{ DBUtils.closeAll(null, preparedStatement, null); } return 0; } // 修改 public int update(Account account,Connection connection) { PreparedStatement preparedStatement = null; String sql = "update account set password = ?,name = ?,balance = ? where cardNo=?;"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, account.getPassword()); preparedStatement.setString(2, account.getName()); preparedStatement.setDouble(3, account.getBalance()); preparedStatement.setString(4, account.getCardNo()); // 执行SQL int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); }finally{ DBUtils.closeAll(null, preparedStatement, null); } return 0; } // 查询单个 public Account select(String cardNo,Connection connection) { PreparedStatement preparedStatement = null; ResultSet resultSet = null; Account account = null; String sql = "select * from account where cardNo = ?"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, cardNo); // 执行SQL resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { String cardNumber = resultSet.getString("cardNo"); String password = resultSet.getString("password"); String name = resultSet.getString("name"); double balance = resultSet.getDouble("balance"); account = new Account(cardNumber, password, name, balance); } return account; } catch (SQLException e) { e.printStackTrace(); }finally{ DBUtils.closeAll(null, preparedStatement, resultSet); } return null; } // 查询所有 public List<Account> selectAll(Connection connection) { PreparedStatement preparedStatement = null; ResultSet resultSet = null; Account account = null; List<Account> accountList = new ArrayList<Account>(); String sql = "select * from account;"; try { preparedStatement = connection.prepareStatement(sql); // 执行SQL resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { String cardNumber = resultSet.getString("cardNo"); String password = resultSet.getString("password"); String name = resultSet.getString("name"); double balance = resultSet.getDouble("balance"); account = new Account(cardNumber, password, name, balance); accountList.add(account); } return accountList; } catch (SQLException e) { e.printStackTrace(); }finally{ DBUtils.closeAll(null, preparedStatement, resultSet); } return null; } }
package com.cxyzxc.www.examples07; import java.sql.Connection; import java.sql.SQLException; public class AccountServiceImpl { /** * 转账业务 * * @param fromNo * 转账人账号 * @param password * 转账人账号密码 * @param toNo * 收款人账号 * @param money * 转账金额 */ public String transfer(String fromNo, String password, String toNo, double money) { String result = "转账失败"; AccountDaoImpl accountDaoImpl = new AccountDaoImpl(); // 创建一个连接对象 Connection connection = null; try { // 获取连接对象 connection = DBUtils.getConnection(); // 开启事务,关闭事务的自动提交,改为手动提交 connection.setAutoCommit(false); // 1.验证fromNo账号是否存在 Account fromAccount = accountDaoImpl.select(fromNo, connection); if (fromAccount == null) { throw new RuntimeException("卡号不存在"); } // 2.验证fromNo的密码是否正确 if (!fromAccount.getPassword().equals(password)) { throw new RuntimeException("密码错误"); } // 3.验证余额是否充足 if (fromAccount.getBalance() < money) { throw new RuntimeException("余额不足"); } // 4.验证toNo账号是否存在 Account toAccount = accountDaoImpl.select(toNo, connection); if (toAccount == null) { throw new RuntimeException("对方卡号不存在"); } // 5.减少fromNo账号的余额 fromAccount.setBalance(fromAccount.getBalance() - money); accountDaoImpl.update(fromAccount, connection); // 程序出现异常 @SuppressWarnings("unused") int num = 10 / 0; // 6.增加toNo账号的余额 toAccount.setBalance(toAccount.getBalance() + money); accountDaoImpl.update(toAccount, connection); // 代码执行到这里,说明转账成功,提交事务 connection.commit(); result = "转账成功"; return result; } catch (Exception e) { e.printStackTrace(); try { // 出现异常,回滚整个事务 System.out.println("出现异常,回滚整个事务,转账失败"); connection.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } } finally { DBUtils.closeAll(connection, null, null); } return result; } }
测试发现,这种方法可以解决service层控制事务失败的问题。
(1)如果使用传递Connection,更容易造成接口污染(BadSmell)。
(2)定义接口是为了更容易更换实现,而将Connection定义在接口中(XxxDao接口,XXXDaoImpl实现XxxDao接口)中,会造成污染当前接口。因为在当前代码中连接对象叫Connection,而在其它数据库连接框架中,连接对象不叫Connection(Mybatis框架中数据库连接对象叫SqlSession,Hibernate框架中数据库连接对象叫session),这时候,你需要重新定义接口,重新传递连接对象。
(1)在整个线程中(单线程),存储一个共享值(Connection对象)。
(2)线程类中拥有一个类似Map的属性(),以键值对的结构<ThreadLocal对象,值>存储数据。
一个线程中所有的操作共享一个ThreadLocal,ThreadLocal里存储的是Connection连接对象,在整个操作流程中任何一个操作环节都可以设置或者获取值。
在DBUtils类中,将当前Connection对象添加到ThreadLocal中。其它类代码保持不变。
package com.cxyzxc.www.examples08; import java.io.IOException; import java.io.InputStream; import java.sql.*; import java.util.Properties; /** * 跨平台方案 注册驱动 获取连接 释放资源 * */ public class DBUtils { // 读取配置文件的Map private static final Properties PROPERTIES = new Properties(); // 声明一个ThreadLocal<Connection>对象用来存储数据库连接对象 private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); static { // 通过复用本类自带流,读取配置文件中的数据 InputStream is = DBUtils.class.getResourceAsStream("/db.properties"); try { // 通过prop对象将流中的配置信息分隔成键值对,将配置文件内容加载到properties集合 PROPERTIES.load(is); // 注册驱动,通过driverName的键获取对应的值(com.mysql.jdbc.Driver) Class.forName(PROPERTIES.getProperty("driver")); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } // 获取连接对象 public static Connection getConnection() { // 将当前线程中绑定的Connection对象赋值给connection变量 Connection connection = threadLocal.get(); try { // 如果连接对象为null,则创建一个连接对象 if (connection == null) { connection = DriverManager.getConnection( PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password")); // 将创建的连接对象存储到当前线程中共享 threadLocal.set(connection); } } catch (SQLException e) { e.printStackTrace(); } return connection; } // 释放所有资源 public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) { try { if (resultSet != null) { resultSet.close(); } if (statement != null) { statement.close(); } if (connection != null) { connection.close(); // 将connection从threadLocal中移除 threadLocal.remove(); } } catch (SQLException e) { e.printStackTrace(); } } }
package com.cxyzxc.www.examples08; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class AccountDaoImpl { // 新增:插入一个Account对象到数据库中 public int insert(Account account) { Connection connection = null; PreparedStatement preparedStatement = null; connection = DBUtils.getConnection(); String sql = "insert into account values(?,?,?,?)"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, account.getCardNo()); preparedStatement.setString(2, account.getPassword()); preparedStatement.setString(3, account.getName()); preparedStatement.setDouble(4, account.getBalance()); // 执行SQL int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(null, preparedStatement, null); } return 0; } // 删除:根据卡号,删除账号 public int delete(String cardNo) { Connection connection = null; PreparedStatement preparedStatement = null; connection = DBUtils.getConnection(); String sql = "delete from account where cardNo = ?;"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, cardNo); // 执行SQL int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(null, preparedStatement, null); } return 0; } // 修改 public int update(Account account) { Connection connection = null; PreparedStatement preparedStatement = null; connection = DBUtils.getConnection(); String sql = "update account set password = ?,name = ?,balance = ? where cardNo=?;"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, account.getPassword()); preparedStatement.setString(2, account.getName()); preparedStatement.setDouble(3, account.getBalance()); preparedStatement.setString(4, account.getCardNo()); // 执行SQL int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(null, preparedStatement, null); } return 0; } // 查询单个 public Account select(String cardNo) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Account account = null; connection = DBUtils.getConnection(); String sql = "select * from account where cardNo = ?"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, cardNo); // 执行SQL resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { String cardNumber = resultSet.getString("cardNo"); String password = resultSet.getString("password"); String name = resultSet.getString("name"); double balance = resultSet.getDouble("balance"); account = new Account(cardNumber, password, name, balance); } return account; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(null, preparedStatement, resultSet); } return null; } // 查询所有 public List<Account> selectAll() { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Account account = null; List<Account> accountList = new ArrayList<Account>(); connection = DBUtils.getConnection(); String sql = "select * from account;"; try { preparedStatement = connection.prepareStatement(sql); // 执行SQL resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { String cardNumber = resultSet.getString("cardNo"); String password = resultSet.getString("password"); String name = resultSet.getString("name"); double balance = resultSet.getDouble("balance"); account = new Account(cardNumber, password, name, balance); accountList.add(account); } return accountList; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(null, preparedStatement, resultSet); } return null; } }
package com.cxyzxc.www.examples08; import java.sql.Connection; import java.sql.SQLException; public class AccountServiceImpl { /** * 转账业务 * * @param fromNo * 转账人账号 * @param password * 转账人账号密码 * @param toNo * 收款人账号 * @param money * 转账金额 */ public String transfer(String fromNo, String password, String toNo, double money) { String result = "转账失败"; AccountDaoImpl accountDaoImpl = new AccountDaoImpl(); // 创建一个连接对象 Connection connection = null; try { // 获取连接对象 connection = DBUtils.getConnection(); // 开启事务,关闭事务的自动提交,改为手动提交 connection.setAutoCommit(false); // 1.验证fromNo账号是否存在 Account fromAccount = accountDaoImpl.select(fromNo); if (fromAccount == null) { throw new RuntimeException("卡号不存在"); } // 2.验证fromNo的密码是否正确 if (!fromAccount.getPassword().equals(password)) { throw new RuntimeException("密码错误"); } // 3.验证余额是否充足 if (fromAccount.getBalance() < money) { throw new RuntimeException("余额不足"); } // 4.验证toNo账号是否存在 Account toAccount = accountDaoImpl.select(toNo); if (toAccount == null) { throw new RuntimeException("对方卡号不存在"); } // 5.减少fromNo账号的余额 fromAccount.setBalance(fromAccount.getBalance() - money); accountDaoImpl.update(fromAccount); // 程序出现异常 @SuppressWarnings("unused") int num = 10 / 0; // 6.增加toNo账号的余额 toAccount.setBalance(toAccount.getBalance() + money); accountDaoImpl.update(toAccount); // 代码执行到这里,说明转账成功,提交事务 connection.commit(); result = "转账成功"; return result; } catch (Exception e) { e.printStackTrace(); try { // 出现异常,回滚整个事务 System.out.println("出现异常,回滚整个事务,转账失败"); connection.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } } finally { DBUtils.closeAll(connection, null, null); } return result; } }
(1)XXXDaoImpl类是专门用来操作数据表的,在这个类中只存在对数据表增删改查的方法,没有其它的内容。这是我们需要的。但是在XXXServiceImpl类中,既有业务需求,还有获取数据库连接对象以及释放资源的代码,在XXXServiceImpl类中,应该只有业务逻辑需求,除此,没有其它操作代码,这才是我们需要的。
(2)因此我们需要将对事务的开启、提交、回滚都封装到DBUtils工具类中。业务层调用DBUtils类中的与事务相关的代码即可。
package com.cxyzxc.www.examples09; import java.io.IOException; import java.io.InputStream; import java.sql.*; import java.util.Properties; /** * 跨平台方案 注册驱动 获取连接 释放资源 * */ public class DBUtils { // 读取配置文件的Map private static final Properties PROPERTIES = new Properties(); // 声明一个ThreadLocal<Connection>对象用来存储数据库连接对象 private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); static { // 通过复用本类自带流,读取配置文件中的数据 InputStream is = DBUtils.class.getResourceAsStream("/db.properties"); try { // 通过prop对象将流中的配置信息分隔成键值对,将配置文件内容加载到properties集合 PROPERTIES.load(is); // 注册驱动,通过driverName的键获取对应的值(com.mysql.jdbc.Driver) Class.forName(PROPERTIES.getProperty("driver")); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } // 获取连接对象 public static Connection getConnection() { // 将当前线程中绑定的Connection对象赋值给connection变量 Connection connection = threadLocal.get(); try { // 如果连接对象为null,则创建一个连接对象 if (connection == null) { connection = DriverManager.getConnection( PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password")); // 将创建的连接对象存储到当前线程中共享 threadLocal.set(connection); } } catch (SQLException e) { e.printStackTrace(); } return connection; } // 释放所有资源 public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) { try { if (resultSet != null) { resultSet.close(); } if (statement != null) { statement.close(); } if (connection != null) { connection.close(); // 将connection从threadLocal中移除 threadLocal.remove(); } } catch (SQLException e) { e.printStackTrace(); } } // 3、开启事务 public static void startTransaction() { Connection connection = null; try { connection = getConnection(); connection.setAutoCommit(false); } catch (SQLException e) { e.printStackTrace(); } } // 4、提交事务 public static void commitTransaction() { Connection connection = getConnection(); try { connection.commit(); } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, null, null); } } // 5、回滚事务 public static void rollbackTransaction() { Connection connection = getConnection(); try { connection.rollback(); } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, null, null); } } }
package com.cxyzxc.www.examples09; public class AccountServiceImpl { /** * 转账业务 * * @param fromNo * 转账人账号 * @param password * 转账人账号密码 * @param toNo * 收款人账号 * @param money * 转账金额 */ public String transfer(String fromNo, String password, String toNo, double money) { String result = "转账失败"; AccountDaoImpl accountDaoImpl = new AccountDaoImpl(); try { // 开启事务,关闭事务的自动提交,改为手动提交 DBUtils.startTransaction(); // 1.验证fromNo账号是否存在 Account fromAccount = accountDaoImpl.select(fromNo); if (fromAccount == null) { throw new RuntimeException("卡号不存在"); } // 2.验证fromNo的密码是否正确 if (!fromAccount.getPassword().equals(password)) { throw new RuntimeException("密码错误"); } // 3.验证余额是否充足 if (fromAccount.getBalance() < money) { throw new RuntimeException("余额不足"); } // 4.验证toNo账号是否存在 Account toAccount = accountDaoImpl.select(toNo); if (toAccount == null) { throw new RuntimeException("对方卡号不存在"); } // 5.减少fromNo账号的余额 fromAccount.setBalance(fromAccount.getBalance() - money); accountDaoImpl.update(fromAccount); // 程序出现异常 @SuppressWarnings("unused") int num = 10 / 0; // 6.增加toNo账号的余额 toAccount.setBalance(toAccount.getBalance() + money); accountDaoImpl.update(toAccount); // 代码执行到这里,说明转账成功,提交事务 DBUtils.commitTransaction(); result = "转账成功"; return result; } catch (Exception e) { e.printStackTrace(); // 出现异常,回滚整个事务 System.out.println("出现异常,回滚整个事务,转账失败"); DBUtils.rollbackTransaction(); } return result; } }
(1)表示层(View)
(2)业务逻辑层(service)
(3)数据访问层(Dao)
1)新建一个项目,在项目中创建lib文件夹,将MySQL数据库jar包放在lib文件夹中,配置环境。
2)在src文件夹下面创建db.properties文件,编写数据库driver、url、user、password信息。
3)创建三层需要的各个包。
(1)utils包:存放工具类(DBUtils类、DateUtils类)
(2)entity包:存放实体类(Xxx.java)
(3)dao包:存放DAO接口
impl包:存放DAO接口实现类
(4)service包:存放service接口
impl:存放service接口实现类
(5)view包:存放程序启动类或测试类(main)
CREATE TABLE IF NOT EXISTS `book`(
`bid` INT PRIMARY KEY AUTO_INCREMENT COMMENT '图书编号',
`isbn` VARCHAR(20) UNIQUE NOT NULL COMMENT '国际标准书号',
`name` VARCHAR(20) NOT NULL COMMENT '书名',
`author` VARCHAR(20) NOT NULL COMMENT '作者',
`press` VARCHAR(20) NOT NULL COMMENT '出版社',
`price` DOUBLE NOT NULL COMMENT '价格',
`classification` VARCHAR(20) NOT NULL COMMENT '分类'
);
INSERT INTO `book`(`bid`,`isbn`,`name`,`author`,`press`,`price`,`classification`)
VALUES
(1001,'978-7-5170-7654-4','SQL从入门到精通','张三','中国水利水电出版社',79.80,'数据库');
INSERT INTO `book`(`bid`,`isbn`,`name`,`author`,`press`,`price`,`classification`)
VALUES
(1002,'976-9-5245-7633-5','java从入门到精通','李四','清华大学出版社',99.80,'程序设计');
package com.cxyzxc.www.entity; import java.util.Date; /** * entity实体类Booke类 * */ public class Book { /** 图书编号 */ private int bid; /** 国际标准书号 */ private String isbn; /** 书名 */ private String name; /** 作者 */ private String author; /** 出版社 */ private String press; /** 价格 */ private double price; /** 分类 */ private String classification; /** 出版日期 */ private Date pubdate; public Book() { super(); } public Book(String isbn, String name, String author, String press, double price, String classification, Date pubdate) { super(); this.isbn = isbn; this.name = name; this.author = author; this.press = press; this.price = price; this.classification = classification; this.pubdate = pubdate; } public Book(int bid, String isbn, String name, String author, String press, double price, String classification, Date pubdate) { super(); this.bid = bid; this.isbn = isbn; this.name = name; this.author = author; this.press = press; this.price = price; this.classification = classification; this.pubdate = pubdate; } public int getBid() { return bid; } public void setBid(int bid) { this.bid = bid; } public String getIsbn() { return isbn; } public void setIsbn(String isbn) { this.isbn = isbn; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getPress() { return press; } public void setPress(String press) { this.press = press; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getClassification() { return classification; } public void setClassification(String classification) { this.classification = classification; } public Date getPubdate() { return pubdate; } public void setPubdate(Date pubdate) { this.pubdate = pubdate; } @Override public String toString() { return "Book [bid=" + bid + ", isbn=" + isbn + ", name=" + name + ", author=" + author + ", press=" + press + ", price=" + price + ", classification=" + classification + ", pubdate=" + pubdate + "]"; } }
package com.cxyzxc.www.dao; import java.util.List; import com.cxyzxc.www.entity.Book; /** * 定义BookDao接口,接口中定义对book表增删改查的方法 * */ public interface BookDao { //增 int insert(Book book); //删 int delete(int bid); //改 int update(Book book); //查单个 Book selectOne(int bid); //查所有 List<Book> selectAll(); }
package com.cxyzxc.www.dao.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.cxyzxc.www.dao.BookDao; import com.cxyzxc.www.entity.Book; import com.cxyzxc.www.utils.DBUtils; import com.cxyzxc.www.utils.DateUtils; /** * 定义BookDaoImpl类,实现BookDao接口,重写接口中的增删改查方法 * */ public class BookDaoImpl implements BookDao { @Override public int insert(Book book) { Connection connection = null; PreparedStatement preparedStatement = null; connection = DBUtils.getConnection(); String sql = "INSERT INTO `book`(`isbn`,`name`,`author`,`press`,`price`,`classification`,`pubdate`)VALUES(?,?,?,?,?,?,?);"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, book.getIsbn()); preparedStatement.setString(2, book.getName()); preparedStatement.setString(3, book.getAuthor()); preparedStatement.setString(4, book.getPress()); preparedStatement.setDouble(5, book.getPrice()); preparedStatement.setString(6, book.getClassification()); preparedStatement.setDate(7, DateUtils.utilDateToSqlDate(book.getPubdate())); int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } return 0; } @Override public int delete(int bid) { Connection connection = null; PreparedStatement preparedStatement = null; connection = DBUtils.getConnection(); String sql = "DELETE FROM `book` WHERE `bid`=?;"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setInt(1, bid); int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } return 0; } @Override public int update(Book book) { Connection connection = null; PreparedStatement preparedStatement = null; connection = DBUtils.getConnection(); String sql = "UPDATE `book` SET `isbn`=?,`name`=?,`author`=?,`press`=?,`price`=?,`classification`=?,`pubdate`=? WHERE `bid`=?;"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setString(1, book.getIsbn()); preparedStatement.setString(2, book.getName()); preparedStatement.setString(3, book.getAuthor()); preparedStatement.setString(4, book.getPress()); preparedStatement.setDouble(5, book.getPrice()); preparedStatement.setString(6, book.getClassification()); preparedStatement.setDate(7, DateUtils.utilDateToSqlDate(book.getPubdate())); preparedStatement.setDouble(8, book.getBid()); int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } return 0; } @Override public Book selectOne(int bid) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Book book = null; connection = DBUtils.getConnection(); String sql = "Select * FROM `book` WHERE `bid`=?;"; try { preparedStatement = connection.prepareStatement(sql); // 绑定参数 preparedStatement.setInt(1, bid); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { int bookid = resultSet.getInt(1); String isbn = resultSet.getString(2); String name = resultSet.getString(3); String author = resultSet.getString(4); String press = resultSet.getString(5); double price = resultSet.getDouble(6); String classification = resultSet.getString(7); Date pubdate = resultSet.getDate(8); book = new Book(bookid, isbn, name, author, press, price, classification, pubdate); } return book; } catch (SQLException e) { e.printStackTrace(); } return null; } @Override public List<Book> selectAll() { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; Book book = null; List<Book> bookList = new ArrayList<Book>(); connection = DBUtils.getConnection(); String sql = "Select * FROM `book`;"; try { preparedStatement = connection.prepareStatement(sql); resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { int bookid = resultSet.getInt(1); String isbn = resultSet.getString(2); String name = resultSet.getString(3); String author = resultSet.getString(4); String press = resultSet.getString(5); double price = resultSet.getDouble(6); String classification = resultSet.getString(7); Date pubdate = resultSet.getDate(8); book = new Book(bookid, isbn, name, author, press, price, classification, pubdate); bookList.add(book); } return bookList; } catch (SQLException e) { e.printStackTrace(); } return null; } }
package com.cxyzxc.www.service; import java.util.List; import com.cxyzxc.www.entity.Book; /** * 定义BookService接口,接口中定义业务逻辑方法 * */ public interface BookService { //添加图书 int addBook(Book book); //删除图书 int deleteBook(int bid); //修改图书 int updateBook(Book book); //查询一本图书 Book selectOne(int bid); //查询所有图书 List<Book> selectAll(); }
package com.cxyzxc.www.service.impl; import java.util.List; import com.cxyzxc.www.dao.BookDao; import com.cxyzxc.www.dao.impl.BookDaoImpl; import com.cxyzxc.www.entity.Book; import com.cxyzxc.www.service.BookService; /** * 定义BookServiceImpl类,实现BookService接口,重写BookService接口中的所有方法 * */ public class BookServiceImpl implements BookService { BookDao bookDao = new BookDaoImpl(); @Override public int addBook(Book book) { // 首先查询一下插入的图书在数据库中是否存在 Book book2 = bookDao.selectOne(book.getBid()); if (book2 == null) { return bookDao.insert(book); } else { System.out.println("插入的图书已经存在,插入失败"); } return 0; } @Override public int deleteBook(int bid) { // 查询要删除的图书是否存在 Book book2 = bookDao.selectOne(bid); if (book2 == null) { System.out.println("删除的图书不存在,无法删除"); } else { return bookDao.delete(bid); } return 0; } @Override public int updateBook(Book book) { // 查询要修改的图书是否存在 Book book2 = bookDao.selectOne(book.getBid()); if (book2 == null) { System.out.println("你要修改的图书不存在"); } else { return bookDao.update(book); } return 0; } @Override public Book selectOne(int bid) { Book book2 = bookDao.selectOne(bid); return book2; } @Override public List<Book> selectAll() { List<Book> bookList = bookDao.selectAll(); return bookList; } }
package com.cxyzxc.www.view; import com.cxyzxc.www.entity.Book; import com.cxyzxc.www.service.BookService; import com.cxyzxc.www.service.impl.BookServiceImpl; import com.cxyzxc.www.utils.DateUtils; public class Test01InsertBook { public static void main(String[] args) { BookService bookService = new BookServiceImpl(); // 添加图书 Book book = new Book("978-9-9456-3286-9", "JSP从入门到精通", "李二狗", "邮电出版社",129, "编程设计", DateUtils.strDateToUtilDate("2022-01-13")); int result = bookService.addBook(book); if (result == 1) { System.out.println("图书添加成功"); } else { System.out.println("图书添加失败"); } } }
package com.cxyzxc.www.view; import com.cxyzxc.www.service.BookService; import com.cxyzxc.www.service.impl.BookServiceImpl; public class Test02DeleteBook { public static void main(String[] args) { BookService bookService = new BookServiceImpl(); // 删除图书 int result = bookService.deleteBook(1003); if (result == 1) { System.out.println("删除成功"); } else { System.out.println("删除失败"); } } }
package com.cxyzxc.www.view; import com.cxyzxc.www.entity.Book; import com.cxyzxc.www.service.BookService; import com.cxyzxc.www.service.impl.BookServiceImpl; import com.cxyzxc.www.utils.DateUtils; public class Test03UpdateBook { public static void main(String[] args) { BookService bookService = new BookServiceImpl(); // //修改图书 Book book = new Book(1002, "976-9-5245-7633-5", "JSP从入门到放弃", "李四","清华大学出版社", 109.8, "编程设计",DateUtils.strDateToUtilDate("2022-10-13")); int result = bookService.updateBook(book); if (result == 1) { System.out.println("修改成功"); } else { System.out.println("修改失败"); } } }
package com.cxyzxc.www.view; import com.cxyzxc.www.entity.Book; import com.cxyzxc.www.service.BookService; import com.cxyzxc.www.service.impl.BookServiceImpl; public class Test04SelectOneBook { public static void main(String[] args) { BookService bookService = new BookServiceImpl(); Book book = bookService.selectOne(1003); if (book == null) { System.out.println("没有你要查找的图书"); } else { System.out.println(book); } } }
package com.cxyzxc.www.view; import java.util.List; import com.cxyzxc.www.entity.Book; import com.cxyzxc.www.service.BookService; import com.cxyzxc.www.service.impl.BookServiceImpl; public class Test05SelectAllBook { public static void main(String[] args) { BookService bookService = new BookServiceImpl(); List<Book> books = bookService.selectAll(); if (books.isEmpty()) { System.out.println("数据库里没有书的数据"); } else { for (int i = 0; i < books.size(); i++) { System.out.println(books.get(i)); } } } }
在Dao层的DaoImpl类中,对数据表进行的增、删、改、查操作方法中存在很多相同的代码,可以将这些相同的代码抽取出来封装到一个类中,形成DaoUtils工具类,实现复用。以查询teacher表为例。
该方法是对数据表进行增、删、改的公共方法。
// 增、删、改三个方法封装成一个方法 public int commonsUpdate(String sql, Object... args) { Connection connection = null; PreparedStatement preparedStatement = null; // 获取数据库连接对象 connection = DBUtils.getConnection(); try { // 获取SQL语句发送对象 preparedStatement = connection.prepareStatement(sql); if (args != null) { // 绑定参数 for (int i = 0; i < args.length; i++) { preparedStatement.setObject(i + 1, args[i]); } } // 执行SQL语句 int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(null, preparedStatement, null); } return 0; }
该方法是对数据表进行查询的公共方法,可以查询一条数据,也可以查询多条数据。不管是查询一条数据还是查询多条数据,都将查询到的数据封装到Object类型的集合中。
public List<Object> commonsSelect(String sql,RowMapper rowMapper, Object... args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; List<Object> objectList = new ArrayList<Object>(); // 获取数据库连接对象 connection = DBUtils.getConnection(); try { // 获取SQL语句发送对象 preparedStatement = connection.prepareStatement(sql); if (args != null) { // 绑定参数 for (int i = 0; i < args.length; i++) { preparedStatement.setObject(i + 1, args[i]); } } // 执行SQL语句 resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { Object object = rowMapper.getRow(resultSet); objectList.add(object); } return objectList; } catch (SQLException e) { e.printStackTrace(); }finally { DBUtils.closeAll(null, preparedStatement, resultSet); } return null; }
使用查询方法从表中查询出来的结果存储在ResultSet结果集中,需要从ResultSet结果集中遍历出数据封装成对应对象,然后将封装出来的对象返回给DaoImpl类使用。这个封装的过程由RowMapper类完成。
package com.cxyzxc.www.examples01; /** * 数据封装类,专门用来处理查询返回的resultSet结果集 * * 针对每一个实体类,封装一个RowMapper类 */ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; public class RowMapper { public static Object getRow(ResultSet resultSet){ Teacher teacher = null; try { //返回的结果集中有哪些字段,RowMapper类是知道的,因为他是实体类的封装类 int tid = resultSet.getInt("tid"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); Date bornDate = resultSet.getDate("bornDate"); String email = resultSet.getString("email"); String address = resultSet.getString("address"); teacher = new Teacher(tid, name, age, bornDate, email, address); return teacher; } catch (SQLException e) { e.printStackTrace(); } return null; } }
综合案例完全按照三层架构实现,创建不同的包存放不同的接口、实现类、工具类、测试类等代码。使用数据库中的teacher表来完成综合案例。
该包用来存放项目开发所需要的数据库连接工具类DBUtils类、日期时间转换工具类DateUtils类,数据库操作工具类DaoUtils类
package com.cxyzxc.www.utils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import com.cxyzxc.www.advanced.RowMapper; public class DaoUtils { // 增、删、改三个方法封装成一个方法 public int commonsUpdate(String sql, Object... args) { Connection connection = null; PreparedStatement preparedStatement = null; // 获取数据库连接对象 connection = DBUtils.getConnection(); try { // 获取SQL语句发送对象 preparedStatement = connection.prepareStatement(sql); if (args != null) { // 绑定参数 for (int i = 0; i < args.length; i++) { preparedStatement.setObject(i + 1, args[i]); } } // 执行SQL语句 int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(null, preparedStatement, null); } return 0; } public List<Object> commonsSelect(String sql,RowMapper rowMapper, Object... args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; List<Object> objectList = new ArrayList<Object>(); // 获取数据库连接对象 connection = DBUtils.getConnection(); try { // 获取SQL语句发送对象 preparedStatement = connection.prepareStatement(sql); if (args != null) { // 绑定参数 for (int i = 0; i < args.length; i++) { preparedStatement.setObject(i + 1, args[i]); } } // 执行SQL语句 resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { Object object = rowMapper.getRow(resultSet); objectList.add(object); } return objectList; } catch (SQLException e) { e.printStackTrace(); }finally { DBUtils.closeAll(null, preparedStatement, resultSet); } return null; } }
package com.cxyzxc.www.utils; import java.io.IOException; import java.io.InputStream; import java.sql.*; import java.util.Properties; /** * 跨平台方案 注册驱动 获取连接 释放资源 * * @author 程序员张小厨 * */ public class DBUtils { // 读取配置文件的Map private static final Properties PROPERTIES = new Properties(); // 声明一个ThreadLocal<Connection>对象用来存储数据库连接对象 private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); static { // 通过复用本类自带流,读取配置文件中的数据 InputStream is = DBUtils.class.getResourceAsStream("/db.properties"); try { // 通过prop对象将流中的配置信息分隔成键值对,将配置文件内容加载到properties集合 PROPERTIES.load(is); // 注册驱动,通过driverName的键获取对应的值(com.mysql.jdbc.Driver) Class.forName(PROPERTIES.getProperty("driver")); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } // 获取连接对象 public static Connection getConnection() { // 将当前线程中绑定的Connection对象赋值给connection变量 Connection connection = threadLocal.get(); try { // 如果连接对象为null,则创建一个连接对象 if (connection == null) { connection = DriverManager.getConnection( PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password")); // 将创建的连接对象存储到当前线程中共享 threadLocal.set(connection); } } catch (SQLException e) { e.printStackTrace(); } return connection; } // 释放所有资源 public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) { try { if (resultSet != null) { resultSet.close(); } if (statement != null) { statement.close(); } if (connection != null) { connection.close(); // 将connection从threadLocal中移除 threadLocal.remove(); } } catch (SQLException e) { e.printStackTrace(); } } // 3、开启事务 public static void startTransaction() { Connection connection = null; try { connection = getConnection(); connection.setAutoCommit(false); } catch (SQLException e) { e.printStackTrace(); } } // 4、提交事务 public static void commitTransaction() { Connection connection = getConnection(); try { connection.commit(); } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, null, null); } } // 5、回滚事务 public static void rollbackTransaction() { Connection connection = getConnection(); try { connection.rollback(); } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(connection, null, null); } } }
package com.cxyzxc.www.utils; import java.text.ParseException; import java.text.SimpleDateFormat; /** * 日期时间工具类DateUtils */ public class DateUtils { private static final SimpleDateFormat SIMPLEDATEFORMAT = new SimpleDateFormat("yyyy-MM-dd"); // 字符串转换为java.util.Date类型日期时间 public static java.util.Date strDateToUtilDate(String strDate) { try { return SIMPLEDATEFORMAT.parse(strDate); } catch (ParseException e) { e.printStackTrace(); } return null; } // java.util.Date类型日期时间转换为java.sql.Date类型日期时间 public static java.sql.Date utilDateToSqlDate(java.util.Date date) { // long date.getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT以来此 Date对象表示的毫秒数 return new java.sql.Date(date.getTime()); } // java.util.Date类转换为字符串类型 public static String utilDateToString(java.util.Date date) { return SIMPLEDATEFORMAT.format(date); } }
该包用来存储实体类,根据teacher表创建实体类Teacher类
package com.cxyzxc.www.entity; import java.util.Date; public class Teacher { /** 教师编号 */ private int tid; /** 姓名 */ private String name; /** 年龄 */ private int age; /** 出生日期 */ private Date bornDate; /** 邮箱 */ private String email; /** 住址 */ private String address; // 无参构造方法 public Teacher() { super(); } // 有参构造方法 public Teacher(String name, int age, Date bornDate, String email, String address) { super(); this.name = name; this.age = age; this.bornDate = bornDate; this.email = email; this.address = address; } public Teacher(int tid, String name, int age, Date bornDate, String email, String address) { super(); this.tid = tid; this.name = name; this.age = age; this.bornDate = bornDate; this.email = email; this.address = address; } // getXxx()/setXxx()方法 public int getTid() { return tid; } public void setTid(int tid) { this.tid = tid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getBornDate() { return bornDate; } public void setBornDate(Date bornDate) { this.bornDate = bornDate; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } // 重写Object类中的toString()方法 @Override public String toString() { return "tid=" + tid + ", name=" + name + ", age=" + age + ", bornDate=" + bornDate + ", email=" + email + ", address=" + address; } }
该包中存放RowMapper接口,用来约束封装对象的ORM
package com.cxyzxc.www.advanced;
import java.sql.ResultSet;
/**
* 该接口用来约束封装对象的ORM
*
*/
public interface RowMapper {
Object getRow(ResultSet resultSet);
}
package com.cxyzxc.www.advanced.impl; /** * 数据封装类,专门用来处理查询返回的resultSet结果集 * * 针对每一个实体类,封装一个RowMapper类 */ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; import com.cxyzxc.www.advanced.RowMapper; import com.cxyzxc.www.entity.Teacher; public class TeacherRowMapper implements RowMapper { @Override public Object getRow(ResultSet resultSet) { Teacher teacher = null; try { // 返回的结果集中有哪些字段,RowMapper类是知道的,因为他是实体类的封装类 int tid = resultSet.getInt("tid"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); Date bornDate = resultSet.getDate("bornDate"); String email = resultSet.getString("email"); String address = resultSet.getString("address"); teacher = new Teacher(tid, name, age, bornDate, email, address); return teacher; } catch (SQLException e) { e.printStackTrace(); } return null; } }
该包用来存放操作数据库的接口
package com.cxyzxc.www.dao; import java.util.List; import com.cxyzxc.www.entity.Teacher; public interface TeacherDao { //增 int insert(Teacher teacher); //删 int delete(int tid); //改 int update(Teacher teacher); //查单个 Teacher selectOne(int tid); //查所有 List<Teacher> selectAll(); }
该包用来存放数据库操作接口的实现类
package com.cxyzxc.www.dao.impl; import java.util.ArrayList; import java.util.List; import com.cxyzxc.www.advanced.RowMapper; import com.cxyzxc.www.advanced.impl.TeacherRowMapper; import com.cxyzxc.www.dao.TeacherDao; import com.cxyzxc.www.entity.Teacher */ public class TeacherDaoImpl implements TeacherDao { /* * (1)该类中提供对teacher表进行增、删、改、查单个、查所有5个方法。 * * (2)该类中的代码只做数据库访问操作,不做任何业务逻辑操作。 * * (3)该类只对数据库一张表进行操作,从而实现复用 */ DaoUtils daoUtils = new DaoUtils(); RowMapper rowMapper = new TeacherRowMapper(); // 新增:向teacher表中插入一条数据(一条数据对应一个Teacher对象),插入成功,返回一个受影响行数值(int类型) @Override public int insert(Teacher teacher) { String sql = "insert into `teacher`(name,age,bornDate,email,address) values(?,?,?,?,?);"; // 赋值 Object[] args = { teacher.getName(), teacher.getAge(), teacher.getBornDate(), teacher.getEmail(), teacher.getAddress() }; return daoUtils.commonsUpdate(sql, args); } // 删除:根据教师tid删除一条数据,删除成功,返回一个受影响行数值(int类型) @Override public int delete(int tid) { String sql = "delete from teacher where tid = ?;"; return daoUtils.commonsUpdate(sql, tid); } // 修改:修改teacher表中的数据,可能对任意的一个字段进行修改,所以方法中直接传递一个对象进行修改,修改成功,返回一个受影响行数值(int类型) @Override public int update(Teacher teacher) { String sql = "update teacher set name = ?,age = ?,bornDate = ?,email = ?,address = ? where tid = ?;"; Object[] args = { teacher.getName(), teacher.getAge(), teacher.getBornDate(), teacher.getEmail(), teacher.getAddress(), teacher.getTid() }; return daoUtils.commonsUpdate(sql, args); } // 查询单个:根据教师tid查询一条数据,查询成功返回一个结果集(ResultSet类型),从结果集中取出元素,封装成一个Teacher对象,将该对象返回 @Override public Teacher selectOne(int tid) { String sql = "select * from teacher where tid = ?;"; List<Object> objectList = daoUtils.commonsSelect(sql, rowMapper, tid); if (objectList.size() == 1) { Teacher teacher = (Teacher) objectList.get(0); return teacher; } else { return null; } } // 查询所有:将teacher表中的所有数据全部查询出来,查询成功返回一个结果集(ResultSet类型),从结果集中取出元素,封装成多个Teacher对象,将多个对象存储在集合中,返回这个集合 @Override public List<Teacher> selectAll() { List<Teacher> teacherList = new ArrayList<Teacher>(); String sql = "select * from teacher;"; DaoUtils daoUtils = new DaoUtils(); Object[] args = null; List<Object> objectList = daoUtils.commonsSelect(sql, rowMapper, args); for (int i = 0; i < objectList.size(); i++) { teacherList.add((Teacher) objectList.get(i)); } return teacherList; } }
该包用来存储业务层接口代码
package com.cxyzxc.www.service; import java.util.List; import com.cxyzxc.www.entity.Teacher; public interface TeacherService { //添加老师 int addTeacher(Teacher teacher); //删除老师 int deleteTeacher(int tid); //修改老师 int updateTeacher(Teacher teacher); //查询一个老师 Teacher selectOne(int tid); //查询所有老师 List<Teacher> selectAll(); }
该包用来存储service层实现类代码
package com.cxyzxc.www.service.impl; import java.util.List; import com.cxyzxc.www.dao.impl.TeacherDaoImpl; import com.cxyzxc.www.entity.Teacher; import com.cxyzxc.www.service.TeacherService; public class TeacherServiceImpl implements TeacherService { @Override public int addTeacher(Teacher teacher) { TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl(); Teacher teacher2 = teacherDaoImpl.selectOne(teacher.getTid()); if (teacher2 == null) { return teacherDaoImpl.insert(teacher); } else { System.out.println("老师已存在"); } return 0; } @Override public int deleteTeacher(int tid) { TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl(); Teacher teacher2 = teacherDaoImpl.selectOne(tid); if (teacher2 == null) { System.out.println("你要删除的老师不存在,无法删除"); } else { return teacherDaoImpl.delete(tid); } return 0; } @Override public int updateTeacher(Teacher teacher) { TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl(); Teacher teacher2 = teacherDaoImpl.selectOne(teacher.getTid()); if (teacher2 == null) { System.out.println("你要修改的老师不存在,无法修改"); } else { return teacherDaoImpl.update(teacher); } return 0; } @Override public Teacher selectOne(int tid){ TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl(); Teacher teacher =teacherDaoImpl.selectOne(tid); return teacher; } @Override public List<Teacher> selectAll(){ TeacherDaoImpl teacherDaoImpl = new TeacherDaoImpl(); return teacherDaoImpl.selectAll(); } }
该包用来存储测试类
package com.cxyzxc.www.view; import com.cxyzxc.www.entity.Teacher; import com.cxyzxc.www.service.TeacherService; import com.cxyzxc.www.service.impl.TeacherServiceImpl; import com.cxyzxc.www.utils.DateUtils; public class TestTeacherServiceImpl01Insert { public static void main(String[] args) { TeacherService teacherService = new TeacherServiceImpl(); Teacher teacher = new Teacher(1004, "王五", 30, DateUtils.strDateToUtilDate("1992-10-07"), "13645678912@qq.com", "安徽合肥庐阳区"); int result =teacherService.addTeacher(teacher); if(result!=0){ System.out.println("老师添加成功"); } } }
package com.cxyzxc.www.view; import com.cxyzxc.www.service.TeacherService; import com.cxyzxc.www.service.impl.TeacherServiceImpl; public class TestTeacherServiceImpl02Delete { public static void main(String[] args) { TeacherService teacherService = new TeacherServiceImpl(); int result =teacherService.deleteTeacher(1004); if(result!=0){ System.out.println("删除成功"); } } }
package com.cxyzxc.www.view; import com.cxyzxc.www.entity.Teacher; import com.cxyzxc.www.service.TeacherService; import com.cxyzxc.www.service.impl.TeacherServiceImpl; import com.cxyzxc.www.utils.DateUtils; public class TestTeacherServiceImpl03Update { public static void main(String[] args) { TeacherService teacherService = new TeacherServiceImpl(); Teacher teacher = new Teacher(1003, "王五", 30, DateUtils.strDateToUtilDate("1992-08-07"), "13677881122@qq.com", "安徽合肥政务区"); int result = teacherService.updateTeacher(teacher); if(result!=0){ System.out.println("修改成功"); } } }
package com.cxyzxc.www.view; import com.cxyzxc.www.entity.Teacher; import com.cxyzxc.www.service.TeacherService; import com.cxyzxc.www.service.impl.TeacherServiceImpl; public class TestTeacherServiceImpl04SelectOne { public static void main(String[] args) { TeacherService teacherService = new TeacherServiceImpl(); Teacher teacher = teacherService.selectOne(1002); if (teacher != null) { System.out.println(teacher); } else { System.out.println("你查询的老师不存在"); } } }
package com.cxyzxc.www.view; import java.util.List; import com.cxyzxc.www.entity.Teacher; import com.cxyzxc.www.service.TeacherService; import com.cxyzxc.www.service.impl.TeacherServiceImpl; public class TestTeacherServiceImpl05SelectAll { public static void main(String[] args) { TeacherService teacherService = new TeacherServiceImpl(); List<Teacher> listTeacher = teacherService.selectAll(); for (int i = 0; i < listTeacher.size(); i++) { System.out.println(listTeacher.get(i)); } } }
该方法是对数据表进行增、删、改的公共方法。与17.1小节中的代码一样,不再赘述。
该方法是对数据表进行查询的公共方法,可以查询一条数据,也可以查询多条数据。不管是查询一条数据还是查询多条数据,都将查询到的数据封装到泛型类型的集合中。
public List<T> commonsSelect(String sql,RowMapper<T> rowMapper, Object... args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; List<T> list = new ArrayList<T>(); // 获取数据库连接对象 connection = DBUtils.getConnection(); try { // 获取SQL语句发送对象 preparedStatement = connection.prepareStatement(sql); if (args != null) { // 绑定参数 for (int i = 0; i < args.length; i++) { preparedStatement.setObject(i + 1, args[i]); } } // 执行SQL语句 resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { T t = rowMapper.getRow(resultSet); list.add(t); } return list; } catch (SQLException e) { e.printStackTrace(); }finally { DBUtils.closeAll(null, preparedStatement, resultSet); } return null; }
package com.cxyzxc.www.advanced;
import java.sql.ResultSet;
/**
* 该接口用来约束封装对象的ORM
*
*/
public interface RowMapper<T> {
T getRow(ResultSet resultSet);
}
package com.cxyzxc.www.advanced.impl; /** * 数据封装类,专门用来处理查询返回的resultSet结果集 * * 针对每一个实体类,封装一个RowMapper类 */ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; import com.cxyzxc.www.advanced.RowMapper; import com.cxyzxc.www.entity.Teacher; public class TeacherRowMapper implements RowMapper<Teacher> { @Override public Teacher getRow(ResultSet resultSet) { Teacher teacher = null; try { // 返回的结果集中有哪些字段,RowMapper类是知道的,因为他是实体类的封装类 int tid = resultSet.getInt("tid"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); Date bornDate = resultSet.getDate("bornDate"); String email = resultSet.getString("email"); String address = resultSet.getString("address"); teacher = new Teacher(tid, name, age, bornDate, email, address); return teacher; } catch (SQLException e) { e.printStackTrace(); } return null; } }
综合案例完全按照三层架构实现,创建不同的包存放不同的接口、实现类、工具类、测试类等代码。使用数据库中的teacher表来完成综合案例。
该包用来存放项目开发所需要的数据库连接工具类DBUtils类、日期时间转换工具类DateUtils类,数据库操作工具类DaoUtils类
package com.cxyzxc.www.utils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import com.cxyzxc.www.advanced.RowMapper; public class DaoUtils<T> { // 增、删、改三个方法封装成一个方法 public int commonsUpdate(String sql, Object... args) { Connection connection = null; PreparedStatement preparedStatement = null; // 获取数据库连接对象 connection = DBUtils.getConnection(); try { // 获取SQL语句发送对象 preparedStatement = connection.prepareStatement(sql); if (args != null) { // 绑定参数 for (int i = 0; i < args.length; i++) { preparedStatement.setObject(i + 1, args[i]); } } // 执行SQL语句 int result = preparedStatement.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); } finally { DBUtils.closeAll(null, preparedStatement, null); } return 0; } public List<T> commonsSelect(String sql,RowMapper<T> rowMapper, Object... args) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; List<T> list = new ArrayList<T>(); // 获取数据库连接对象 connection = DBUtils.getConnection(); try { // 获取SQL语句发送对象 preparedStatement = connection.prepareStatement(sql); if (args != null) { // 绑定参数 for (int i = 0; i < args.length; i++) { preparedStatement.setObject(i + 1, args[i]); } } // 执行SQL语句 resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { T t = rowMapper.getRow(resultSet); list.add(t); } return list; } catch (SQLException e) { e.printStackTrace(); }finally { DBUtils.closeAll(null, preparedStatement, resultSet); } return null; } }
该类与17.4.1.2小节中的代码一样,不再赘述。
该类与17.4.1.3小节中的代码一样,不再赘述。
该包用来存储实体类,根据teacher表创建实体类Teacher类,与17.4.2小节中的代码一样,不再赘述。
该包中存放RowMapper接口,用来约束封装对象的ORM
package com.cxyzxc.www.advanced;
import java.sql.ResultSet;
/**
* 该接口用来约束封装对象的ORM
*
*/
public interface RowMapper<T> {
T getRow(ResultSet resultSet);
}
package com.cxyzxc.www.advanced.impl; /** * 数据封装类,专门用来处理查询返回的resultSet结果集 * * 针对每一个实体类,封装一个RowMapper类 */ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; import com.cxyzxc.www.advanced.RowMapper; import com.cxyzxc.www.entity.Teacher; public class TeacherRowMapper implements RowMapper<Teacher> { @Override public Teacher getRow(ResultSet resultSet) { Teacher teacher = null; try { // 返回的结果集中有哪些字段,RowMapper类是知道的,因为他是实体类的封装类 int tid = resultSet.getInt("tid"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); Date bornDate = resultSet.getDate("bornDate"); String email = resultSet.getString("email"); String address = resultSet.getString("address"); teacher = new Teacher(tid, name, age, bornDate, email, address); return teacher; } catch (SQLException e) { e.printStackTrace(); } return null; } }
该包用来存放操作数据库的接口
package com.cxyzxc.www.dao; import java.util.List; import com.cxyzxc.www.entity.Teacher; public interface TeacherDao { //增 int insert(Teacher teacher); //删 int delete(int tid); //改 int update(Teacher teacher); //查单个 Teacher selectOne(int tid); //查所有 List<Teacher> selectAll(); }
该包用来存放数据库操作接口的实现类
package com.cxyzxc.www.dao.impl; import java.util.ArrayList; import java.util.List; import com.cxyzxc.www.advanced.RowMapper; import com.cxyzxc.www.advanced.impl.TeacherRowMapper; import com.cxyzxc.www.dao.TeacherDao; import com.cxyzxc.www.entity.Teacher; import com.cxyzxc.www.utils.DaoUtils; /** * */ public class TeacherDaoImpl implements TeacherDao { /* * (1)该类中提供对teacher表进行增、删、改、查单个、查所有5个方法。 * * (2)该类中的代码只做数据库访问操作,不做任何业务逻辑操作。 * * (3)该类只对数据库一张表进行操作,从而实现复用 */ DaoUtils<Teacher> daoUtils = new DaoUtils<Teacher>(); RowMapper<Teacher> rowMapper = new TeacherRowMapper(); // 新增:向teacher表中插入一条数据(一条数据对应一个Teacher对象),插入成功,返回一个受影响行数值(int类型) @Override public int insert(Teacher teacher) { String sql = "insert into `teacher`(name,age,bornDate,email,address) values(?,?,?,?,?);"; // 赋值 Object[] args = { teacher.getName(), teacher.getAge(), teacher.getBornDate(), teacher.getEmail(), teacher.getAddress() }; return daoUtils.commonsUpdate(sql, args); } // 删除:根据教师tid删除一条数据,删除成功,返回一个受影响行数值(int类型) @Override public int delete(int tid) { String sql = "delete from teacher where tid = ?;"; return daoUtils.commonsUpdate(sql, tid); } // 修改:修改teacher表中的数据,可能对任意的一个字段进行修改,所以方法中直接传递一个对象进行修改,修改成功,返回一个受影响行数值(int类型) @Override public int update(Teacher teacher) { String sql = "update teacher set name = ?,age = ?,bornDate = ?,email = ?,address = ? where tid = ?;"; Object[] args = { teacher.getName(), teacher.getAge(), teacher.getBornDate(), teacher.getEmail(), teacher.getAddress(), teacher.getTid() }; return daoUtils.commonsUpdate(sql, args); } // 查询单个:根据教师tid查询一条数据,查询成功返回一个结果集(ResultSet类型),从结果集中取出元素,封装成一个Teacher对象,将该对象返回 @Override public Teacher selectOne(int tid) { String sql = "select * from teacher where tid = ?;"; List<Teacher> objectList = daoUtils.commonsSelect(sql, rowMapper, tid); if (objectList.size() == 1) { Teacher teacher = (Teacher) objectList.get(0); return teacher; } else { return null; } } // 查询所有:将teacher表中的所有数据全部查询出来,查询成功返回一个结果集(ResultSet类型),从结果集中取出元素,封装成多个Teacher对象,将多个对象存储在集合中,返回这个集合 @Override public List<Teacher> selectAll() { List<Teacher> teacherList = new ArrayList<Teacher>(); String sql = "select * from teacher;"; Object[] args = null; List<Teacher> list = daoUtils.commonsSelect(sql, rowMapper, args); for (int i = 0; i < list.size(); i++) { teacherList.add(list.get(i)); } return teacherList; } }
该包用来存储业务层接口代码,与17.4.7小节代码一直,这里不再赘述。
该包用来存储service层实现类代码,与17.4.8小节中代码一致,这里不再赘述。
该包用来存储测试类
与17.4.9.1小节代码一致,不再赘述。
与17.4.9.2小节代码一致,不再赘述。
与17.4.9.3小节代码一致,不再赘述。
与17.4.9.4小节代码一致,不再赘述。
与17.4.9.5小节代码一致,不再赘述。
在程序初始化时,提前创建好指定数量的数据库连接对象存储在“池子”中(这个池子称为“连接池”),当需要连接数据库的时候,从这个“池子”中取出一个连接对象使用,使用完毕后,不会将这个连接对象关闭,而是将这个连接对象放回“池子”中,实现复用,节省资源。
在lib文件夹中引入druid-1.1.5.jar文件和mysql-connector-java-5.1.0-bin.jar文件,并将两个jar文件配置到项目中。
在src文件夹下创建database.properties配置文件,配置文件中内容如下:
# 连接设置 driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/jdbcdatabase username=root password=123456 # 初始化连接,连接池连接对象数量 initialSize=10 #最大连接数 maxActive=30 #最小空闲连接 maxIdle=5 #超时等待时间(毫秒为单位) maxWait=3000
package com.cxyzxc.www.utils; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSourceFactory; public class DBUtils { // 声明一个连接池对象 private static DruidDataSource druidDataSource; static { // 实例化配置文件对象 Properties properties = new Properties(); try { // 加载配置文件内容 InputStream is = DBUtils.class .getResourceAsStream("/database.properties"); properties.load(is); // 创建连接池 druidDataSource = (DruidDataSource) DruidDataSourceFactory .createDataSource(properties); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } // 获取连接对象 public static Connection getConnection() { try { // 通过连接池获得连接对象 return druidDataSource.getConnection(); } catch (SQLException e) { e.printStackTrace(); } return null; } // 释放资源,将连接对象放入连接池中 public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) { try { if (resultSet != null) { resultSet.close(); } if (statement != null) { statement.close(); } if (connection != null) { // 使用完连接对象后,将连接对象还给连接池,这里的close()方法是DruidPooledConnection实现类里的close()方法,将connection连接对象还给连接池 connection.close(); } } catch (SQLException e) { e.printStackTrace(); } } }
package com.cxyzxc.www.utils; import java.sql.Connection; public class Test { public static void main(String[] args) { // 获取20个连接对象,输出连接对象,地址值不同 for (int i = 1; i <= 20; i++) { Connection connection = DBUtils.getConnection(); System.out.println(connection); // 调用关闭连接对象的方法后,发现获取的20个连接对象地址值是同一个,说明每次从连接池中取出的连接对象是同一个 // DBUtils.closeAll(connection, null, null); } } }
前面的DaoUtils工具类是我们经过千难万阻自己封装的,也有一些组织给我们封装DBUtils工具类,比如Apache组织提供了一个对JDBC进行简单封装的开源工具类库Commons DbUtils类,使用它能够简化JDBC应用程序的开发,同时也不影响程序的性能。
Apache DBUtils是java编程中的数据库操作实用工具,小巧简单实用,主要特征有:
1)对于数据表的读操作,他可以把结果转换成List,Array,Set等java集合,便于程序员操作;
2)对于数据表的写操作,也变得很简单(只需写sql语句)
3)可以使用数据源,使用JNDI,数据库连接池等技术来优化性能–重用已经构建好的数据库连接对象,而不像php,asp那样,费时费力的不断重复的构建和析构这样的对象。
1)ResultSetHandler接口:转换类型接口
2)QueryRunner类:执行SQL语句的类
1)创建lib文件夹,导入需要的jar包,并将其配置到项目中
2)在src文件夹下面创建database.properties配置文件
# 连接设置 driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/jdbcdatabase username=root password=123456 # 初始化连接,连接池连接对象数量 initialSize=10 #最大连接数 maxActive=30 #最小空闲连接 maxIdle=5 #超时等待时间(毫秒为单位) maxWait=3000
3)编写DBUtils连接池工具类
package com.cxyzxc.www.utils; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import javax.sql.DataSource; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSourceFactory; public class DBUtils { // 声明一个连接池对象 private static DruidDataSource druidDataSource; static { // 实例化配置文件对象 Properties properties = new Properties(); try { // 加载配置文件内容 InputStream is = DBUtils.class .getResourceAsStream("/database.properties"); properties.load(is); // 创建连接池 druidDataSource = (DruidDataSource) DruidDataSourceFactory .createDataSource(properties); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } //返回一个数据源 public static DataSource getDataSource(){ return druidDataSource; } }
CREATE TABLE IF NOT EXISTS `product` (
`pid` INT PRIMARY KEY AUTO_INCREMENT COMMENT '产品编号',
`pname` VARCHAR(20) NOT NULL COMMENT '产品名称',
`price` DOUBLE NOT NULL COMMENT '产品价格',
`birthday` DATE NOT NULL COMMENT '产品生产日期'
);
INSERT INTO `product`(`pid`,`pname`,`price`,`birthday`)VALUES(1001,'虎皮凤爪',20.5,'2022-06-12');
INSERT INTO `product`(`pid`,`pname`,`price`,`birthday`)VALUES(1002,'卧龙锅巴',18.5,'2022-09-22');
package com.cxyzxc.www.entity; import java.util.Date; public class Product { private int pid; private String pname; private double price; private Date birthday; public Product() { super(); } public Product(String pname, double price, Date birthday) { super(); this.pname = pname; this.price = price; this.birthday = birthday; } public Product(int pid, String pname, double price, Date birthday) { super(); this.pid = pid; this.pname = pname; this.price = price; this.birthday = birthday; } public int getPid() { return pid; } public void setPid(int pid) { this.pid = pid; } public String getPname() { return pname; } public void setPname(String pname) { this.pname = pname; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public String toString() { return "Product [pid=" + pid + ", pname=" + pname + ", price=" + price + ", birthday=" + birthday + "]"; } }
package com.cxyzxc.www.dao; import java.util.List; import com.cxyzxc.www.entity.Product; public interface ProductDao { //添加 int insert(Product product); //删除 int delete(int pid); //修改 int update(Product product); //查询单个 Product selectOne(int pid); //查询所有 List<Product> selectAll(); }
package com.cxyzxc.www.dao.impl; import java.sql.SQLException; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import com.cxyzxc.www.dao.ProductDao; import com.cxyzxc.www.entity.Product; import com.cxyzxc.www.utils.DBUtils; import com.cxyzxc.www.utils.DateUtils; public class ProductDaoImpl implements ProductDao { // 创建QueryRunner对象,并传递一个数据源对象 private QueryRunner queryRunner = new QueryRunner(DBUtils.getDataSource()); @Override public int insert(Product product) { String sql = "INSERT INTO `product`(`pname`,`price`,`birthday`)VALUES(?,?,?);"; Object[] args = { product.getPname(), product.getPrice(), DateUtils.utilDateToSqlDate(product.getBirthday()) }; try { return queryRunner.update(sql, args); } catch (SQLException e) { e.printStackTrace(); } return 0; } @Override public int delete(int pid) { String sql = "DELETE FROM `product` WHERE `pid` = ?;"; try { return queryRunner.update(sql, pid); } catch (SQLException e) { e.printStackTrace(); } return 0; } @Override public int update(Product product) { String sql = "UPDATE `product` SET `pname` = ?,`price`=?,`birthday`=? WHERE `pid`=?;"; Object[] args = { product.getPname(), product.getPrice(), DateUtils.utilDateToSqlDate(product.getBirthday()), product.getPid() }; try { return queryRunner.update(sql, args); } catch (SQLException e) { e.printStackTrace(); } return 0; } @Override public Product selectOne(int pid) { // 查询一个数据,使用BeanHandler将记录转换为对象 BeanHandler<Product> product = new BeanHandler<Product>(Product.class); String sql = "SELECT * FROM `product` WHERE `pid`=?;"; try { return queryRunner.query(sql, product, pid); } catch (SQLException e) { e.printStackTrace(); } return null; } @Override public List<Product> selectAll() { // 查询一个数据,使用BeanHandler将记录转换为对象 BeanListHandler<Product> productList = new BeanListHandler<Product>(Product.class); String sql = "SELECT * FROM `product`;"; try { return queryRunner.query(sql, productList); } catch (SQLException e) { e.printStackTrace(); } return null; } }
package com.cxyzxc.service; import java.util.List; import com.cxyzxc.www.entity.Product; public interface ProductService { //增加 int addProduct(Product product); //删除 int deleteProduct(int pid); //修改 int updateProduct(Product product); //查询单个 Product selectOneProduct(int pid); //查询所有 List<Product> selectAllProduct(); }
package com.cxyzxc.service.impl; import java.util.List; import com.cxyzxc.service.ProductService; import com.cxyzxc.www.dao.ProductDao; import com.cxyzxc.www.dao.impl.ProductDaoImpl; import com.cxyzxc.www.entity.Product; public class ProductServiceImpl implements ProductService { ProductDao productDao = new ProductDaoImpl(); @Override public int addProduct(Product product) { // 查询添加的商品是否存在 Product pd = productDao.selectOne(product.getPid()); if (pd == null) { return productDao.insert(product); } else { System.out.println("商品已经存在,不能重复添加"); } return 0; } @Override public int deleteProduct(int pid) { // 查询添加的商品是否存在 Product pd = productDao.selectOne(pid); if (pd != null) { return productDao.delete(pid); } else { System.out.println("商品不存在,不能删除"); } return 0; } @Override public int updateProduct(Product product) { // 查询添加的商品是否存在 Product pd = productDao.selectOne(product.getPid()); if (pd!= null) { return productDao.update(product); } else { System.out.println("商品不存在,不能修改"); } return 0; } @Override public Product selectOneProduct(int pid) { Product product =productDao.selectOne(pid); if(product!=null){ return product; }else{ System.out.println("没有你要查找产品,查找失败"); } return null; } @Override public List<Product> selectAllProduct() { List<Product> productList = productDao.selectAll(); if(productList.size()!=0){ return productList; }else{ System.out.println("数据库为空,没有产品"); } return null; } }
package com.cxyzxc.www.view; import com.cxyzxc.service.ProductService; import com.cxyzxc.service.impl.ProductServiceImpl; import com.cxyzxc.www.entity.Product; import com.cxyzxc.www.utils.DateUtils; public class Test01InsertProduct { public static void main(String[] args) { //创建ProductService引用,指向ProductServiceImpl实现类 ProductService productService = new ProductServiceImpl(); //增加产品 Product product = new Product(1003,"流心威化饼干", 13.5, DateUtils.strDateToUtilDate("2022-11-10")); int result = productService.addProduct(product); String str = result==1?"商品添加成功":"商品添加失败"; System.out.println(str); } }
package com.cxyzxc.www.view; import com.cxyzxc.service.ProductService; import com.cxyzxc.service.impl.ProductServiceImpl; public class Test02DeleteProduct { public static void main(String[] args) { // 创建ProductService引用,指向ProductServiceImpl实现类 ProductService productService = new ProductServiceImpl(); int result = productService.deleteProduct(1003); String str = result == 1 ? "删除成功" : "删除失败"; System.out.println(str); } }
package com.cxyzxc.www.view; import com.cxyzxc.service.ProductService; import com.cxyzxc.service.impl.ProductServiceImpl; import com.cxyzxc.www.entity.Product; import com.cxyzxc.www.utils.DateUtils; public class Test03UpdateProduct { public static void main(String[] args) { // 创建ProductService引用,指向ProductServiceImpl实现类 ProductService productService = new ProductServiceImpl(); // 增加产品 Product product = new Product(1002, "流心威化饼干", 13.5, DateUtils.strDateToUtilDate("2022-11-10")); int result = productService.updateProduct(product); String str = result == 1 ? "修改成功" : "修改失败"; System.out.println(str); } }
package com.cxyzxc.www.view; import com.cxyzxc.service.ProductService; import com.cxyzxc.service.impl.ProductServiceImpl; import com.cxyzxc.www.entity.Product; public class Test04SelectOneProduct { public static void main(String[] args) { // 创建ProductService引用,指向ProductServiceImpl实现类 ProductService productService = new ProductServiceImpl(); Product product = productService.selectOneProduct(1003); if (product != null) { System.out.println(product); } else { System.out.println("你要查询的商品不存在"); } } }
package com.cxyzxc.www.view; import java.util.List; import com.cxyzxc.service.ProductService; import com.cxyzxc.service.impl.ProductServiceImpl; import com.cxyzxc.www.entity.Product; public class Test05SelectAllProduct { public static void main(String[] args) { // 创建ProductService引用,指向ProductServiceImpl实现类 ProductService productService = new ProductServiceImpl(); List<Product> productList = productService.selectAllProduct(); for (int i = 0; i < productList.size(); i++) { System.out.println(productList.get(i)); } } }
自此,JDBC所有知识点学习完毕。希望大家多看笔记多理解笔记,多写写笔记中的代码,熟练掌握所有技能。
urce(properties);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//返回一个数据源
public static DataSource getDataSource(){
return druidDataSource;
}
}
## 20.2 综合案例
### 20.2.1 创建product表
CREATE TABLE IF NOT EXISTS product
(
pid
INT PRIMARY KEY AUTO_INCREMENT COMMENT ‘产品编号’,
pname
VARCHAR(20) NOT NULL COMMENT ‘产品名称’,
price
DOUBLE NOT NULL COMMENT ‘产品价格’,
birthday
DATE NOT NULL COMMENT ‘产品生产日期’
);
### 20.2.2 向表中添加数据
INSERT INTO product
(pid
,pname
,price
,birthday
)VALUES(1001,‘虎皮凤爪’,20.5,‘2022-06-12’);
INSERT INTO product
(pid
,pname
,price
,birthday
)VALUES(1002,‘卧龙锅巴’,18.5,‘2022-09-22’);
### 20.2.3 创建实体类Product
package com.cxyzxc.www.entity;
import java.util.Date;
public class Product {
private int pid; private String pname; private double price; private Date birthday; public Product() { super(); } public Product(String pname, double price, Date birthday) { super(); this.pname = pname; this.price = price; this.birthday = birthday; } public Product(int pid, String pname, double price, Date birthday) { super(); this.pid = pid; this.pname = pname; this.price = price; this.birthday = birthday; } public int getPid() { return pid; } public void setPid(int pid) { this.pid = pid; } public String getPname() { return pname; } public void setPname(String pname) { this.pname = pname; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public String toString() { return "Product [pid=" + pid + ", pname=" + pname + ", price=" + price + ", birthday=" + birthday + "]"; }
}
### 20.2.4 创建ProductDao接口
package com.cxyzxc.www.dao;
import java.util.List;
import com.cxyzxc.www.entity.Product;
public interface ProductDao {
//添加
int insert(Product product);
//删除
int delete(int pid);
//修改
int update(Product product);
//查询单个
Product selectOne(int pid);
//查询所有
List<Product> selectAll();
}
### 20.2.4 创建ProductDaoImpl实现类
package com.cxyzxc.www.dao.impl;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import com.cxyzxc.www.dao.ProductDao;
import com.cxyzxc.www.entity.Product;
import com.cxyzxc.www.utils.DBUtils;
import com.cxyzxc.www.utils.DateUtils;
public class ProductDaoImpl implements ProductDao {
// 创建QueryRunner对象,并传递一个数据源对象
private QueryRunner queryRunner = new QueryRunner(DBUtils.getDataSource());
@Override public int insert(Product product) { String sql = "INSERT INTO `product`(`pname`,`price`,`birthday`)VALUES(?,?,?);"; Object[] args = { product.getPname(), product.getPrice(), DateUtils.utilDateToSqlDate(product.getBirthday()) }; try { return queryRunner.update(sql, args); } catch (SQLException e) { e.printStackTrace(); } return 0; } @Override public int delete(int pid) { String sql = "DELETE FROM `product` WHERE `pid` = ?;"; try { return queryRunner.update(sql, pid); } catch (SQLException e) { e.printStackTrace(); } return 0; } @Override public int update(Product product) { String sql = "UPDATE `product` SET `pname` = ?,`price`=?,`birthday`=? WHERE `pid`=?;"; Object[] args = { product.getPname(), product.getPrice(), DateUtils.utilDateToSqlDate(product.getBirthday()), product.getPid() }; try { return queryRunner.update(sql, args); } catch (SQLException e) { e.printStackTrace(); } return 0; } @Override public Product selectOne(int pid) { // 查询一个数据,使用BeanHandler将记录转换为对象 BeanHandler<Product> product = new BeanHandler<Product>(Product.class); String sql = "SELECT * FROM `product` WHERE `pid`=?;"; try { return queryRunner.query(sql, product, pid); } catch (SQLException e) { e.printStackTrace(); } return null; } @Override public List<Product> selectAll() { // 查询一个数据,使用BeanHandler将记录转换为对象 BeanListHandler<Product> productList = new BeanListHandler<Product>(Product.class); String sql = "SELECT * FROM `product`;"; try { return queryRunner.query(sql, productList); } catch (SQLException e) { e.printStackTrace(); } return null; }
}
### 20.2.5 创建ProductService接口
package com.cxyzxc.service;
import java.util.List;
import com.cxyzxc.www.entity.Product;
public interface ProductService {
//增加
int addProduct(Product product);
//删除
int deleteProduct(int pid);
//修改
int updateProduct(Product product);
//查询单个
Product selectOneProduct(int pid);
//查询所有
List<Product> selectAllProduct();
}
### 20.2.6 创建ProductServiceImpl实现类
package com.cxyzxc.service.impl;
import java.util.List;
import com.cxyzxc.service.ProductService;
import com.cxyzxc.www.dao.ProductDao;
import com.cxyzxc.www.dao.impl.ProductDaoImpl;
import com.cxyzxc.www.entity.Product;
public class ProductServiceImpl implements ProductService {
ProductDao productDao = new ProductDaoImpl();
@Override public int addProduct(Product product) { // 查询添加的商品是否存在 Product pd = productDao.selectOne(product.getPid()); if (pd == null) { return productDao.insert(product); } else { System.out.println("商品已经存在,不能重复添加"); } return 0; } @Override public int deleteProduct(int pid) { // 查询添加的商品是否存在 Product pd = productDao.selectOne(pid); if (pd != null) { return productDao.delete(pid); } else { System.out.println("商品不存在,不能删除"); } return 0; } @Override public int updateProduct(Product product) { // 查询添加的商品是否存在 Product pd = productDao.selectOne(product.getPid()); if (pd!= null) { return productDao.update(product); } else { System.out.println("商品不存在,不能修改"); } return 0; } @Override public Product selectOneProduct(int pid) { Product product =productDao.selectOne(pid); if(product!=null){ return product; }else{ System.out.println("没有你要查找产品,查找失败"); } return null; } @Override public List<Product> selectAllProduct() { List<Product> productList = productDao.selectAll(); if(productList.size()!=0){ return productList; }else{ System.out.println("数据库为空,没有产品"); } return null; }
}
### 20.2.7 创建测试类
#### 20.2.7.1 测试插入数据
package com.cxyzxc.www.view;
import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
import com.cxyzxc.www.entity.Product;
import com.cxyzxc.www.utils.DateUtils;
public class Test01InsertProduct {
public static void main(String[] args) {
//创建ProductService引用,指向ProductServiceImpl实现类
ProductService productService = new ProductServiceImpl();
//增加产品
Product product = new Product(1003,"流心威化饼干", 13.5, DateUtils.strDateToUtilDate("2022-11-10"));
int result = productService.addProduct(product);
String str = result==1?"商品添加成功":"商品添加失败";
System.out.println(str);
}
}
#### 20.2.7.2 测试删除数据
package com.cxyzxc.www.view;
import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
public class Test02DeleteProduct {
public static void main(String[] args) {
// 创建ProductService引用,指向ProductServiceImpl实现类
ProductService productService = new ProductServiceImpl();
int result = productService.deleteProduct(1003);
String str = result == 1 ? "删除成功" : "删除失败";
System.out.println(str);
}
}
#### 20.2.7.3 测试修改数据
package com.cxyzxc.www.view;
import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
import com.cxyzxc.www.entity.Product;
import com.cxyzxc.www.utils.DateUtils;
public class Test03UpdateProduct {
public static void main(String[] args) {
// 创建ProductService引用,指向ProductServiceImpl实现类
ProductService productService = new ProductServiceImpl();
// 增加产品
Product product = new Product(1002, "流心威化饼干", 13.5,
DateUtils.strDateToUtilDate("2022-11-10"));
int result = productService.updateProduct(product);
String str = result == 1 ? "修改成功" : "修改失败";
System.out.println(str);
}
}
#### 20.2.7.4 测试查询一条数据
package com.cxyzxc.www.view;
import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
import com.cxyzxc.www.entity.Product;
public class Test04SelectOneProduct {
public static void main(String[] args) {
// 创建ProductService引用,指向ProductServiceImpl实现类
ProductService productService = new ProductServiceImpl();
Product product = productService.selectOneProduct(1003);
if (product != null) {
System.out.println(product);
} else {
System.out.println("你要查询的商品不存在");
}
}
}
#### 20.2.7.5 测试查询所有数据
package com.cxyzxc.www.view;
import java.util.List;
import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
import com.cxyzxc.www.entity.Product;
public class Test05SelectAllProduct {
public static void main(String[] args) {
// 创建ProductService引用,指向ProductServiceImpl实现类
ProductService productService = new ProductServiceImpl();
List<Product> productList = productService.selectAllProduct();
for (int i = 0; i < productList.size(); i++) {
System.out.println(productList.get(i));
}
}
}
**自此,JDBC所有知识点学习完毕。希望大家多看笔记多理解笔记,多写写笔记中的代码,熟练掌握所有技能。**
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。