1.JDBC 基础
Sun公司为简化数据库开发,定义了一套jdbc接口,这套接口由数据库厂商去实现,这样,开发人员只需要学习jdbc接口,并通过jdbc加载具体的驱动,就可以操作数据库
demo
数据库是从1开始计数,而不是0
public class MyJDBCDemo {
public static void main(String[] args) throws SQLException {
// TODO Auto-generated method stub
//加载驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//建立连接,账户密码,这是在本机上的简写方式
Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb2","root","code");
//执行语句的载体
Statement st=conn.createStatement();
String sql = "select * from users;";
//执行
ResultSet rs=st.executeQuery(sql);
//处理结果集
while(rs.next()){
System.out.println("MyJDBCDemo.main()"+rs.getObject(1)+rs.getObject(2));
}
//需要关闭
rs.close();
st.close();
}
}
返回的是第一个元素 id 和第二个 name
1.1 DriverManager
主要用来:
加载驱动:DriverManager.registerDriver(new Driver())
建立连接:DriverManager.getConnection(url, user, password)
1.2Collection
1.3 Statement
1.4 ResultSet
获取指定类型的数据:getString(int index) getString(String columnName)
在实际应用中,更推荐使用列名获取对象而不是列表’id’
通常使用如下方式获取每一列的相关属性值,而不是采用object的方式,方便直接赋值
当某一条执行完毕到最后,光标应该移到句首执行下一条
1.5 释放资源
Connection对象,它是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放
为确保资源释放代码能运行,资源释放代码也一定要放在finally语句中public class MyJDBCDemo2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//1 加载驱动
Connection conn=null;
Statement st=null;
ResultSet rs=null;
try {
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//2.建立连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb6","root","cskaoyan");
//3,获取statement 用于执行sql语句
st = conn.createStatement();
//4,生成sql语句,并执行
//execute
String sql = "select * from users;";
boolean flag = st.execute(sql);
//5,处理结果集
if (flag) {
rs=st.getResultSet();
while(rs.next()){
System.out.println("MyJDBCDemo.main()"+rs.getInt("id")+"\t"+
rs.getString("name")+"\t"+
rs.getString("password")+"\t"+
rs.getString("email"));
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
//6.关闭连接
if (rs!=null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
2.JDBC升级版
2.1 预处理
public class PrepareStDemo {
public static void main(String[] arg){
Connection conn = null;
Statement st = null;
PreparedStatement prest = null;
ResultSet rs = null;
try{
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb6","root","rjl000");
st = conn.createStatement();
String idString = "1";
String sql = "select * from users where id ='"+ idString+"';";
String sql2 = "insert into users values (4,'zl','123456','zl@sina.com');";
int id = 6;
String name = "zl";
String password = "123456";
String email = "zl@sina.com";
String sql3 = "insert into users values ("+id+",'"+name+"','"+password+"','"+email+"')";
/* st.executeUpdate(sql3);*/
String sql4 = "insert into users values(?,?,?,?)";
prest = conn.prepareStatement(sql4);
prest.setInt(1,id);
prest.setString(2,name);
prest.setString(3,password);
prest.setString(4,email);
prest.executeUpdate();
2.2 大数据
分为大文本和二进制文件(图片、音视频)
都要设置处理方法和数据的读写
public class MyJdbcBigTestDemo {
public static void main(String[] arg) throws IOException{
Connection conn = null;
Statement st = null;
PreparedStatement prest= null;
ResultSet rs=null;
try{
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb7","root","rjl000");
String sql = "insert into table1 values (?,?);";
prest = conn.prepareStatement(sql);
String sqlString = "select * from table1 where id =2;";//注意不能使index,这是保留字
st = conn.createStatement();
rs = st.executeQuery(sqlString);
while(rs.next()){
int index = rs.getInt(1);
Reader reader = rs.getCharacterStream(2);
File fileout = new File("src/b.txt");
Writer writer = new FileWriter(fileout);
char ch[] = new char[1024];
int len;
while((len=reader.read(ch))!= -1){
writer.write(ch,0,len);
}
writer.close(); //注意关闭流
reader.close();
}
} catch(SQLException e){
e.printStackTrace();
}
finally{
if(rs!=null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(st!=null){
try{
st.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}
public class MyJdbcBigBinaryDemo {
public static void main(String[] arg) throws IOException{
Connection conn = null;
Statement st = null;
PreparedStatement prest= null;
ResultSet rs=null;
try{
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//1.建立连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb7","root","rjl000");
//2,获取statement 用于执行sql语句
String sql = "insert into table2 values (?,?);";
prest = conn.prepareStatement(sql);
//3.从数据库里面读出的内容保存到 文件
String sqlString = "select * from table2 where id =1;";
st = conn.createStatement();
rs = st.executeQuery(sqlString);
while (rs.next()) {
int index= rs.getInt(1);
System.out.println("MyJdbcBigTestDemo.main()"+index);
InputStream fis = rs.getBinaryStream(2);
File fileout = new File("src/02.jpg");
FileOutputStream fos = new FileOutputStream(fileout);
byte[] b = new byte[1024];
int len=0;
while ((len=fis.read(b))!=-1) {
fos.write(b, 0, len);
}
fos.close();
fis.close();
}
} catch(SQLException e){
e.printStackTrace();
}
finally{
if(rs!=null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(st!=null){
try{
st.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}
2.3 批处理
当需要向数据库发送一批SQL语句执行时,应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率
Statement.addBatch(sql)
可以向数据库发送多条不同的SQL语句
当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句
PreparedStatement.addBatch()
发送的是预编译后的SQL语句,执行效率高。
只能应用在SQL语句相同,但参数不同的批处理中。因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据
注意内存溢出问题
executeBatch()方法:执行批处理命令
clearBatch()方法:清除批处理命令
一条一条执行
批处理1
只是参数不同是,可用循环来简化
倘若一次处理数据太多,会影响数据库性能,此时可以写一个判断语句,一次执行若干条。倘若要写20条,10条处理一次,这是个常用的写法,如果不是整数条呢?就需要在循环外再添加一个执行,比如写25条
这里数据库中已经有了18条,所以从19开始
//4,生成sql语句,并执行
String sql1 = "insert into users values (11,'a','123','xjbd');";
String sql2 = "insert into users values (12,'aa','123','xjbd');";
String sql3 = "insert into users values (13,'aaa','123','xjbd');";
String sql4 = "insert into users values (14,'aaaa','123','xjbd');";
String sql="insert into users values (?,?,?,?);";
prest = conn.prepareStatement(sql);
for (int i = 0;i<25;i++) {
prest.setInt(1, i+19);
prest.setString(2, "aaa"+i);
prest.setString(3, "123"+i);
prest.setString(4, "aaa@163.com"+i);
prest.addBatch();
if (i%10==0) {
prest.executeBatch();
prest.clearBatch();
}
}
prest.executeBatch();
prest.clearBatch();
int i[] = prest.executeBatch();
for(int result: i){
System.out.println("MyJdbcBatchDemo.main()"+result);
}
prest.clearBatch();
2.4 调用存储过程
定义一个核心的procedure,只知道有这么一个过程接口,在一些机密要求比较高的应用场合,比如在金融机构,查询一个数据,只需要传入一个ID,传出一个数据,而隐藏了表明列名等信息。
先在数据库里定义这个procedure
public class MyProcedureDemo {
public static void main(String[] srg){
Connection conn=null;
Statement st=null;
ResultSet rs=null;
CallableStatement callst;
try {
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//2.建立连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb6","root","rjl000");
//3,获取statement 用于执行procedure方法
callst = conn.prepareCall("{call demofunc(?, ?)}");
//传入参数
callst.setString(1, "abcdef");
callst.registerOutParameter(2, Types.VARCHAR);
callst.execute();
String result = callst.getString(2);
System.out.println("MyProcedureDemo.main()"+result);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
//6.关闭连接
if (rs!=null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}