博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【java】对数据库操作的那些事(包含数据库中的预处理)
阅读量:6805 次
发布时间:2019-06-26

本文共 6133 字,大约阅读时间需要 20 分钟。

一、连接问题

前面刚介绍了怎么连接数据库,也写了对应的模板。可是它的可维护性很差。那么怎么解决问题呢?

首先写一个配置文件jdbc.properties

## MySQLdriver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/hncu?

useUnicode=true&characterEncoding=UTF-8 username=root password=1234 ## Oracle #driver=oracle.jdbc.driver.OracleDriver #url=jdbc:oracle:thin:@192.168.31.12:1521:orcl #username=scott #password=tiger </span>

然后创建一个生成连接的工厂ConnFactory .java

package cn.hncu.hibernate0;import java.io.IOException;import java.sql.Connection;import java.sql.DriverManager;import java.util.Properties;public class ConnFactory {	private static Connection conn;	static {		try {			//读取配置文件			Properties p = new Properties();			p.load(ConnFactory.class.getClassLoader().getResourceAsStream("jdbc.properties"));			String driver = p.getProperty("driver");			String url = p.getProperty("url");			String username = p.getProperty("username");			String pwd = p.getProperty("password");						Class.forName(driver);			conn = DriverManager.getConnection(url,username,pwd);			System.out.println("已连接到数据库..."+conn);		} catch (Exception e) {			throw new RuntimeException("读取配置文件失败", e);		}	}	public static Connection getConn(){		return conn;	}	public static void main(String[] args) {		getConn();	}}
最后直接通过ConnFactory.getConn()获得。

这要做的优点,当改变所要连接的数据库类型时,仅仅须要改动配置文件里的内容就可以。

二、解说getXXX()方法

	@Test	public void getXXXDemo() throws Exception{		Statement st = ConnFactory.getConn().createStatement();		String sql = "select * from book";		ResultSet rs = st.executeQuery(sql);		while(rs.next()){			Integer id = rs.getInt(1);//这里的1表示数据表中的第一列,以下同理			String name = rs.getString(2);			//Double price = (Double)rs.getObject(3);//出异常,由于内部是採用BigDecimal来处理			Double price = rs.getDouble(3);			Object dateTime = rs.getObject(4);//把日期和时间作为一个总体读取出来			System.out.println(id+","+name+","+price+","+dateTime);						String strDateTime = dateTime.toString();			System.out.println(strDateTime);			strDateTime = rs.getDate(4)+"--"+rs.getTime(4);//日期和时间能够单独获取			System.out.println(":::"+strDateTime);		}		ConnFactory.getConn().close();	}
注:对于自己主动增长列。删除之后再插入新记录,序号不会回头,继续往前增长。即中间会出现空号

三、解说Statement中的三个executeXXX()方法

1、executeQuery: 仅仅能运行select语句

2、executeUpdate: 能够运行insert、delete和update语句,但不能运行select

3、execute:增删改查的4种(随意)语句都能运行。该方法若运行非select语句时返回false,运行select语句时返回true,且st对象会缓存该次查询的结果。我

们可通过ResultSet rs = st.getResultSet()来获得结果集

	@Test	public void executeXXXDemo() throws Exception{		Statement st = ConnFactory.getConn().createStatement();	    String sql = "select * from book";		//String sql = "insert into book(name,price,pub) values('软件project',22.35,'2015-12-05 22:12:23')";		//String sql = "update book set price=38.88 where name='软件project'";		//String sql = "delete from book where name='软件project'";	    //st.executeQuery(sql);		//st.executeUpdate(sql);		boolean boo = st.execute(sql);				if(boo){			ResultSet rs = st.getResultSet();			while(rs.next()){				System.out.println(rs.getObject(2));			}		}	}

四、数据库查询时防黑技术(预处理语句)

案例、用户登录(通过用户输入信息来拼接sql语句----非常危急)

	@Test//用户登录    	public void login() throws Exception{		Connection con = ConnFactory.getConn();		Statement st = con.createStatement();		Scanner sc = new Scanner(System.in);		int id = sc.nextInt(); sc.nextLine();		String name = sc.nextLine();		String sql = "select count(*) from stud where id="+id+" and sname='"+name+"'";		System.out.println("sql:"+sql);		ResultSet rs = st.executeQuery(sql);		rs.next();		int a = rs.getInt(1);		if(a<=0){			System.out.println("登录不成功");		}else{			System.out.println("登录成功");		}				con.close();	   	}
黑的方法。输入:1002(回车)   1' or '1'='1
因此:假设须要用 用户输入的信息 来拼接 sql语句,就不能用statement。否则用户能够通过构建where子句中的一个true条件来突破防护对于上面的情

况,应该用PreparedStatement来解决!

	@Test//用户登录     黑:1002(回车)   1' or '1'='1	public void login2() throws Exception{		Scanner sc = new Scanner(System.in);				Connection con = ConnFactory.getConn();		String sql = "select count(*) from stud where id=? and sname=?";//须要用户输入的地方,用占位符('?')来取代。然后在兴许通过设參来给占位符赋值		PreparedStatement pst = con.prepareStatement(sql);		//设置參数		int id = sc.nextInt(); sc.nextLine();		pst.setInt(1, id); //參数1----代表第1个占位符		String name = sc.nextLine();		pst.setString(2, name);//參数2				ResultSet rs = pst.executeQuery();				rs.next();		int a = rs.getInt(1);		if(a<=0){			System.out.println("登录不成功");		}else{			System.out.println("登录成功");		}				con.close();	   	}

五、获取自己主动增长列(如id)

	@Test //演示获取自己主动增长列如id	public void saveAuto() throws Exception{		Connection con = ConnFactory.getConn();		String sql = "insert into book(name,price,pub) values('JavaEE',100.8,'2013-06-12 08:30:30')";		Statement st = con.createStatement();				//st.executeUpdate(sql);		st.executeUpdate(sql,Statement.RETURN_GENERATED_KEYS);		ResultSet rs = st.getGeneratedKeys();//里面封装了自己主动生成的全部值		if(rs.next()){			int id = rs.getInt(1);//获取第1个自己主动增长列			System.out.println("自己主动增长的id:"+id);		}		System.out.println("-----------------");				//预处理语句		sql =  "insert into book(name,price) values(?,?)";		PreparedStatement pst = con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);		pst.setString(1, "计算机基础");		pst.setDouble(2, 28);		pst.executeUpdate();		ResultSet rs2 = pst.getGeneratedKeys();//里面封装了自己主动生成的全部值		if(rs2.next()){			int id = rs2.getInt(1);//获取第1个自己主动增长列			System.out.println("自己主动增长的id:"+id);		}	}

六、演示批处理语句

public void batch() throws Exception{		Connection con = ConnFactory.getConn();		String sql = "insert into book(name,price,pub) values('JavaEE',100.8,'2015-06-12 08:30:30')";		Statement st = con.createStatement();		for(int i=0;i<10;i++){			st.addBatch(sql);		}		sql = "update book set price=price*1.1 where price>100";		st.addBatch(sql);		int[] a = st.executeBatch();		for(int r:a){			System.out.println(r);//r为每条sql语句所影响的记录数		}	}
预处理

public void preparedBatch() throws Exception{		Connection con = ConnFactory.getConn();		String sql = "insert into book(name,price,pub) values(?,?,?)";		PreparedStatement pst = con.prepareStatement(sql);		for(int i=0;i<5;i++){			pst.setString(1, "Java"+i);			pst.setDouble(2, 55.85+i);			pst.setString(3, "2016-12-10 07:07:08");			pst.addBatch(); //pst的方式不能带參数sql		}		//pst.executeBatch();		int[] a = pst.executeBatch();		for(int r:a){			System.out.println(r);//r为每条sql语句所影响的记录数		}	}
注意:预处理
的方式不能带參数sql,普通的须要

转载地址:http://esjwl.baihongyu.com/

你可能感兴趣的文章
MDSF:如何使用GMF来做TOGAF建模工具
查看>>
Spring Security简介
查看>>
打造一流的研发中心
查看>>
MCollective架构篇3-Puppet插件的部署及测试
查看>>
配置GNS使用CRT连接
查看>>
Java:集合类性能分析
查看>>
cms无法登陆
查看>>
JavaScript中事件处理
查看>>
VSTO 向office文档中插入内容
查看>>
【百度地图API】关于如何进行城市切换的三种方式
查看>>
How to provide highlighting with Spring data elasticsearch
查看>>
MongoDB 游标
查看>>
即将搭载人工智能芯片的华为Mate10,究竟会为业界带来什么?
查看>>
Android实现登录小demo
查看>>
AgentWeb是基于Android WebView一个功能完善小型浏览器库
查看>>
开放数据中心联盟推8个云计算应用模型
查看>>
学习数据分析的“里程碑”是什么?
查看>>
数据科学与DevOps之间的差距还有救吗?
查看>>
信息化一周回顾:金融业大数据十大趋势
查看>>
Http、TCP/IP协议与Socket之间的区别
查看>>