软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 数据库 -> 【java】对数据库操作的那些事(包括数据库中的预处理) -> 正文阅读
数据库 最新文章
Python&MySQL&PyQt
最新用python来操作mysql完全解析
mongodb的安装详解
1.PDO简介
《MySQL必知必会学习笔记》:高级联结
【翻译自mos文章】怎么对Microsoft(Office)
MyCAT全局表描述及示例
ocp
关于SQL数据表存储过程表名前缀换成dbo代码
数据库调优教程(二)慢查询数据准备

[数据库]【java】对数据库操作的那些事(包括数据库中的预处理)

  2016-03-28 21:48:29

一、连接问题


前面刚介绍了怎么连接数据库,也写了相应的模板,但是它的可维护性非常差,那么怎么解决这个问题呢?
首先写一个配置文件jdbc.properties
<span style="font-size:18px;">## MySQL
driver=com.mysql.jdbc.Driver
url=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

<span style="font-size:18px;">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();
	}
}
</span>
最后直接通过ConnFactory.getConn()获得。这要做的好处,当改变所要连接的数据库类型时,只需要修改配置文件中的内容即可。



二、讲解getXXX()方法


<span style="font-size:18px;"><span style="white-space:pre">	</span>@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();
	}</span>
注:对于自动增长列,删除之后再插入新记录,序号不会回头,继续往前增长。即中间会出现空号


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


1、executeQuery: 只能执行select语句
2、executeUpdate: 可以执行insert、delete和update语句,但不能执行select
3、execute:增删改查的4种(任意)语句都能执行。该方法若执行非select语句时返回false,执行select语句时返回true,且st对象会缓存该次查询的结果,我
们可通过ResultSet rs = st.getResultSet()来获得结果集

<span style="font-size:18px;"><span style="white-space:pre">	</span>@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('软件工程',22.35,'2015-12-05 22:12:23')";
		//String sql = "update book set price=38.88 where name='软件工程'";
		//String sql = "delete from book where name='软件工程'";
	    //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));
			}
		}
	}</span>



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


案例、用户登录(通过用户输入信息来拼接sql语句----很危险)
<span style="font-size:18px;"><span style="white-space:pre">	</span>@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();	   
	}</span>
黑的方法,输入:1002(回车)   1' or '1'='1
因此:如果需要用 用户输入的信息 来拼接 sql语句,就不能用statement,否则用户可以通过构建where子句中的一个true条件来突破防护对于上面的情

况,应该用PreparedStatement来解决!

<span style="font-size:18px;"><span style="white-space:pre">	</span>@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();	   
	}</span>



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

<span style="font-size:18px;"><span style="white-space:pre">	</span>@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);
		}
	}</span>

六、演示批处理语句


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,普通的需要




































上一篇文章      下一篇文章      查看所有文章
2016-03-28 21:48:11  
360图书馆 论文大全 母婴/育儿 软件开发资料 网页快照 文字转语音 购物精选 软件 美食菜谱 新闻中心 电影下载 小游戏 Chinese Culture
生肖星座解梦 人民的名义 人民的名义在线看 三沣玩客 拍拍 视频 开发 Android开发 站长 古典小说 网文精选 搜图网 天下美图
中国文化英文 多播视频 装修知识库
2017-4-26 17:50:59
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --