mysql之数据库连接的方法封装及防sql注入
一、定义数据库和表
create database animal;
CREATE TABLE `pet` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`owner` varchar(20) DEFAULT NULL,
`species` varchar(20) DEFAULT NULL,
`sex` char(1) DEFAULT NULL,
`birth` date DEFAULT NULL,
`death` date DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8;
二、连接数据库并定义数据库操作基本方法的几个工具类
(1)数据库连接及查询更新操作的封装
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
/**
* 模拟单例模式
* */
public class DBConn {
// 定义connection对象
private static Connection conn;
// 私有构造函数
private DBConn() {
}
// 返回连接对象
public static Connection getConn() {
if (conn == null) {
try {
long startTime = System.currentTimeMillis();
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager
.getConnection("jdbc:mysql://localhost:3306/animal?user=root&generateSimpleParameterMetadata=true&password=root&useUnicode=true&characterEncoding=UTF-8");
long endTime = System.currentTimeMillis();
System.out.println("耗时的操作:" + (endTime - startTime));
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
return conn;
}
// 更新的封装操作
public static boolean update(String sql, Object args[]) {
// 1.声明返回值变量
boolean flag = false;
// 2.获取预处理对象
PreparedStatement pstmt = null;
try {
pstmt = getConn().prepareStatement(sql);
// 3.为占位符赋值
int index = 1;
// 4.遍历赋值
for (Object arg : args) {
pstmt.setObject(index++, arg);
}
// 5.执行sql语句
int num = pstmt.executeUpdate();
if (num > 0) {
flag = true;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
DBConn.release(null, pstmt);
}
return flag;
}
// 查找的封装操作
public static <T> List<T> query(String sql, Object args[],
IResultSetHandle<T> irsh) {
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = getConn().prepareStatement(sql);
if (args != null) {
int index = 1;
for (Object arg : args) {
pstmt.setObject(index++, arg);
}
}
rs = pstmt.executeQuery();
//交给别人处理
return irsh.handle(rs);
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBConn.release(rs, pstmt);
}
return null;
}
// 释放资源
public static void release(ResultSet rs, PreparedStatement stmt) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
(2)定义IResultSetHandle接口供DBConn实现
import java.sql.ResultSet;
import java.util.List;
public interface IResultSetHandle<T> {
List<T> handle(ResultSet rs);
}
(3)日期转换
public class DateUtil {
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
public static String DateToStr(Date date) {
return sdf.format(date);
}
}
三、定义实体类
public class Pet implements Serializable{
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private String owner;
private String species;
private String sex;
private Date birth;
private Date death;
public Pet() {
super();
// TODO Auto-generated constructor stub
}
public Pet(Integer id, String name, String owner, String species,
String sex, Date birth, Date death) {
super();
this.id = id;
this.name = name;
this.owner = owner;
this.species = species;
this.sex = sex;
this.birth = birth;
this.death = death;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Date getDeath() {
return death;
}
public void setDeath(Date death) {
this.death = death;
}
@Override
public String toString() {
return "Pet [id=" + id + ", name=" + name + ", owner=" + owner
+ ", species=" + species + ", sex=" + sex + ", birth=" + birth
+ ", death=" + death + "]";
}
}
四、对实体Bean操作的接口封装
public interface PetDao {
//插入实体
boolean insert(Pet entity);
//更新实体
boolean update(Pet entity);
//删除实体
boolean delete(Pet entity);
//根据id删除实体
boolean delete(Integer id);
//根据id、查询实体
Pet getObjectById(Integer id);
//查询所有实体
List<Pet> getObjects();
//根据用户查询实体
List<Pet> getObjectsByOwner(String owner);
}
五、对实体Bean操作接口的实现
public class PetDaoImpl implements PetDao {
@Override
public boolean insert(Pet entity) {
String sql = "insert into pet(name,owner,species,sex,birth,death)values(?,?,?,?,?,?)";
return DBConn.update(
sql,
new Object[] { entity.getName(), entity.getOwner(),
entity.getSpecies(), entity.getSex(),
entity.getBirth(), entity.getDeath() });
}
@Override
public boolean update(Pet entity) {
String sql = "update pet set name=?,owner=?,species=?,sex=?,birth=?,death=? where id=?";
return DBConn.update(sql,new Object[] { entity.getName(), entity.getOwner(),
entity.getSpecies(), entity.getSex(),
entity.getBirth(), entity.getDeath(), entity.getId() });
}
@Override
public boolean delete(Pet entity) {
return delete(entity.getId());
}
@Override
public boolean delete(Integer id) {
String sql = "delete from pet where id=?";
return DBConn.update(sql, new Object[] { id });
}
@Override
public Pet getObjectById(Integer id) {
String sql = "select id,name,owner,species,sex,birth,death from pet where id=?";
return (Pet) DBConn.query(sql, new Object[]{id}, new IResultSetHandle<Pet>() {
@SuppressWarnings("rawtypes")
public List<Pet> handle(ResultSet rs) {
List<Pet> entities=new ArrayList<Pet>();
Class cls=Pet.class;
try {
while(rs.next()){
Pet pet=(Pet) cls.newInstance();
//Field[] field=cls.getDeclaredFields();
for(int i=0;i<rs.getMetaData().getColumnCount();i++){
//Field f=field[i];
Field f=cls.getDeclaredField(rs.getMetaData().getColumnName(i+1));
//暴力操作
f.setAccessible(true);
f.set(pet, rs.getObject(i+1));
}
entities.add(pet);
}
} catch (Exception e) {
e.printStackTrace();
}
return entities;
}
}).get(0);
}
@Override
public List<Pet> getObjects() {
String sql = "select id,name,owner,species,sex,birth,death from pet ";
return DBConn.query(sql, null, new IResultSetHandle<Pet>() {
public List<Pet> handle(ResultSet rs) {
List<Pet> entities=new ArrayList<Pet>();
@SuppressWarnings("rawtypes")
Class cls=Pet.class;
try {
while(rs.next()){
Pet pet=(Pet) cls.newInstance();
//Field[] field=cls.getDeclaredFields();
for(int i=0;i<rs.getMetaData().getColumnCount();i++){
//Field f=field[i];
Field f=cls.getDeclaredField(rs.getMetaData().getColumnName(i+1));
f.setAccessible(true);
f.set(pet,rs.getObject(i+1));
}
entities.add(pet);
}
} catch (Exception e) {
e.printStackTrace();
}
return entities;
}
});
}
@Override
public List<Pet> getObjectsByOwner(String owner) {
String sql = "select id,name,owner,species,sex,birth,death from pet where owner=?";
return DBConn.query(sql, new Object[]{owner}, new IResultSetHandle<Pet>() {
public List<Pet> handle(ResultSet rs) {
List<Pet> entities=new ArrayList<Pet>();
@SuppressWarnings("rawtypes")
Class cls=Pet.class;
try {
while(rs.next()){
Pet pet=(Pet)cls.newInstance();
//Field[] field=cls.getDeclaredFields();
for(int i=0;i<rs.getMetaData().getColumnCount();i++){
//Field f=field[i];
Field f=cls.getDeclaredField(rs.getMetaData().getColumnName(i+1));
f.setAccessible(true);
f.set(pet, rs.getObject(i+1));
}
entities.add(pet);
}
} catch (Exception e) {
e.printStackTrace();
}
return entities;
}
});
}
}
六、防sql注入的测试
@Test
public void test() {
List<Pet> entities=petDao.getObjectsByOwner("' or '1'='1'");
for(Pet en:entities){
System.out.println(en.toString());
}
}
如果使用以下方法则会被注入
@Override
public Pet getObjectById(Integer id) {
Pet entity = null;
conn = DBConn.getConn();
String sql = "select id,name,owner,species,sex,birth,death from pet where id=?";
try {
pstmt = conn.prepareStatement(sql);
int index = 1;
pstmt.setObject(index++, id);
rs = pstmt.executeQuery();
if (rs.next()) {
entity = new Pet();
entity.setId(rs.getInt("id"));
entity.setName(rs.getString("name"));
entity.setOwner(rs.getString("owner"));
entity.setSpecies(rs.getString("species"));
entity.setSex(rs.getString("sex"));
entity.setBirth(rs.getDate("birth"));
entity.setDeath(rs.getDate("death"));
}
DBConn.release(rs, pstmt);
} catch (SQLException e) {
e.printStackTrace();
}
return entity;
}
mysql之数据库连接的方法封装及防sql注入的更多相关文章
- C#防SQL注入代码的实现方法
对于网站的安全性,是每个网站开发者和运营者最关心的问题.网站一旦出现漏洞,那势必将造成很大的损失.为了提高网站的安全性,首先网站要防注入,最重要的是服务器的安全设施要做到位. 下面说下网站防注入的几点 ...
- .Net防sql注入的方法总结
#防sql注入的常用方法: 1.服务端对前端传过来的参数值进行类型验证: 2.服务端执行sql,使用参数化传值,而不要使用sql字符串拼接: 3.服务端对前端传过来的数据进行sql关键词过来与检测: ...
- 【荐】PDO防 SQL注入攻击 原理分析 以及 使用PDO的注意事项
我们都知道,只要合理正确使用PDO,可以基本上防止SQL注入的产生,本文主要回答以下几个问题: 为什么要使用PDO而不是mysql_connect? 为何PDO能防注入? 使用PDO防注入的时候应该特 ...
- PHP防SQL注入不要再用addslashes和mysql_real_escape_string
PHP防SQL注入不要再用addslashes和mysql_real_escape_string了,有需要的朋友可以参考下. 博主热衷各种互联网技术,常啰嗦,时常伴有强迫症,常更新,觉得文章对你有帮助 ...
- 【转载】C#防SQL注入过滤危险字符信息
不过是java开发还是C#开发或者PHP的开发中,都需要关注SQL注入攻击的安全性问题,为了保证客户端提交过来的数据不会产生SQL注入的风险,我们需要对接收的数据进行危险字符过滤来防范SQL注入攻击的 ...
- 回头探索JDBC及PreparedStatement防SQL注入原理
概述 JDBC在我们学习J2EE的时候已经接触到了,但是仅是照搬步骤书写,其中的PreparedStatement防sql注入原理也是一知半解,然后就想回头查资料及敲测试代码探索一下.再有就是我们在项 ...
- golang 防SQL注入 基于反射、TAG标记实现的不定参数检查器
收到一个任务,所有http的handler要对入参检查,防止SQL注入.刚开始笨笨的,打算为所有的结构体写一个方法,后来统计了下,要写几十上百,随着业务增加,以后还会重复这个无脑力的机械劳作.想想就l ...
- SpringBoot微服务电商项目开发实战 --- api接口安全算法、AOP切面及防SQL注入实现
上一篇主要讲了整个项目的子模块及第三方依赖的版本号统一管理维护,数据库对接及缓存(Redis)接入,今天我来说说过滤器配置及拦截设置.接口安全处理.AOP切面实现等.作为电商项目,不仅要求考虑高并发带 ...
- sql注入和防sql注入
sql注入: from pymysql import * def main(): # 创建连接 conn = connect(host="127.0.0.1", port=3306 ...
随机推荐
- POJ 2559 Program C
Submit Status Practice POJ 2559 Description A histogram is a polygon composed of a sequence of recta ...
- 关于Integer缓冲
默认的时候,-128--127范围内的数会被缓冲 但是jvm启动的时候可以修改启动参数-Djava.lang.Integer.IntegerCache.high=2000 来修改上限,但是下限是不可以 ...
- Spring学习笔记之初始化和销毁方法的调用次序
Multiple lifecycle mechanisms configured for the same bean, with different initialization methods, a ...
- 虚拟机安装Centos版本的linux
选择自定义安装,然后一路确定下去,对了,Centos的版本一定要高,比如centos 6,太低安装会出问题
- 隐藏与显示:display/visibility/visible区别
说到标签的隐藏,你们会用到什么呢?display?visibility?还是服务器控件的visible? 显然,这三者都能起到隐藏与显示的效果,但是用途确完全不一样,请看用法与区别: <div ...
- julia生成指定格式的字符串.jl
julia生成指定格式的字符串.jl """ julia生成指定格式的字符串.jl http://bbs.bathome.net/thread-39829-1-1.htm ...
- Tomcat的安装(一)
一.Tomcat文件下载类型 1.tar.gz 文件是linux的安装包 2.exe文件是Windows系统的安装包 3.zip文件是Windows系统下压缩版(解压缩即可,免安装) 二.下面使用zi ...
- ld can't link with a main executable file for architecture armv7
在iPhone 6 Plus上跑的时候遇到了这么一个错误:ld can't link with a main executable file for architecture armv7,然后就各种改 ...
- GSM cell phone calls use outdated encryption that can now be cracked with rainbow tables on a PC
Decrypting GSM phone calls Motivation. GSM telephony is the world’s most popular communication techn ...
- 一个Android Socket的例子
1.开篇简介 Socket本质上就是Java封装了传输层上的TCP协议(注:UDP用的是DatagramSocket类).要实现Socket的传输,需要构建客户端和服务器端.另外,传输的数据可以是字符 ...