反射封装
sql语句由字符串拼接而成时,当条件后面加上 or true,就会发生sql注入,如: username=“a’ or ‘1=1’ ”,这样就会使条件恒为true,为避免这样,可以使用statement的子类preparedStatement
preparedStatement的作用
- 提前传入sql,执行的时候,不传入sql
- 解决sql注入漏洞
- 支持转入sql中的参数
- 提高效率
Object…params(可变形参数组)
作用:再调用函数时,可以传入任意个任意类型的参数
-
Object…params必须将它放到函数最后,否则将出现错误,原因是数组将其他参数化为了自己的,而其他参数将无值
查询多行多列
public static <T> ArrayList<T> list(String sql, Class<T> c,Object...params) {
ArrayList<T> list = new ArrayList<T>();
try {
//注册驱动-反射去加载jar包中com.mysql。jdbcDriver这个类的DriverManager.registerDriver()
Class.forName("com.mysql.jdbc.Driver");
//获取连接对象
Connection con= DriverManager.getConnection("jdbc:mysql://localhost:3307/camp-2023?characterEncoding=utf8","root","root");
System.out.println(con);
//需要创建statement
PreparedStatement preparedStatement = con.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
preparedStatement.setObject(i+1,params[i]);
}
//statement执行sql,返回结果集
ResultSet rs = preparedStatement.executeQuery();
//结果集rs得到结果集元数据
ResultSetMetaData md = rs.getMetaData();
//获取结果集的总列数
int columnCount = md.getColumnCount();
//解析
while(rs.next()) {//读取结果集的光标向下移动一行,光标默认在哪一行,列名所在的哪一行
//根据每一行数据,封装成一个实体对象
T t=c.newInstance();
//取出某一行的每一列数据,封装到对象t的属性中
for (int i = 1; i <columnCount ; i++) {
//通过列的序号,获取每一列的值
Object value= rs.getObject(i);
if(value !=null) {
//通过列的序号,获取每一列的名
String columnName = md.getColumnName(i);
//因为列名和实体类t中的属性名一致,为每一个属性构造一个反射中的set方法
Field f = c.getDeclaredField(columnName);
//赋予私有属性的赋值权限
f.setAccessible(true);
//使用反射,把value给到对象t的属性中
f.set(t, value);//理解为:把value赋值给对象的columName属性,相当于set方法
}
}
list.add(t);
}
//关闭资源
preparedStatement.close();
con.close();
}catch (Exception e){
e.printStackTrace();
}
return list;
}
查询一行
public static <T> T selectRow(String sql, Class<T> c,Object...params) {
try {
//注册驱动-反射去加载jar包中com.mysql。jdbcDriver这个类的DriverManager.registerDriver()
Class.forName("com.mysql.jdbc.Driver");
//获取连接对象
Connection con= DriverManager.getConnection("jdbc:mysql://localhost:3307/camp-2023?characterEncoding=utf8","root","root");
System.out.println(con);
//需要创建statement
PreparedStatement preparedStatement = con.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
preparedStatement.setObject(i+1,params[i]);
}
//statement执行sql,返回结果集
ResultSet rs = preparedStatement.executeQuery();
//结果集rs得到结果集元数据
ResultSetMetaData md = rs.getMetaData();
//获取结果集的总列数
int columnCount = md.getColumnCount();
T t=null;
//解析
if (rs.next()) {//读取结果集的光标向下移动一行,光标默认在哪一行,列名所在的哪一行
//根据每一行数据,封装成一个实体对象
t=c.newInstance();
//取出某一行的每一列数据,封装到对象t的属性中
for (int i = 1; i < columnCount; i++) {
//通过列的序号,获取每一列的值
Object value = rs.getObject(i);
if (value != null) {
//通过列的序号,获取每一列的名
String columnName = md.getColumnName(i);
//因为列名和实体类t中的属性名一致,为每一个属性构造一个反射中的set方法
Field f = c.getDeclaredField(columnName);
//赋予私有属性的赋值权限
f.setAccessible(true);
//使用反射,把value给到对象t的属性中
f.set(t, value);//理解为:把value赋值给对象的columName属性,相当于set方法
}
}
}
//关闭资源
preparedStatement.close();
con.close();
return t;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
查询一列
public static <T> ArrayList<T> selectColumn(String sql, Class<T> c,Object...params) {
ArrayList<T> list = new ArrayList<T>();
try {
//注册驱动-反射去加载jar包中com.mysql。jdbcDriver这个类的DriverManager.registerDriver()
Class.forName("com.mysql.jdbc.Driver");
//获取连接对象
Connection con= DriverManager.getConnection("jdbc:mysql://localhost:3307/camp-2023?characterEncoding=utf8","root","root");
System.out.println(con);
//需要创建statement
PreparedStatement preparedStatement = con.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
preparedStatement.setObject(i+1,params[i]);
}
//statement执行sql,返回结果集
ResultSet rs = preparedStatement.executeQuery();
//结果集rs得到结果集元数据
ResultSetMetaData md = rs.getMetaData();
//获取结果集的总列数
int columnCount = md.getColumnCount();
//解析
while (rs.next()) {//读取结果集的光标向下移动一行,光标默认在哪一行,列名所在的哪一行
//取出某一行的每一列数据,封装到对象t的属性中
//通过列的序号,获取每一列的值
T t=(T) rs.getObject(1);
list.add(t);
}
//关闭资源
preparedStatement.close();
con.close();
}catch (Exception e){
e.printStackTrace();
}
return list;
}
查询单个
public static <T> T selectOne(String sql, Class<T> c,Object...params) {
try {
//注册驱动-反射去加载jar包中com.mysql。jdbcDriver这个类的DriverManager.registerDriver()
Class.forName("com.mysql.jdbc.Driver");
//获取连接对象
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3307/camp-2023?characterEncoding=utf8", "root", "root");
System.out.println(con);
//需要创建statement
PreparedStatement preparedStatement= con.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
preparedStatement.setObject(i+1,params[i]);
}
//statement执行sql,返回结果集
ResultSet rs = preparedStatement.executeQuery();
//结果集rs得到结果集元数据
ResultSetMetaData md = rs.getMetaData();
//获取结果集的总列数
int columnCount = md.getColumnCount();
//解析
T t =null;
if (rs.next()){
t= (T)rs.getObject(1);
}
//通过列的序号,获取每一列的值
//关闭资源
preparedStatement.close();
con.close();
return t;
}catch (Exception e){
e.printStackTrace();
}
return null;
}