JDBC的增删改-结果集的元数据-Class反射-JDBC查询封装
一、使用JDBC批量添加
知识点复习:
1、JDBC的六大步骤 (导入jar包, 加载驱动类,获取连接对象, 获取sql执行器、执行sql与并返回结果, 关闭数据库连接)
2、封装了一个DBUtil 类, 通过读取属性文件的方式获取 基础连接信息。
3、批量添加: 一次性可执行多个添加记录 ,将多个sql语句在当前这次连接中执行完毕。
// 设置部门集合 List<Dept> list = new ArrayList<>(); list.add(new Dept(60,"市场部","武汉市")); list.add(new Dept(70,"研发部","武汉市")); list.add(new Dept(80,"教学部","武汉市")); //通过DBUtil获取数据库连接 Connection conn = DBUtil.getConn(); String sql="insert into dept(deptno,dname,loc) values (?,?,?)"; //获取预编译sql执行器 PreparedStatement ps = conn.prepareStatement(sql); //批量设置该条sql语句的 参数 for(Dept dept : list){ //设置参数 ps.setInt(1,dept.getDeptno()); ps.setString(2,dept.getDname()); ps.setString(3,dept.getLoc()); // 将设置好的参数 先放入批量添加的容器中 ps.addBatch(); // 对于完整的sql语句 可以用有参的 // ps.addBatch(sql); } // 执行sql语句 返回每一行sql语句影响的行数 , int [] counts = ps.executeBatch(); System.out.println("结果长度:"+ counts.length); System.out.println("结果:"+ Arrays.toString(counts)); //关闭sql语句 DBUtil.closeAll(conn,ps,null);
二、结果集的元数据:
columnCount 结果集的列数
columnName 列的名称 // select columnName as columnLabel…
columnLabel 列的别名(label)
columnClassName 列在Java中对应的类型(可配合Class.forName(String className)获取Class类型的返回值)
columnType 列在数据库中的类型(数值编号)
columnTypeName 列在数据库中的类型名称
columnDisplaySize 列大小
结果集(ResultSet)和结果集元数据(ResultSetMetaData)同为JDBC标准中的接口|标准。
java.sql.ResultSet
java.sql.ResultSetMetaData
三、Class反射
1、为什么需要使用反射
由于之前创建对象的过程 ,是已知这个类,然后对类进行编译,编译通过之后才可以创建对象, 现在可能出现 “未知的类” 只有“包名+类名” ,在运行期间才知道 该类是否存在,并动态创建该类的对象。 这时 创建对象的过程 可以通过反射的方式 完成。
反射机制的定义: 对于任意一个类,都可以在运行期间,动态的创建该类的对象,能知晓该对象的属性和方法,并动态调用属性 和方法 ,这个过程就是Java的反射机制
对于任意类 都存在一个该类的Class类型 ,如何获取类的Classs类型
方式一: Class cls = Class.forName("类的全类名")
方式二: Class cls = 类名.class;
方式三: Class cls = 类的对象名.getClass()
常用API
Construct:
cls.getConstructor(int.class , String.class); 根据参数类型和个数 获取cls 对应的 构造器对象
Field : 属性对应的类型
getDeclareFields () : 获取所有声明的属性 (包括 任何修饰符,不包括private修饰)
getFields(): 获取所有声明的public修饰的属性
getDeclareFiled(String name): 根据属性名获取属性对象
getField(String name):根据属性名获取属性对象 (必须是共有的 )
Method : 方法对应的类型
getDeclaredMethods() : 返回当前类的自己声明的方法
getMethods() :返回所有的方法(包括父类的)
invoke(obj,参数值) :调用该方法
getMethod(“方法名” ,参数值):根据方法名返回Method
四、反射封装(增删改查)
preparedStatement的作用:
1、提前传入sql,执行的时候,不传入sql
2、支持传入sql中的参数
3、解决sql注入逻辑漏洞
4、提高执行效率
Object ...params(可变形参数组) 作用:在调用函数时,可以传入任意个任意类型的参数
标题查询多行的封装
//查询多行多列 public static <T> List<T> list(String sql,Class<T> c,Object...params){ //创建一个集合,存放所有的对象 List<T> tList=new ArrayList<>(); try { //1、注册驱动-反射去加载jar包中com.mysql.jdbc.Driver这个类中的 DriverManager.registerDriver(new Driver()); Class.forName("com.mysql.jdbc.Driver"); //2、获取连接对象 var conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/summer-camp2023?characterEncoding=utf8", "root", "admin"); //3、定义sql //4、需要创建statement var st = conn.prepareStatement(sql); for (int i = 0; i < params.length; i++) { st.setObject(i+1,params[i]); } //5、statement 执行sql,返回 结果集 var rs = st.executeQuery(); //结果集rs得到结果集元数据 ResultSetMetaData md=rs.getMetaData(); //获取结果集总列数 var columnCount = md.getColumnCount(); //6、解析rs while (rs.next()) {//rs.next 读取结果集的光标向下移动一行,光标默认在哪一行,列名所在的那一行 //根据每一行数据,封装成一个实体对象 T t = c.newInstance(); // 1、取出某一行的每个数据,封装到对象t的属性中 for (int i = 1; i <= columnCount; i++) { //通过列的序号,获取每一列的值 var value = rs.getObject(i); if (value!=null){ //通过列的序号,获取每一列的列名 var columnName = md.getColumnName(i); //因为列名和实体类t中的属性名一致,为每一个属性构造一个反射中的set方法 var f = c.getDeclaredField(columnName); //赋予私有属性的赋值权限 f.setAccessible(true); //使用反射,把value给到对象t的属性中 f.set(t,value);//理解为:把value赋值给对象t的ColumName,相当于set方法 } } //把对象存入集合中 tList.add(t); } //7、关闭资源 st.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } return tList; }
查询一行的封装
//查询一行 public static <T> T selectRow(String sql,Class<T> c,Object...params){ //创建一个集合,存放所有的对象 List<T> tList=new ArrayList<>(); try { //1、注册驱动-反射去加载jar包中com.mysql.jdbc.Driver这个类中的 DriverManager.registerDriver(new Driver()); Class.forName("com.mysql.jdbc.Driver"); //2、获取连接对象 var conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/summer-camp2023?characterEncoding=utf8", "root", "admin"); //3、定义sql //4、需要创建statement var st = conn.prepareStatement(sql); //执行前给sql传递参数 for (int i = 0; i < params.length; i++) { st.setObject(i+1,params[i]); } //5、statement 执行sql,返回 结果集 var rs = st.executeQuery(); //结果集rs得到结果集元数据 ResultSetMetaData md=rs.getMetaData(); //获取结果集总列数 var columnCount = md.getColumnCount(); //根据每一行数据,封装成一个实体对象 //6、解析rs T t=null; if (rs.next()) {//rs.next 读取结果集的光标向下移动一行,光标默认在哪一行,列名所在的那一行 t = c.newInstance(); // 1、取出某一行的每个数据,封装到对象t的属性中 for (int i = 1; i <= columnCount; i++) { //通过列的序号,获取每一列的值 var value = rs.getObject(i); if (value!=null){ //通过列的序号,获取每一列的列名 var columnName = md.getColumnName(i); //因为列名和实体类t中的属性名一致,为每一个属性构造一个反射中的set方法 var f = c.getDeclaredField(columnName); //赋予私有属性的赋值权限 f.setAccessible(true); //使用反射,把value给到对象t的属性中 f.set(t,value);//理解为:把value赋值给对象t的ColumName,相当于set方法 } } } //7、关闭资源 st.close(); conn.close(); return t; } catch (Exception e) { e.printStackTrace(); } return null; }
查询一列的封装
//查询一列 public static <T> List<T> selectColumn(String sql,Class<T> c,Object...params){ //创建一个集合,存放所有的对象 List<T> tList=new ArrayList<>(); try { //1、注册驱动-反射去加载jar包中com.mysql.jdbc.Driver这个类中的 DriverManager.registerDriver(new Driver()); Class.forName("com.mysql.jdbc.Driver"); //2、获取连接对象 var conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/summer-camp2023?characterEncoding=utf8", "root", "admin"); //3、定义sql //4、需要创建statement var st = conn.prepareStatement(sql); for (int i = 0; i < params.length; i++) { st.setObject(i+1,params[i]); } //5、statement 执行sql,返回 结果集 var rs = st.executeQuery(); //结果集rs得到结果集元数据 ResultSetMetaData md=rs.getMetaData(); //获取结果集总列数 var columnCount = md.getColumnCount(); //6、解析rs while (rs.next()) {//rs.next 读取结果集的光标向下移动一行,光标默认在哪一行,列名所在的那一行 //通过列的序号,获取每一列的值 T t = (T) rs.getObject(1); //把对象存入集合中 tList.add(t); } //7、关闭资源 st.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } return tList; }
查询单个的封装
//查询单个 public static <T> T selectOne(String sql,Class<T> c,Object...params){ try { //1、注册驱动-反射去加载jar包中com.mysql.jdbc.Driver这个类中的 DriverManager.registerDriver(new Driver()); Class.forName("com.mysql.jdbc.Driver"); //2、获取连接对象 var conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/summer-camp2023?characterEncoding=utf8", "root", "admin"); //3、定义sql var st = conn.prepareStatement(sql); for (int i = 0; i < params.length; i++) { st.setObject(i+1,params[i]); } //5、statement 执行sql,返回 结果集 var rs = st.executeQuery(); //结果集rs得到结果集元数据 ResultSetMetaData md=rs.getMetaData(); //获取结果集总列数 var columnCount = md.getColumnCount(); //6、解析rs T t=null; if (rs.next()) { t = (T) rs.getObject(1); } //7、关闭资源 st.close(); conn.close(); return t; } catch (Exception e) { e.printStackTrace(); } return null; }
增删改封装方法
//增删改 public static int update(String sql,Object...params){ try { //1、注册驱动-反射去加载jar包中com.mysql.jdbc.Driver这个类中的 DriverManager.registerDriver(new Driver()); Class.forName("com.mysql.jdbc.Driver"); //2、获取连接对象 var conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/summer-camp2023?characterEncoding=utf8", "root", "admin"); //3、定义sql //4、需要创建statement var st = conn.prepareStatement(sql); for (int i = 0; i < params.length; i++) { st.setObject(i+1,params[i]); } //5、statement 执行sql,返回 结果集 var i = st.executeUpdate(); //7、关闭资源 st.close(); conn.close(); return i; } catch (Exception e) { e.printStackTrace(); } return 0; }
总的来说,封装只是为了让代码变得更简洁,为后面的开发做铺垫!
本文作者:二价亚铁
本文链接:https://www.cnblogs.com/xw-01/p/17545583.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步