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 ...
随机推荐
- TOP 10开源的推荐系统简介
最近这两年推荐系统特别火,本文搜集整理了一些比较好的开源推荐系统,即有轻量级的适用于做研究的SVDFeature.LibMF.LibFM等,也有重量级的适用于工业系统的 Mahout.Oryx.Eas ...
- Linux-Gcc生成和使用静态库和动态库详解
一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...
- include指令和<jsp:include>标准动作
利用JSP的包含机制,可以有效的避免重复,把可重用的部分独立出去,使用include把它们包含到当前文件.JSP有两种包含机制:include指令和<jsp:include>标准动作. 1 ...
- 蓝桥杯 algo_5 最短路 (bellman,SPFA)
问题描述 给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环).请你计算从1号点到其他点的最短路(顶点从1到n编号). 输入格式 第一行两个整数n, m. 接下来的m行,每行有三个 ...
- CSS引入外部字体
@font-face { font-family: '综艺体'; font-style: normal; font-weight: normal; src: url(../cs ...
- 一张图告诉你为什么 Gmail 是最好的邮箱,以及大量私货
今天早上,我的同事详细介绍了 Gmail 相比其他邮箱的优势,比如强大的垃圾邮件过滤.简单的使用界面.强大的功能设置等等.但是对我来说,这些并不是我使用 Gmail 的最重要原因. 我第一个正式的邮箱 ...
- SharePoint 2013 Nintex Workflow 工作流帮助(七)
博客地址 http://blog.csdn.net/foxdave 工作流动作 11. Check out item(Libraries and lists分组) 与上一个对应,用于签出条目.如果一个 ...
- PHP time() 函数
定义和用法 time() 函数返回当前时间的 Unix 时间戳. 语法 time(void) 参数 描述 void 可选. 说明 返回自从 Unix 纪元(格林威治时间 1970 年 1 月 1 日 ...
- explain分析查询
参考以下文章,在此非常感谢原作者 explain分析查询
- (转)Position定位:relative | absolute
原文:http://hi.baidu.com/zxc0420/item/9ada5110845ba1e89c778a08 Position定位:relative | absolute 定位一直是WEB ...