JDBC操作之DML

需求:向t_student表中 【插入,修改和删除数据】

步骤1: 加载注册驱动【com.mysql.jdbc.Driver】–》【可以不写,但是习惯问题】

步骤2:获取链接数据库对象Connection --》 DriverManager来获取连接对象

步骤3:编写静态SQL语句–》 【一次性写好SQL并且参数已经确定】—》写成字符串,但是语句中不用分号

步骤4:创建可以执行和发送静态语句的对象Statement --》通过连接对象Connection创建

步骤5:发送语句和执行executeUpdate方法将静态语句进行发送和执行

PS: 这个语句可以执行DDL 和 DML 操作,如果是DML操作会返回一个值,这个值是一个整数,是受影响操作的行数,可以同判断这个数确定是否操作成功【只要大于0即可】

PS: 执行建表语句的时候,返回值是0但是代表建表成功

步骤6:数据库属于长连接,这个资源只要不释放,就会一直保持连接

PS:释放原则:1.程序执行完毕关闭【Demo级别可以】 2.手动释放资源,有一个统一的操作close

插入一条数据到数据库表中

insert into t_student(name,age)values('乔峰',33)

编写代码

package com.qfedu.JDBC.DML;import java.sql.*;/*** 通过JDBC向表中插入数据*/
public class InsertTest {public static void main(String[] args) throws ClassNotFoundException, SQLException {//1.加载注册驱动Class.forName("com.mysql.jdbc.Driver");//2.获取数据库链接对象//loaclhost -->代表着两个地址 一个是内环地址【计算自己自带 127.0.0.1】  一个是外环地址【根据网线或路由器分配得来】Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1","root","123456");//3.创建执行和发送静态SQL语句的对象Statement statement = conn.createStatement();//4.编写静态SQL语句String sql = "insert into t_student(name,age)values('乔峰',33)";//5.执行发送操作int i = statement.executeUpdate(sql);if(i > 0) {System.out.println("插入成功");}else {System.out.println("插入失败,执行语句问题");}//6.释放资源statement.close();conn.close();}
}

需求:

 1. 在插入一条值   啊朱,182. 更新数据将乔峰,修改为 萧峰,年龄修改为34

3.将啊朱数据进行删除

package com.qfedu.JDBC.DML;public class InsertAndUpdateAndDeleteSQL {private InsertAndUpdateAndDeleteSQL(){};//提供插入语句【静态SQL】public static final String INSERT_SQL = "insert into t_student(name,age)values('啊朱',18)";//提供更新语句public static final String UPDATE_SQL = "update t_student set name = '萧峰',age = 34 where id = 1";//删除语句public static final String DELETE_SQL = "delete from t_student where name = '啊朱'";}import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;/*** 需求:**    1. 在插入一条值   啊朱,18*    2. 更新数据将乔峰,修改为 萧峰,年龄修改为34*    3.将啊朱数据进行删除*/
public class UpdateAndDelete {public static void main(String[] args) throws Exception {Class.forName("com.mysql.jdbc.Driver");/*JDBC连接驱动路径写法:1.常规jdbc:mysql://连接数据库服务器的IP地址:3306/连接数据库的名称2.可以在数据库名称后面添加连接数据【如果直接和数据库名称相连使用? 剩余的数据库参数使用&符号进行连接】连接数据库的同时指定数据库的编码集jdbc:mysql://连接数据库服务器的IP地址:3306/连接数据库的名称?useUnicode=true&characterEncoding=UTF-83.MySQL 5.6版本开始之后,使用JDBC连接数据库时,数据库连接会对SSL连接进行安全验证PS:连接数据库的时候回出现一行警告,这个警告不会影响数据库执行如果出现了这个警告,关闭警告即可jdbc:mysql://连接数据库服务器的IP地址:3306/连接数据库的名称?useSSL=falseps:习惯性这样书写数据库链接语句jdbc:mysql://连接数据库服务器的IP地址:3306/连接数据库的名称?useUnicode=true&characterEncoding=UTF-8&useSSL=false*/Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1", "root", "123456");Statement statement = connection.createStatement();//1.执行插入//InsertTableData(statement);//2.更新//atl+ctrl+m --> 快捷抽取方法//UpdateTableData(statement);//3.删除//DeleteTableData(statement);statement.close();connection.close();}public static void DeleteTableData(Statement statement) throws SQLException {int i = statement.executeUpdate(InsertAndUpdateAndDeleteSQL.DELETE_SQL);if (i>0){System.out.println("删除成功");}else{System.out.println("删除失败");}}public static void UpdateTableData(Statement statement) throws SQLException {int i = statement.executeUpdate(InsertAndUpdateAndDeleteSQL.UPDATE_SQL);if (i>0){System.out.println("更新成功");}else{System.out.println("更新失败");}}public static void InsertTableData(Statement statement) throws SQLException {int i = statement.executeUpdate(InsertAndUpdateAndDeleteSQL.INSERT_SQL);if (i>0){System.out.println("插入成功");}else{System.out.println("插入失败");}}
}

总结:

想通过JDBC对数据库进行增删改操作,就需要使用到一个语句对象Statement【这个对象只接受静态SQL语句】

使用executeUpdate方法进行操作,返回值是一个int类型数据,通过判断这个数据是否大于0即可知道是否添加成功【创建表返回时0,但是操作成功】,DDL和DML都需要和这个方法执行

JDBC操作DQL

DQL语句这里依旧是使用静态SQL语句,还是需要是Statement对象,DQL语句在通过JDBC操作的时候使用方法和得到返回这都有很大改变

返回值类型 方法和方法说明
ResultSet executeQuery(String sql) 执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。

什么ResultSet?

ResultSet表示数据库结果集的数据表,通常通过执行查询数据库的语句【DQL】生成。

通过对对这个虚拟表的操作即可以取出当前虚拟表中的值

PS: 这里大家要记住在学习MySQL时MySQL数据类型对应Java中的数据类型什么

演示代码

package com.qfedu.JDBC.DQL;import java.sql.*;/*** DQL语句通过JDBC进行操作*/
public class SelectTest {public static void main(String[] args) throws Exception {String sql = "select * from t_student";Class.forName("com.mysql.jdbc.Driver");Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1","root","123456");Statement statement = connection.createStatement();//resultSet就是存储这个查询语句得到虚拟表对象ResultSet resultSet = statement.executeQuery(sql);System.out.println(resultSet);//问题:此时返回resultSet确实是一个虚拟表对象com.mysql.jdbc.JDBC4ResultSet@67424e82,所以如何获取其内部值//在ResultSet官方API中有一句说明,ResultSet存在着一个光标,通过移动这个光标即可以获取到resultSet对象中存值//ResultSet中提供一个方法 next -->移动光标,如果有下一行数据返回true,否则没有数据则返回false//利用这个原则,就可以使用while循环,循环获取出结果集中数据了while(resultSet.next()){//移动光标获取值//如果需要回去到具体一行数据值,ResultSet提供了两个方法/*ps:以下的XXX代表的是不同数据类型,通过get方法表中获取数据的数据类型1.    XXXX  getXXXX(int  columnIndex)获取当前光标行的第N列数据【根据表从左向后获取列,左第一列为为1,依次类推】例如: student表中有三个列  id【1】   name【2】  age【3】通过当前get方法获取列数据时      getInt(1) --> 相当于获取到 id着列的值2.   XXXX  getXXXX(String columnName)获取当前光标行的列的名字获取列中存储数据例如: student表中有三个列  id   name  age通过当前get方法获取列数据时      getInt(id) --> 相当于获取到 id着列的值*///获取ResultSet对象中存储数据值是一定要注意使用是什么数据类型【☞表中】,接收的时候使用什么数据类型接收【☞Java代码中】//这两个数据类型一定要一一对应int id = resultSet.getInt(1);String name = resultSet.getString("name");int age = resultSet.getInt("age");System.out.println("存储在Student表中 ID值是:"+id+" name值是:"+name+" age值是:"+age);}//ResultSet也属于长连接对象,所以也要释放resultSet.close();statement.close();connection.close();}
}

ResultSet执行过程

1.在没有调用next方法之前,光标是在列这一行

2.代用了next方法,光标会移动到一行数据的位置

3.通过getXXX方法获取出这一行数据

4.再次调用next方法,结果没有数据了,返回false 程序结束

需求:统计出t_student中有多少条数据

package com.qfedu.JDBC.DQL;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;/*** DQL语句通过JDBC进行操作[统计数据]*/
public class SelectTest2 {public static void main(String[] args) throws Exception {String sql = "select count(id) count from t_student";Class.forName("com.mysql.jdbc.Driver");Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1","root","123456");Statement statement = connection.createStatement();//resultSet就是存储这个查询语句得到虚拟表对象ResultSet resultSet = statement.executeQuery(sql);while(resultSet.next()) {//直接传递列名int count1 = resultSet.getInt("count");System.out.println(count1);//如果要是你确定列个数int count2 = resultSet.getInt(1);System.out.println(count2);}resultSet.close();statement.close();connection.close();}
}

使用JDBC实现登录案例

1.实现登录

  • 创建一张用户表 User

    • id ,主键、自动增长。
    • 用户名,字符串类型,唯一、非空
    • 密码,字符串类型,非空
    • 手机号码,字符串类型
  • 插入 2 条测试语句
  • 通过控制台用户输入用户名和密码。
  • 用户输入的用户名和密码作为条件,编写查询 SQL 语句。
  • 如果该用户存在,提示登录成功,反之提示失败。

代码

package com.qfedu.JDBC.LogIn;
//提供静态SQL语句
public class CreateAndInsertSQL{private CreateAndInsertSQL(){};//提供建表public static  final  String CREATE_TABLE ="create table user(" +"id int primary key auto_increment," +"username varchar(20) unique not null," +"password varchar(20) not null," +"phoneNumber varchar(20)" +")";//提供插入语句public  static final String INSERTINOT_1 ="insert into user(username,password,phoneNumber)values('zhangsan','123456','13112345678')";public  static final String INSERTINOT_2 ="insert into user(username,password,phoneNumber)values('lisi','111111','13842383838')";public static String  SelectTableData(String username,String password){return "select * from user where username = '"+username+"' and password = '"+ password+"'";}}
package com.qfedu.JDBC.LogIn;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;//创建表和插入表中数据
public class CreateTableAndInsert{public static void main(String[] args) throws Exception {//加载连接驱动Class.forName("com.mysql.jdbc.Driver");// 获取连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1","root","123456");//创建执行SQL语句对象【静态语句】Statement statement = connection.createStatement();//5.建表int succeed = statement.executeUpdate(CreateAndInsertSQL.CREATE_TABLE);if (succeed == 0){System.out.println("建表成功");}int i = statement.executeUpdate(CreateAndInsertSQL.INSERTINOT_1);int i1 = statement.executeUpdate(CreateAndInsertSQL.INSERTINOT_2);if(i>0 && i1 >0){System.out.println("插入数据成功");}statement.close();connection.close();}}
package com.qfedu.JDBC.LogIn;import java.sql.*;
import java.util.Scanner;public class LoginTest {public static void main(String[] args) throws ClassNotFoundException, SQLException {Scanner input = new Scanner(System.in);System.out.println("请输入用户名:");String username = input.nextLine();System.out.println("请输入密码:");String password = input.nextLine();Class.forName("com.mysql.jdbc.Driver");Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1","root","123456");Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery(CreateAndInsertSQL.SelectTableData(username, password));//如果判断是否登录成功if(resultSet.next()){System.out.println("登录成功");}else{System.out.println("登录失败");}resultSet.close();statement.close();connection.close();}
}

预编译语句对象和JDBC工具抽取封装

预编译语句对象

在之前所有编写MySQL语句的时候,我们都是在开发阶段就要直接将SQL语句写好,并且里面的传输数据也是直接写死,对于这样SQL语句称为【静态SQL语句】,这样静态SQL语句存在一些弊端

【1.不好修改 2.语句中参数是写死的,不能动态获取参数

**3.静态语句没有进行优化   4.静态语句及其容易出现SQL注入】**

Java为了解决这些问题,它提供了一个Statement子类【子接口】,叫做PreparedStatement,它也是一个接口,它提供了一个静态编译语句对象

PreparedStatement表示预编译的 SQL 语句的对象。

SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。

在使用预编译语句对象到时候,需要使用到占位符号,进行参数占位 --》 【?】

例如:

静态语句向表中插入数据

insert into t_student(name,age)values('zhangsan',18);

预编译语句性表中插入数据

 insert into t_student(name,age)values(?,?);

在语句中【?】只是一个占位符号,没有具体值,所以预编译语句提供一个方法可以对【?】进行赋值操作

void setXXXX(int parameterIndex, XXXX value);

PS:XXX代表传入数据库中数据的数据类型
位置计算,从左向右,占位符的第一位位置是【1】,依次类推

预编译语句和静态语句对比

预编译语句特点:

1.代码的可读性和可维护性比较【因为使用占位,只需要实现一个语句,动态改变值就可以不停查询出不同结果】

ps:所以预编译语句类似于【语句模板】

2.预编译语句可以最大能力提高性能

3.预防SQL注入

SQL语句的执行流程

修改一个案例实现预编译语句

需求:使用预编译语句向t_student插入数据package com.qfedu.JDBC.PreparedStatement;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;//实现预编译语句
public class PreparedStatementDemo {public static void main(String[] args)throws Exception {//1.写预编译语句String  preSQL = "insert into t_student(name,age)values(?,?)";//加载连接驱动Class.forName("com.mysql.jdbc.Driver");// 获取连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1","root","123456");//创建预编译语句对象--》需要传入预编译语句对象进行对象创建PreparedStatement preparedStatement = connection.prepareStatement(preSQL);//对象创建完毕之后,语句中还是存在占位符号,所以需要使用预编译语句对象对当前占位符进行赋值//1.先对预编译语句对象中占位进行赋值preparedStatement.setString(1,"西方失败");//第一个?赋值preparedStatement.setInt(2,1);//第二个?赋值//执行DDL或DML语句,方法依旧是 executeUpdate 这个没有参数直接执行并接收返回值【还是判断是否大于0】int i = preparedStatement.executeUpdate();//boolean execute = preparedStatement.execute();if (i>0){System.out.println("插入成功");}else{System.out.println("插入失败");}//预编译语句对象也属于长连接preparedStatement.close();connection.close();}
}
需求:使用预编译语句进行查询
package com.qfedu.JDBC.PreparedStatement;import jdk.nashorn.internal.ir.CallNode;
import netscape.javascript.JSUtil;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;//实现预编译语句
public class PreparedStatementDemo2 {public static void main(String[] args)throws Exception {//1.写预编译语句String  preSQL = "select * from t_student where id = ?";//加载连接驱动Class.forName("com.mysql.jdbc.Driver");// 获取连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1","root","123456");//创建预编译语句对象--》需要传入预编译语句对象进行对象创建PreparedStatement preparedStatement = connection.prepareStatement(preSQL);//对象创建完毕之后,语句中还是存在占位符号,所以需要使用预编译语句对象对当前占位符进行赋值//1.先对预编译语句对象中占位进行赋值preparedStatement.setInt(1,4);//2.使用DQL语言进行查询 executeQuery方法,这个方法没有参数ResultSet resultSet = preparedStatement.executeQuery();boolean execute = preparedStatement.execute();System.out.println(execute);while(resultSet.next()){int id = resultSet.getInt("id");String name = resultSet.getString("name");int age = resultSet.getInt("age");System.out.println(id+name+age);}//预编译语句对象也属于长连接preparedStatement.close();connection.close();}
}

ps:预编译语句中提供一个execute方法,这个方法返回值是boolean,即可以运行DDL和DML,也可以运行DQL,但是这个方法的返回值决定点在于是否可以获取到一个ResultSet对象,也就是说execute方法对查询语句的到ResultSet结果集之后会返回【true】,剩余DDL和DML返回值为【false】

综上所述:

1.对于预编译语句而言,可以依旧使用executeUpdate执行【DDL和DML】语句,也可以使用executeQuery执行【DQL】语句,这两个方法对比静态语句中方法少了方法形参,但是执行效果是一样的

模拟SQL注入

package com.qfedu.JDBC.PreparedStatement;import java.sql.*;/*** SQL注入操作*/
public class LoginTest {public static void main(String[] args) throws Exception {//用户注册信息user表,只有用户名和密码正取之后才能让其登录//1.静态SQL语句String  staticSQL = "select * from user where username = '' OR 1 = 1 AND password = '123456'";String  perSQL = "select * from user where username = ? AND password = ?";Class.forName("com.mysql.jdbc.Driver");Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1", "root", "123456");
//        Statement statement = connection.createStatement();
//        ResultSet resultSet = statement.executeQuery(staticSQL);
//        if(resultSet.next()){//            System.out.println("登录成功");
//        }else{//            System.out.println("登录失败");
//        }PreparedStatement preparedStatement = connection.prepareStatement(perSQL);//因为数据是以占位符的形式传递进去//因为预编译语句会将参数看做是一个字段【列】一个值 而不是当做一个SQL语句运行/*说明:静态SQL中,它会将where子句的后面看做时一个表达式 和整个整个语句融为一体,是一个完整的SQL预编译语句,他会将出现占位符号的位置,看做就是一个字段【列】的值ps:将 '' OR 1 = 1 看做是一个用户名即 username列里面是否存在和这个值*/preparedStatement.setString(1,"'' OR 1 = 1");}
}核心:"为了SQL语句的安全建议开发的时候都写预编译语句"

JDBC封装工具类

在实际开发JDBC的过程中,存在大量向同的重复性代码【触发了DRY原则】,所以我们需要对重复的代码进行抽取,封装到一个统一的类中,通过这类就可以获取到JDBC的基础操作,就不用大量重复编写代码

通过对之前代码的简单分析可以的到一些结论

1.加载注册驱动每个对象都需要使用

2.获取连接对象

在获取连接对象的时候用,需要传递参数,如果将参数写死在代码中,如果修改连接数据库,那么你就要查找对应代码才能修改,还是需要修改原码,所以建议将当前数据封装到一个文件中,读取这个文件即可以获取到链接的数据,以后要修改连接的时候,无需查找代码,只需要文件即可

  1. 数据库的连接属于一个【长连接】,程序不关闭的且没有做任何资源释放,后果就是一直会有一个连接资源占用,如果是Demo级别,其实没有大问题,但是在实际开发中10万人连接,服务器的内存压力就非常大,甚至会出现崩溃【宕机】

抽取一个工具类【DBUtil】这个工具类中就提供以上三种操作,后续需要什么在向这个类添加即可

步骤1:创建一个资源文件,将会数据库连接参数写入到文件中,使用时读取文件即可

#数据库连接配置写到这个文件中
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb1
username=root
password=123456

步骤2:抽取创建DBUtil工具类

package com.qfedu.JDBC.util;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;/*** JDBC工具类*/
public class DBUtil {//1.工具类不会创建对象,所以将构造方法私有化private  DBUtil(){}//2.创建一个Properties文件对象以便读取文件中的数据private static final Properties p = new Properties();//3.提供一个静态代码块 用来对要使用数据库连接对象进行配置static {//3.1先文件中内容读取出来try {//获取类的类的加载器ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();//通过类的加载器获取classPath路径下文件【db.properties】InputStream resourceAsStream = contextClassLoader.getResourceAsStream("db.properties");p.load(resourceAsStream);//通过字节流加载} catch (IOException e) {throw  new  RuntimeException("加载classPath路径下的db.properties文件出现失败:"+e.getMessage());}//3.2 加载注册驱动try {Class.forName(p.getProperty("driver"));} catch (ClassNotFoundException e) {throw  new  RuntimeException("数据库驱动加载失败:"+e.getMessage());}}/*** 获取Connection连接对象* @return Connection连接对象*         会抛出异常,连接对象获取失败*/public static Connection getConnectionInstance(){try {return DriverManager.getConnection(p.getProperty("url"),p.getProperty("username"),p.getProperty("password"));} catch (SQLException e) {throw  new  RuntimeException("数据库获取连接对象失败:"+e.getMessage());}}/*** 释放JDBC连接资源对象* @param connection 连接对象* @param statement  静态SQL语句对象* @param preparedStatement  预编译语句对象* @param resultSet  结果集*/public static void closeAll(Connection connection, Statement statement, PreparedStatement preparedStatement, ResultSet resultSet){//这里的释放原则,只要创建就是释放 反之不执行try {if (connection != null) {connection.close();}if (statement != null) {statement.close();}if(preparedStatement != null){preparedStatement.close();}if(resultSet != null){resultSet.close();}}catch (SQLException e){throw  new  RuntimeException("释放资源出出现失败:"+e.getMessage());}}}

步骤3:测试工具类

package com.qfedu.JDBC.util;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class DBTest {public static void main(String[] args) throws SQLException {//查询语句String sql = "select * from t_student where id = ?";//1.加载驱动获取连接对象Connection connection = DBUtil.getConnectionInstance();//2.获取预编译语句对象PreparedStatement preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1,3);ResultSet resultSet = preparedStatement.executeQuery();if(resultSet.next()){System.out.println("查询成功");}DBUtil.closeAll(connection,null,preparedStatement,resultSet);}
}

JDBC之ORM映射

ORM(object Relational Mapping)从数据库中查询出的结果集(ResultSet)在进行遍历是,我们逐行取出值,但是这个是零散,所以为了使用方便,在实际开发中提供了一种思想,更加便于管理这些零散数据,主要是提供了对零散数据的封装,提供公益的访问方式和使用途径

PS:关系型数据库和Java中的类是存在一定联系

​ 数据库中表 -----》 看做 -----》Java中类

​ 数据库中表的列 ----》 看做 ----》 Java中类中属性

​ 数据库中表的每一行数据 —》 看做 —》 java中类的对象

所以就是因为存在这种关系 —》称之为 【ORM映射】

因为要将这些零散进行封装,所以就需要提供一个存储零散数据载题,这个载体就叫做**【实体类】**

ps:什么是实体类?就是刚开始学习面向对象时的描述类

什么是实体类(entity)?

实体类的作用就是通过ResultSet查询出来的零散数据的统一载体

一行数据中,多个零散的数据进行整体的封装,通过entity的规则对表中数据进行对象的封装

实体类的设计原则?

【表名 == 类型】 【列 == 属性】 【实体类要提供get和set方法】 【提供有参无参构造方法】

扩展: JavaBean规范

ps:实体类就是JavaBean

JavaBean是一种Java语言的一个重要的组件【就是一个类】

要写和这个JavaBean这类就需要遵守一个规范

1.这个类必须使用public修饰

2.必须保证有【有参无参构造反方】

3.包含处理属性操作的手段【提供get和set】

JavaBean规范类一般多用于domain、dao、services组件中分装类【存储数据使用】

实例类案例

package com.qfedu.JDBC.entity;
//这类就是tbStock这个表的实体类
public class T_tbStock {//跟表中列的名一致【属性名】private String ordername;private String locationid;private String dateid;//这类提供get和Set 还有有参无参构造方法public T_tbStock() {}public T_tbStock(String ordername, String locationid, String dateid) {this.ordername = ordername;this.locationid = locationid;this.dateid = dateid;}public String getOrdername() {return ordername;}public void setOrdername(String ordername) {this.ordername = ordername;}public String getLocationid() {return locationid;}public void setLocationid(String locationid) {this.locationid = locationid;}public String getDateid() {return dateid;}public void setDateid(String dateid) {this.dateid = dateid;}@Overridepublic String toString() {return "T_tbStock{" +"ordername='" + ordername + '\'' +", locationid='" + locationid + '\'' +", dateid='" + dateid + '\'' +'}';}
}
package com.qfedu.JDBC.entity;import com.qfedu.JDBC.util.DBUtil;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;/*
实体类使用*/
public class T_tbStockTest {public static void main(String[] args) throws Exception {//1.需要加载注册驱动和创建连接对象Connection connection = DBUtil.getConnectionInstance();String sql = "select * from tbstock";Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery(sql);//如果按照以前的方式
//        while(resultSet.next()){//            //零散数据的体现其实就是这个表中值,我们无法提供合理方式进行存
//            String ordername = resultSet.getString(1);
//            String locationid = resultSet.getString(2);
//            String dateid = resultSet.getString(3);
//        }//以表和类之间产生一个映射关系【ORM】 表即是类 表中列即是类中属性 表中每一行数据封装在这个类的对象List<T_tbStock> list = new ArrayList<>();while(resultSet.next()){String ordername = resultSet.getString(1);String locationid = resultSet.getString(2);String dateid = resultSet.getString(3);//将数据分装进对象中T_tbStock tb = new T_tbStock(ordername,locationid,dateid);list.add(tb);}list.forEach(System.out::println);}
}

DAO数据访问对象(Data Access Object)

什么DAO:主要作用就是执行【CRUD(增删改查)】

DAO是一个数据访问接口,数据访问:顾名思义就是与数据库打交道

在核心JavaEE中是这样介绍DAO模式的:为了建立一个健壮的JavaEE的应用程序,应该将所有对数据库的访问抽象的封装在一个公共API中

用程序设计的语言来说,其实就是建议一个接口,接口中定了此应用程序中将会用到所有事务方法

在应用程序中,当需要和数据源进行交互的时候,则直接使用这个接口,并编写一个实现接口类,这个类中将实现接口所有的方法,并且对外提供暴露,外部只需要调用这个类就可以完成对数据库的操作,这个操作就是DAO包中核心

扩展 :DAO包中设计方式

DAO包的设计规范:

DAO包中组件:【DAO接口、DAO实现类、DAO的测试类】

分包的规范:

【以下仅以我开发经验而言】

com.公司的域名.项目名称.dao --> 存储着dao包中接口文件

com.公司的域名.项目名称.dao.impl --> 存储着Dao包中接口的实现类

com.公司的域名.项目名称.dao.domian --> 存放着Dao包中需要使用到实体类【ORM思想】

PS:有的的地方习惯将实体类单独抽取出来一个包entity,含义和domian是一样的

com.公司的域名.项目名称.dao.test --> 存测试文件

PS:在实际项目提交【甲方爸爸】,需要将test全员删除

​ JavaSE是以jar为打包,可以提供对外使用

​ JavaEE是以war为打包,可以提供对外使用

具体包所创建的东西

domain包:描述对象的,一般就是存储实体类 例如:Person.java

dao包: 接口文件【定义操作数据库的方法CRUD】 例如: IPersonDao 或 IPersonDAO

impl包: 这个包就是对dao中接口的具体实现类【CRUD】 例如:IPersonDAOImpl

test包: 测试包对impl包中实现类测试是否可以使用,能否争取完成操作 例如:PersonDAOTest

创建DAO包之后,我们需要使用面向接口编程:

所有触发DAO包的操作都需要使用接口来实现对象创建

例如: IPersonDAO pd = new IPersonDAOImpl();

2-28 数据库链接操作_JDBC_02相关推荐

  1. mysql的远程链接工具_Navicat远程链接mysql-8数据库具体操作

    未经允许不得转载 *Navicat**远程链接mysql-8数据库具体操作方案* *一:本地链接* *二:公有云链接* *备注:此文档是以root用户演示.项目最好用其他用户* *具体步骤:* *公有 ...

  2. thinkphp连mysql增删改查_ThinkPHP5.1框架数据库链接和增删改查操作示例

    本文实例讲述了ThinkPHP5.1框架数据库链接和增删改查操作.分享给大家供大家参考,具体如 本文实例讲述了ThinkPHP5.1框架数据库链接和增删改查操作.分享给大家供大家参考,具体如下: 一. ...

  3. xp 安装mysql数据库_Windows XP系统中安装MySQL5.5.28数据库图文教程

    Windows XP系统中安装MySQL5.5.28数据库图文教程 2014-07-13 16:35来源:中国存储网 导读:MySQL数据库的安装一共分为两个部分:数据库的安装和数据库的配置.一.My ...

  4. dml操作mysql_数据库DML操作(DCL了解)

    DQL:SELECT * FROM 表名 DML(数据操作语言,它是对表记录的操作(增.删.改)!) 1. 插入数据 * INTERT INTO 表名(列名1,列名2, ...) VALUES(列值1 ...

  5. mysql(数据库)初级操作

    数据库 第一节 MySQL介绍和安装 mysql安装简单总结 #1.下载:MySQL Community Server 5.7.16 http://dev.mysql.com/downloads/my ...

  6. informix数据同步到mysql_informix数据库扩容操作步骤

    一.目前现网SMP数据库情况 1.informix数据库采用双机(RP5470)+磁盘阵列存储,保证informix始终在主机上运行,并以独占方式控制管理阵列上的数据库空间. 目的:informix数 ...

  7. 从C#到Objective-C,循序渐进学习苹果开发(7)--使用FMDB对Sqlite数据库进行操作

    本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台苹果开发的一系列感想和体验历程,本系列文章是在起步阶段逐步积累的,希望带给大家更好,更真实的转换历程体验.本篇主要开始介绍基于XCod ...

  8. 数据库链接池终于搞对了,这次直接从100ms优化到3ms!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 本文来源: https://www.jianshu.com/p/a ...

  9. 使用iOS原生sqlite3框架对sqlite数据库进行操作

    摘要: iOS中sqlite3框架可以很好的对sqlite数据库进行支持,通过面向对象的封装,可以更易于开发者使用. 使用iOS原生sqlite3框架对sqlite数据库进行操作 一.引言 sqlit ...

最新文章

  1. 近期活动盘点:高管AI大数据能力研修班、英伟达初创企业展示开启报名
  2. websocket 更新点位 浏览器卡顿_我们来看看Swoole是如何实现WebSocket服务器及客户端的...
  3. 【阿西莫夫】最后的问题
  4. OpenCV图像的轮廓的匹配
  5. Springboot集成ES启动报错
  6. 数据3分钟丨​PingCAP DevCon 2021回顾;openGauss社区颁发首张OGCA认证证书
  7. java数组排序问题:array.sort()是从小到大排序,那么如何从大到小排序?
  8. 中信证券:维持贝壳“买入”的投资评级
  9. 关于Redis、ZooKeeper等分布式锁原理的一些思考
  10. [SQL实战]之查找当前薪水排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不准使用order by
  11. VS2012统计代码量
  12. python调用c++动态库_python调用c++开发的动态库
  13. 鼎力加密狗驱动程序_怎么安装加密狗驱动程序
  14. [ZigBee] 15、Zigbee协议栈应用(一)——Zigbee协议栈介绍及简单例子(长文,OSAL及Zigbee入门知识)...
  15. 计算机excel猪肉价格分析,猪肉价格的统计模型.doc
  16. 【MDCC 2016】信息无障碍专题沙龙现场实录 | 附PPT下载
  17. 守望先锋ptr服务器位置,守望先锋测试服怎么进 守望先锋ptr怎么进
  18. CodeForces Round #521 (Div.3) B. Disturbed People
  19. 有道云怎么换行_『42』怎样令为知笔记中的长网址换行?
  20. 电脑无法安装软件打不开计算机,电脑刚安装软件打不开怎么办

热门文章

  1. ☀️苏州程序大白用万字解析Python网络编程与Web编程☀️《❤️记得收藏❤️》
  2. 第一章_01_JAVA概述
  3. 指纹识别(一)—— 电容式、光学式、超声波式介绍
  4. 带有 JavaScript 的井字游戏:带有 Minimax 算法的 AI 玩家
  5. 华强北airpods三代连接安卓手机没声音_正品Airpods的钱买了8个“华强北顶配”,翻了7次车...
  6. 代理IP的三个实际应用场景
  7. Swin Transformer: Hierarchical Vision Transformer using Shifted Windows论文阅读
  8. SpringAMQP详解
  9. 为师在拆装机中的感受
  10. mysql设置时间默认值