Table of contents
SQL injection
What is SQL injection
The so-called SQL injection is to insert parameters containing SQL statement fragments into the SQL statement to be executed, and finally achieve SQL commands that trick the database server into performing malicious operations.
SQL injection case
/**
* SQL注入测试类
*/
public class SqlInjectTest {
/**
* 体现sql注入
*/
public void sqlInject(String username,int userage){
Connection connection =null;
Statement statement =null;
ResultSet resultSet =null;
try{
//获取连接
connection = JdbcUtils.getConnection();
//创建Statement对象
statement = connection.createStatement();
//定义sql语句
String sql ="select * from users where username ='"+username+"' and userage = "+userage;
System.out.println(sql);
//执行sql语句
resultSet = statement.executeQuery(sql);
//处理结果集
while(resultSet.next()){
int userid = resultSet.getInt("userid");
String name = resultSet.getString("username");
int age = resultSet.getInt("userage");
System.out.println(userid+" "+name+" "+age);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.closeResource(resultSet,statement,connection);
}
}
public static void main(String[] args) {
SqlInjectTest sit = new SqlInjectTest();
sit.sqlInject("oldlu' or 1=1 --",28);
}
}
Solve SQL injection
public void noSqlInject(String username,int userage){
Connection connection = null;
PreparedStatement ps =null;
ResultSet resultSet = null;
try{
//获取连接
connection = JdbcUtils.getConnection();
//创建PreparedStatement对象
ps = connection.prepareStatement("select * from users where username = ? and userage = ?");
//绑定参数
ps.setString(1,username);
ps.setInt(2,userage);
//执行sql
resultSet = ps.executeQuery();
//处理结果集
while(resultSet.next()){
int userid = resultSet.getInt("userid");
String name = resultSet.getString("username");
int age = resultSet.getInt("userage");
System.out.println(userid+" "+name+" "+age);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.closeResource(resultSet,ps,connection);
}
}
JDBC batch add data
Introduction to batch adding data
In JDBC, the batch insertion of data is performed through the addBatch() and executeBatch() methods of the PreparedStatement object.
addBatch() loads several SQL statements together, and then transmits them to the database for execution at one time, which is to process sql data in batches.
executeBatch() will execute the loaded SQL statements.
Note: MySql does not enable batch processing by default. Since 5.1.13, the database driver has added a parameter processing of rewriteBatchStatement, which enables MySql to start batch processing. Add this parameter in the url: rewriteBatchedStatements=true
Mysql URL parameter description
Realize batch addition of data
Enable batch addition in url
rewriteBatchedStatements=true
Method 1 for batch adding data
/**
* 批量添加数据方式一
*/
public void addBatch1(){
Connection conn = null;
PreparedStatement ps =null;
try{
//创建连接
conn = JdbcUtils.getConnection();
//创建PreparedStatement
ps = conn.prepareStatement("insert into users values(default ,?,?)");
//参数绑定
for(int i=0;i<1000;i++){
//绑定username
ps.setString(1,"ITBZ"+i);
//绑定userage
ps.setInt(2,20);
//缓存sql
ps.addBatch();
}
//执行sql
ps.executeBatch();
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.closeResource(ps,conn);
}
}
Method 2 to realize batch addition of data
/**
* 批量添加数据方式二
*/
public void addBatch2(){
Connection conn = null;
PreparedStatement ps =null;
try{
//创建连接
conn = JdbcUtils.getConnection();
//创建PreparedStatement
ps = conn.prepareStatement("insert into users values(default ,?,?)");
//参数绑定
for(int i=1;i<=1000;i++){
//绑定username
ps.setString(1,"ITBZ"+i);
//绑定userage
ps.setInt(2,20);
//缓存sql
ps.addBatch();
if(i%500 == 0){
//执行sql
ps.executeBatch();
//清除缓存
ps.clearBatch();
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.closeResource(ps,conn);
}
}
JDBC transaction processing
Business Profile
business:
A transaction is a sequence of operations performed as a single logical unit of work that is either fully performed or not performed at all.
Business operation process:
1. Start the transaction
2. Submit the transaction
3. Rollback transaction
Features of transaction processing in JDBC
In JDBC, the Connection object is used to manage transactions, and the default is to automatically commit transactions. You can set whether the transaction is automatically committed through the setAutoCommit(boolean autoCommit) method. The parameter is boolean type, and the default value is true, which means that the transaction is automatically committed. Method rolls back the transaction.
JDBC transaction processing implementation
/**
* 批量添加数据方式二
* 支持事务处理
*/
public void addBatch2(){
Connection conn = null;
PreparedStatement ps =null;
try{
//创建连接
conn = JdbcUtils.getConnection();
//设置事务的提交方式,将自动提交修改为手动提交
conn.setAutoCommit(false);
//创建PreparedStatement
ps = conn.prepareStatement("insert into users values(default ,?,?)");
//参数绑定
for(int i=1;i<=1000;i++){
//绑定username
ps.setString(1,"ITBZ"+i);
//绑定userage
ps.setInt(2,20);
//缓存sql
ps.addBatch();
if(i%500 == 0){
//执行sql
ps.executeBatch();
//清除缓存
ps.clearBatch();
}
if(i==501){
String str = null;
str.length();
}
}
//提交事务
JdbcUtils.commit(conn);
}catch(Exception e){
e.printStackTrace();
JdbcUtils.rollback(conn);
}finally{
JdbcUtils.closeResource(ps,conn);
}
}
Use of the Blob type
Introduction to MySql Blob Type
Blob (full name: Binary Large Object binary large object). In MySql, Blob is a binary data type used to store pictures, files and other data. PreparedStatement must be used to manipulate data of type Blob, because data of type Blob cannot be concatenated with strings. In most cases, it is not recommended to store files directly in the MySQL database, but if the application scenario is that files and data are highly coupled, or file security requirements are high, then storing files and data together is safe and Easy backup and migration.
Blob type in Mysql
There are four types of blobs in MySql, which are consistent except for the maximum storage capacity.
Precautions for using the Blob type
1. In actual use, define different Blob types according to the size of the data to be stored.
2. If the stored files are too large, the performance of the database will decrease.
Insert Blob type data
create table
CREATE TABLE `movie` (
`movieid` int(11) NOT NULL AUTO_INCREMENT,
`moviename` varchar(30) DEFAULT NULL,
`poster` mediumblob,
PRIMARY KEY (`movieid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Store Blob type data through PreparedStatement
/**
* Blob类型操作测试类
*/
public class BlobTest {
/**
* 向Movie表中插入数据
*/
public void insertMovie(String moviename, InputStream is){
Connection conn =null;
PreparedStatement ps =null;
try{
//获取连接
conn = JdbcUtils.getConnection();
//创建PreparedStatement对象
ps = conn.prepareStatement("insert into movie values(default,?,?)");
//绑定参数
ps.setString(1,moviename);
ps.setBlob(2,is);
ps.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.closeResource(ps,conn);
}
}
public static void main(String[] args) throws FileNotFoundException {
BlobTest bt = new BlobTest();
//创建读取文件的IO流
InputStream is = new FileInputStream(new File("d:/1.jpg"));
bt.insertMovie("战狼",is);
}
}
Remove file size limit
Although MediumBlob allows to save a maximum of 16M, the default supported capacity in MySql is 4194304 or 4M. We can expand the supported capacity by modifying the max_allowed_packet attribute in the my.ini file of Mysql. After the modification, the MySql service needs to be restarted.
file location
modify properties
Read Blob type data
/**
* 根据影片ID查询影片信息
* @param movieid
*/
public void selectMovieById(int movieid)
{
Connection conn =null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
//获取连接
conn =JdbcUtils.getConnection();
//创建PreparedStatement对象
ps = conn.prepareStatement("select * from movie where movieid = ?");
//绑定参数
ps.setInt(1,movieid);
//执行sql
rs = ps.executeQuery();
while(rs.next()){
int id = rs.getInt("movieid");
String name = rs.getString("moviename");
System.out.println(id+" "+name);
//获取blob类型的数据
Blob blob = rs.getBlob("poster");
//获取能够从Blob类型的列中读取数 据的IO流
InputStream is = blob.getBinaryStream();
//创建文件输出字节流对象
OutputStream os = new FileOutputStream(id+"_"+name+".jpg");
//操作流完成文件的输出处理
byte[] buff = new byte[1024];
int len;
while((len = is.read(buff)) != -1){
os.write(buff,0,len);
}
os.flush();
is.close();
os.close();
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.closeResource(rs,ps,conn);
}
}
Other query methods
fuzzy query
Implement fuzzy query
/**
* 模糊查询测试类
*/
public class FuzzyQueryTest {
/**
* 根据用户名称模糊查找用户信息
*/
public List<Users> fuzzyQuery(String username){
List<Users> list= new ArrayList<>();
Connection conn =null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
//获取数据库连接
conn = JdbcUtils.getConnection();
//创建PreparedStatement对象
ps = conn.prepareStatement("select * from users where username like ?");
//参数绑定
ps.setString(1,username);
//执行sql语句
rs = ps.executeQuery();
while(rs.next()){
Users user = new Users();
user.setUserid(rs.getInt("userid"));
user.setUsername(rs.getString("username"));
user.setUserage(rs.getInt("userage"));
list.add(user);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.closeResource(rs,ps,conn);
}
return list;
}
public static void main(String[] args) {
FuzzyQueryTest ft = new FuzzyQueryTest();
List<Users> users = ft.fuzzyQuery("%d%");
for(Users user1:users){
System.out.println(user1.getUserid()+""+user1.getUsername()+" "+user1.getUserage());
}
}
}
dynamic query
Realization of dynamic condition query
/**
* 动态条件查询测试类
*/
public class DynamicConditionQueryTest {
/**
* 动态条件查询Users
*/
public List<Users> queryUsers(Users users){
List<Users> list= new ArrayList<>();
Connection conn =null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
//获取数据库连接
conn = JdbcUtils.getConnection();
//拼接查询SQL语句
String sql = this.generateSql(users);
System.out.println(sql);
//创建PreparedStatement对象
ps = conn.prepareStatement(sql);
//执行sql语句
rs = ps.executeQuery();
while(rs.next()){
Users user = new Users();
user.setUserid(rs.getInt("userid"));
user.setUsername(rs.getString("username"));
user.setUserage(rs.getInt("userage"));
list.add(user);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.closeResource(rs,ps,conn);
}
return list;
}
/**
* 生成动态条件查询sql
*/
private String generateSql(Users users){
StringBuffer sb = new StringBuffer("select * from users where 1=1");
if(users.getUserid() > 0){
sb.append(" and userid = ").append(users.getUserid());
}
if(users.getUsername() !=null &&users.getUsername().length() > 0){
sb.append(" and username = '").append(users.getUsername()).append("'");
}
if(users.getUserage() > 0){
sb.append(" and userage = ").append(users.getUserage());
}
return sb.toString();
}
public static void main(String[] args) {
DynamicConditionQueryTest dt = new DynamicConditionQueryTest();
Users users = new Users();
users.setUsername("Oldlu");
users.setUserage(20);
List<Users> list = dt.queryUsers(users);
for(Users user1:list){
System.out.println(user1.getUserid()+""+user1.getUsername()+" "+user1.getUserage());
}
}
}