JDBC详解
1,MySQL的乱码解决UTF-8
1)通过sql语句修改编码方式:a,修改某个数据表的编码ALTER TABLE table_name CHARACTER SET utf8;
b,创建数据库的时候指定编码方式:CREATE DATABASE some_database CHARACTER SET utf8;
2)从配置文件修改编码:my.ini文件下default-character-set=utf8
3)URL中指定编码方式:Connection conn = DriverManager.getConnection(“jdbc:mysql://localhost:3306/databaseWeb?unicode=true&characterEncodeing=UTF-8”,”root”,”admin”);
2,JDBC基本操作:CRUD
数据库程序常被称为CRUD程序,因为它包括数据的创建Create, 读取查询Read,更新Update,删除Delete等操作,其首字母缩写便是CRUD。
2.1查询数据库
查询数据库遵循固定的流程:
加载jdbc驱动程序
Class.forName(“com.mysql.jdbc.Driver”);
获取Connection连接
public static final String url = "jdbc:mysql://127.0.0.1/student";
public static final String user = "root";
public static final String password = "root";
Connection conn = DriverManager.getConnection(url, user, password);//获取连接
创建Statement对象
用来向数据库发送查询和命令,它由Connection的createStatement方法创建,其代码如下:
Statement statement=conn.createStatement();
查询数据库返回ResultSet对象
String sql = “select * from tb_test”
ResultSet rs =statement.executeQuery(sql);
遍历ResultSet输出数据
处理结果最简单的方式是使用ResultSet的next方法在表中移动,每次移动一行,在每一行中,ResultSet提供了各种getX方法。它们都以列名或索引为参数,有各种不同的Java类型返回结果。
While(rs.next()){
Int id = rs.getInt(“id”);
String name = rs.getString(“name”);
}
关闭ResultSet
Finally{
If(rs != null)
rs.close();
关闭Statement
If(statement != null)
Statement.close();
关闭Connection
If(conn != null)
Conn.close();
2.2,插入人员信息
Java程序也可以执行INSERT语句往数据库插入数据,方法仍然是使用Statement对象,不过执行INSERT语句时要使用executeUpdate(String sql)方法而不是executeQuery(String sql)方法。executeUpdate()方法用于执行INSERT , UPDATE , DELETE 等,返回数据库中影响的行数,返回int类型。而executeQuery()方法用于执行SELECT,返回查询到的结果集,返回ResultSet类型。
Result = stmt.executeUpdate(sql); //执行insert sql语句,返回影响行数
2.3,获取自动插入的ID
Statement提供getGeneratedKeys()方法以ResultSet方式返回所有自动生成的健值,遍历该ResultSet对象便可得到插入行的id。
Rs =stmt.getGeneratedKeys(); //获取自动生成的键值
Rs.next(); //滚动到下一列
2.4,删除人员信息
删除数据使用Statement的executeUpdate(String sql)方法执行DELETE语句。与INSERT不同的是,DELETE必须使用WHERE条件指定删除哪一行数据,否则将删除所有数据。对于有主键的表来说,可以使用主键来标识哪一行数据,因为主键是唯一的,不可重复的。
2.5,修改人员数据
相对于插入删除,修改要麻烦多,修改数据需要先把原来的数据呈现出来,客户做出修改后再保存数据。
2.6使用PreparedStatement
使用Statement 是最简单的方式,只需要组织出正确的SQL语句,然后执行executeQuery或者executeUpdate就可以了。
PreparedStatement接口继承自Statment接口,是Statement的子类,因此拥有Statement接口的所有方法,例如执行executeUpdate() , executeQuery , getGeneratedKeys()等
PreparedStatement与Statement的最大区别是PreparedStatement可以使用参数,也就是(?)号。PreparedStatement允许使用不完整的SQL语句,空缺的部分使用问号代替,直到执行前的时候设置进去。
String sql = “UPDATE tb_test set name = ? ,sex = ? , age = ? , birthday = ? where id = ?”;
PreparedStatement preStmt = conn.prepareStatement(sql); // 预编译带参数SQL语句
preStmt.setString(1,name); //设置第1个参数
preStmt.setString(2,sex); //设置第2个参数
preStmt.setInt(3,Integer.parsetInt(age)); //设置第3个参数
preStmt.setDate(4,date); //设置第4个参数
preStmt.setInt(5,Integer.parseInt(id)); //设置第5个参数
Int result = praStmt.executeUpdate(sql); //执行SQL语句
2.7,Statement批处理SQL
Statement与PreparedStatement都能够批处理SQL语句,也就是同时执行多条SQL语句。这些SQL语句必须是INSERT , UPDATE , DELETE等SQL语句,他们执行后都返回一个int类型数,表示影响的行数。Statement与PreparedStatement通过addBatch()方法添加一条SQL语句,通过executeBatch()方法批量执行SQL语句,返回一个int数组,代表各句SQL的返回值,先看Statement执行批处理语句的例子:
Statement Stmt = conn.createStatement();
For(int i = 0; i<5; i++){
String sql = “insert into tb_test (name,age,sex,birthday) values (‘name’ + i +”’,’17”, ‘男’ , current_date()”)”;
Stmt.addBatch(sql); //批量添加
}
Int[] result = stmt.executeBatch(); //批量执行将每一句SQL执行结果组成int[]数组
2.8,PreparedStament批处理SQL
String sql =”insert into tb_test (name , age , sex , birthday) values (?,?,?,?);”
PreparedStament preStmt = conn.PreparedStament(sql);
For (int i = 0 ; i < 5 ; i++){
Int index = 1;
preStmt.setString (index ++ , “name” + i); //设置第一个参数
PreStmt.setInt(index ++ , 25+ i);
preStmt.setString (index ++ , “男”);
preStmt.setString (index ++ , new java.sql.Date(System.currentTimeMillis()));
preStmt.addBatch();
}
Int[] result = preStmt.executeBatch();
3,处理结果集
查询结果都保持在ResultSet结果集中,遍历结果集便可取到数据
3.1,查询多个结果集
查询多个表格可以使用同一个Statement或者PreparedStatement实现,返回同一个ResultSet对象,例如:
rs = stmt.executeQuery(“select * from 表格一”);
While (rs.next()){
.....//遍历ResultSet
}
//中间不需要执行rs.close(),JDBC默认自动关闭前一次查询的ResultSet
rs = stmt.executeQuery(“select * from 表格二”))
While (rs.next()){
.....//遍历ResultSet
}
3.2,可以滚动的结果集
除了常用的next()方法,ResultSet接口还有其他的方法,比如previous() , first() , last() 等。如果后面还有记录,next()会返回true,同时自动向下滚动一条记录,否则返回false。Previous()方法刚刚好相反,如果前面还有记录,previous()会返回true,同时自动向上滚动一条记录,否则返回false。First()是滚动到第一条记录,如果第一条记录存在的话。last()是滚动到最后一条记录。
3.3,pagination分页显示
MySQL中实现分页是利用LIMIT实现的,例如“SELECT * FROM tb_test LIMIT 21,10”只取出从第21行开始的10行记录。
分页显示需要先查询记录总数,执行如SELECT count(*) FROM tb_test 的SQL语句,将返回包含总记录数的只有一行一列的ResultSet.然后计算总页数,本页第一条记录的在数据库中的行数等。当前的页数将作为地址栏参数传递给服务器。
分页显示还要生成导航栏的信息,比如第一页,上一页,下一页,最后一页等,
3.4带条件的查询
3.5,ResultSetMetaData元数据
3.6直接显示中文列名
4,JDBC高级应用
4.1,DAO模式与Java Bean
DAO(数据库操作对象,Database Access Object) 是JDBC下常用的模式,保存数据是它将Java Bean 的属性拆分成正确的SQL语句,并保存到数据库中;读取数据库时将数据从数据库中读取出来,并通过setter方法设置到Java Bean中。
4.2,事务实例:转账
数据库时具有事务性的,这是数据库不同于其他存储方式的区别之一。
事务有两个结果,提交(Commit)与回滚(Rollback).如果两步没有错就可以提交。
Conn.setAutoCommit(false)将自动提交设置为false
Conn.commit()
Conn.rollback()
4.3,存储二进制数据
MySQL提供了BLOB类型字段用于存储二进制数据。
4.4,数据源(连接池)