一、CURD操作:增删该查操作
junit单元测试的使用
让方法能脱离main方法直接运行.
主要是用来开发测试时使用,线上的生产场景不能使用!
线上的生产场景只能使用正常的方法调用!
packagecom.test1;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.Statement;importorg.junit.Test;/** 增删改查
**/
public classCRUDDemo {//可以自己运行的方法,不需要main方法调用!//@Testpublic void insert() throwsException{// Class.forName("com.mysql.jdbc.Driver");// Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb1", "root", "123");
Statement st=conn.createStatement();//语义直通器int res = st.executeUpdate("insert into stu2 values('Tyson','male','yes')");//通过返回值是否是非0判断是否执行成功
if(res != 0){
System.out.println("插入数据成功");
}//st.close();
conn.close();
}
@Testpublic void delete() throwsException{// Class.forName("com.mysql.jdbc.Driver");// Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb1", "root", "123");
Statement st=conn.createStatement();int res = st.executeUpdate("delete from stu2 where name = 'Tyson'");//通过返回值是否是非0判断是否执行成功
if(res != 0){
System.out.println("删除数据成功");
}//st.close();
conn.close();
}
@Testpublic void update() throwsException{// Class.forName("com.mysql.jdbc.Driver");// Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb1", "root", "123");
Statement st=conn.createStatement();int res = st.executeUpdate("update stu2 set zhuxiao = 'yes' where name = 'Frank'");//通过返回值是否是非0判断是否执行成功
if(res != 0){
System.out.println("更新数据成功");
}//st.close();
conn.close();
}
@Testpublic void search() throwsException{// Class.forName("com.mysql.jdbc.Driver");// Connection conn = DriverManager.getConnection("jdbc:mysql:///day229", "root", "123");
Statement st=conn.createStatement();
ResultSet rs= st.executeQuery("select * from stu2");while(rs.next()){
String name= rs.getString(1);
String gender= rs.getString(2);
String zhuxiao= rs.getString(3);
System.out.println(name+","+gender+","+zhuxiao);
}//rs.close();
st.close();
conn.close();
}
}
封装数据库操作工具类:
注册驱动和获取连接对象的操作是每种操作都需要进行的步骤!
所以考虑将相同的操作封装到工具类中以方便使用!
优化:由于数据库连接使用的四大参数有可能随时发生变化,最好放到配置文件中指定!防止硬编码!
public classDbutils {//构造方法私有化
privateDbutils(){}//公共的静态方法,获取连接对象
public static Connection getConnection() throwsException{//通过配置文件获取参数
Properties p = newProperties();
p.load(new FileInputStream("dbconfig.txt"));// String driverName = p.getProperty("driverName");
String url= p.getProperty("url");
String userName= p.getProperty("userName");
String password= p.getProperty("password");
Class.forName(driverName);//将连接对象返回
returnDriverManager.getConnection(url,userName,password);
}
}
packagecom.utils;importjava.io.FileInputStream;importjava.sql.Connection;importjava.sql.DriverManager;importjava.util.Properties;/** 数据库操作的工具类
* 主要用来获取连接对象!
* 通过连接对象有可能获取Statement对象,也有可能获取的是预编译的对象
*
* 共同的操作:
* 1.注册驱动
* 2.获取连接对象
*
*
*
* 优化:
* 将四大参数放到配置文件中!!!
**/
public classDbutils {privateDbutils(){
}//公共的静态方法,获取连接对象
public static Connection getConnection() throwsException{//通过配置文件获取参数
Properties p = newProperties();
p.load(new FileInputStream("dbconfig.txt"));// String driverName = p.getProperty("driverName");
String url= p.getProperty("url");
String userName= p.getProperty("userName");
String password= p.getProperty("password");
Class.forName(driverName);// Connection conn =DriverManager.getConnection(url,userName,password);returnconn;
}
}
packagecom.test1;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.Statement;importorg.junit.Test;importcom.utils.Dbutils;/** 使用工具类实现增删改查
**/
public classCRUDDemo2 {//可以自己运行的方法,不需要main方法调用!//@Testpublic void insert() throwsException{
Connection conn=Dbutils.getConnection();
Statement st=conn.createStatement();int res = st.executeUpdate("insert into stu2 values('Tyson','male','yes')");//通过返回值是否是非0判断是否执行成功
if(res != 0){
System.out.println("插入数据成功");
}//st.close();
conn.close();
}
@Testpublic void delete() throwsException{
Connection conn=Dbutils.getConnection();
Statement st=conn.createStatement();int res = st.executeUpdate("delete from stu2 where name = 'Tyson'");//通过返回值是否是非0判断是否执行成功
if(res != 0){
System.out.println("删除数据成功");
}//st.close();
conn.close();
}
@Testpublic void update() throwsException{
Connection conn=Dbutils.getConnection();
Statement st=conn.createStatement();int res = st.executeUpdate("update stu2 set zhuxiao = 'yes' where name = 'Frank'");//通过返回值是否是非0判断是否执行成功
System.out.println(res);if(res != 0){
System.out.println("更新数据成功");
}//st.close();
conn.close();
}
@Testpublic void search() throwsException{// Connection conn =Dbutils.getConnection();
Statement st=conn.createStatement();
ResultSet rs= st.executeQuery("select * from stu2");while(rs.next()){
String name= rs.getString(1);
String gender= rs.getString(2);
String zhuxiao= rs.getString(3);
System.out.println(name+","+gender+","+zhuxiao);
}//rs.close();
st.close();
conn.close();
}
}
Statement接口详解:
是一个sql语句的执行器,可以执行sql语句.同时可以指定将来获取到的结果集的类型:
statement语句执行的方法:
DML:insert ,update ,delete
DDL:create table
DQL:select
如果是查询语句,建议使用executeQuery方法,直接得到结果集对象!
如果是更新类语句,建议使用executeUpdate方法,得到的结果是一个int值,通常用返回值是否非0来判断是否执行成功.
特例:execute方法可以执行任何类型的sql语句.返回值是boolean类型.
如果是true表示结果是一个结果集.
packagecom.test1;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.ResultSetMetaData;importjava.sql.Statement;importorg.junit.Test;importcom.utils.Dbutils;/** Statement接口
*
* executeUpdate(String sql):增删改操作
* executeQuery(String sql):针对查询
* execute(String sql):执行任意的sql语句,返回的是个布尔类型
*
* 结果集的操作:
* 游标的移动:
* next():
* previous():
* void afterLast():
* void beforFirst():
* boolean first():
* boolean last():
*
* absolute(int row):
* relative(int count):count正数,往下移动,负数,往上移动
*
* getRow():获取当前行编号!
*
* 获取结果集的特性:
* 通过获取Statement语句时指定的参数指定!!!
*
*
* 结果集的元数据:描述数据的数据!
* 如果我不知道结果集有多少列!如何遍历结果集?
* 通过结果集的元数据!!
* 元数据里可以获取列的数量.
* 通过while循环遍历行,通过for循环遍历列.
**/
public classCRUDDemo3 {
@Testpublic void search3() throwsException{// Connection conn =Dbutils.getConnection();
Statement st=conn.createStatement();
ResultSet rs= st.executeQuery("select * from stu2");//如果不知道结果集的列数,如果遍历?
ResultSetMetaData metaData =rs.getMetaData();int count =metaData.getColumnCount();//遍历结果集
while(rs.next()){//遍历列:
for(int i = 1;i<=count;i++){
Object obj=rs.getObject(i);
System.out.print(obj);if(i !=count){
System.out.print(", ");
}
}//System.out.println();
}//st.close();
conn.close();
}
@Testpublic void search() throwsException{// Connection conn =Dbutils.getConnection();
Statement st=conn.createStatement();//boolean b = st.execute("select * from stu2");//if(b){// //获取结果集//ResultSet rs = st.getResultSet();//while(rs.next()){//String name = rs.getString(1);//System.out.println(name);//}//rs.close();//}
ResultSet rs= st.executeQuery("select * from stu2");
System.out.println(rs.getRow());
rs.absolute(5);
System.out.println(rs.getRow());//获取结果集的行数
rs.afterLast();
rs.previous();
System.out.println(rs.getRow());
rs.close();//st.close();
conn.close();
}
@Testpublic void search2() throwsException{// Connection conn =Dbutils.getConnection();
Statement st=conn.createStatement();/** 第一个参数:结果集的类型:可滚动,不敏感,不可更新
* ResultSet.TYPE_FORWARD_ONLY: 结果集的游标只能往下滚动
* ResultSet.TYPE_SCROLL_INSENSITIVE : 对数据库底层数据变化不敏感
* ResultSet.TYPE_SCROLL_SENSITIVE : 对数据库底层数据变化敏感
* MySQL只支持第二种!!!
*
* 第二个参数:结果集的变化是否能更新到底层数据库,
* ResultSet.CONCUR_READ_ONLY : 结果集的更改不更新到底层的数据库
* ResultSet.CONCUR_UPDATABLE : 结果集的更改更新到底层的数据库
* 目前,所有的数据库都只支持第一种!!!
*
* MySQL获取的Statement对象,默认是以下组合!!
* ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY
**/ResultSet rs= st.executeQuery("select * from stu2");
System.out.println(rs.getRow());
rs.absolute(5);
System.out.println(rs.getRow());//获取结果集的行数
rs.afterLast();
rs.previous();
System.out.println(rs.getRow());
rs.close();//st.close();
conn.close();
}
}
结果集游标操作:
绝对定位:
boolean first():
boolean last():
void beforeFirst():
void afterLast():
boolean absolute(int row):
相对定位:从当前位置移动
boolean next():
boolean previous():
boolean relative(int amount):正数表示往后移动,负数表示往前移动
判断操作:
boolean isAfterLast():
boolean isBeforeFirst():
boolean isFirst():
boolean isLast():
结果集的元数据操作:
若不知道具体的结果集有多少列,可以通过结果集的元数据获取结果集的描述信息,其中就包括列的数量.
通过列的数量就可以遍历一行数据的各个列.
通过游标的返回值就可以遍历行.
二者结合,就可以遍历一个不知道具体行数和列数的结果集!
ResultSetMetaData metaData =rs.getMetaData();int count =metaData.getColumnCount();//遍历结果集
while(rs.next()){//遍历列:
for(int i = 1;i<=count;i++){
Object obj=rs.getObject(i);
System.out.print(obj);if(i !=count){
System.out.print(", ");
}
}//System.out.println();
}
加上异常处理的完整程序!
对非内存资源的释放一般是放在finally块中.就需要将资源的定义放在try块外.
finally中需要对资源进行非空判断!!!
sql注入
sql注入:sql语句中出现了一些sql中的关键字,导致整个sql语句的含义发生了变化.即为sql注入!
防止sql注入的主要方法是让sql语句中不能出现特殊的关键字.
使用预编译语句即可保证sql语句中只能填入指定类型的值!
PreparedStatement对象
连接对象通过prepareStatement方法,可以获取一个预编译的对象,在获取时需要传递一个需要预先编译的sql语句.
SQL语句中一般都会包含占位符?
在得到预编译语句后,通过setXXX(占位符索引,值)方法对占位符进行赋值!
占位符索引从1开始.
优点:提高效率,防止sql注入
二进制大对象:blob:***
binary large object:
使用流技术上传和下载数据!
二进制大文本:text:***
使用流技术上传和下载数据!
批处理:
Statement接口和PreparedStatement接口都可以实现批处理!
前者更适合多种sql语句混合使用的场景.
后者更适合同种sql语句一起执行的场景.
注意:不同的数据库驱动版本可能对批处理有不同的支持!
MySQL默认没有开启批处理功能!
需要在url后添加如下属性开启此功能!
url=jdbc:mysql:///day17?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true
更改的是客户端的配置,不需要重启.
事务操作:
事务的操作都是通过连接对象进行的:
手动开启事务:
void setAutoCommit(boolean on):设置为false就是开启了手动事务!
事务回滚:
void rooback():
事务提交:
void commit():
回滚点:
回滚点也是通过连接对象进行的操作!savepoint是接口
设置回滚点:
Savepoint setSavepoint():
回滚到回滚点:
void rollback(Savepoint sp):
标准事务处理:
try中处理
final中释放资源
连接池(数据源)
dbcp连接池(数据源):apache开源的数据源.
需要导入两个包:
需要设置的数据:
数据库连接四大参数:
第一种方式:将数据库连接的四大参数在程序中直接提供(硬编码)
第二种方式:使用Properties类关联到一个配置文件.将四大参数用配置文件提供!
池参数:一般保持默认!
最大空闲连接数
最大活动连接数
初始连接数
装饰者模式:decorator Wrapper
需要被装饰的类装饰类有共同的父类或者是接口!
先创建一个底层被包装对象,
再创建包装类对象时,将底层对象通过构造方法传递!!!
是你还有你!(是你:装饰类和被装饰的类有共同的父类(接口),还是你:在成员变量位置保持一个被装饰对象的引用)
一切拜托你!!(不关心的方法,直接调用底层被包装的对象的相应方法)
增强点上增强!!!(在增强方法肾功能进行逻辑上的增强)
packagecom.test7;/** 装饰器模式:
* 包装一个对象,绝大多数方法保持不变,只在少数方法上进行增强!
*
*
*
* 对象增强的手段:常用的是继承!
* A
* AA extends A{
* ///
* }
*
* 咖啡 :
* 加奶咖啡:
* 加糖咖啡:
* 加盐咖啡:
* 加糖,加奶咖啡:
* ...
* 随着需求的不断变化,会导致类的暴增!!!
*
* 使用装饰器模式:
* 咖啡 :
*
* 咖啡 a = new 咖啡();
* 加奶咖啡 b = 加奶咖啡(a);
* 加糖咖啡 c = 加糖咖啡(b);
*
*
* 连接池:
* getConnection
* createStatement.
* prepareStatement
*
*
* 连接池在close方法上进行了增强!!!
* close
*
* jdk中使用装饰者典型的是:io流
*
* BufferedReader(Reader r)
*
*
**/
abstract classAnimal{public abstract voidtest1();public abstract voidtest2();public abstract voidtest3();public abstract voidtest4();
}class Dog extendsAnimal{
@Overridepublic voidtest1() {
System.out.println("dog test1");
}
@Overridepublic voidtest2() {
System.out.println("dog test2");
}
@Overridepublic voidtest3() {
System.out.println("dog test3");
}
@Overridepublic voidtest4() {
System.out.println("dog test4");
}
}//装饰器类:让装饰器类和被装饰的类有共同的父类(接口).//在装饰类中保持一个父类(接口)的引用.在构造方法中对其进行赋值//在增强点方法上进行修改,其余的非增强点方法保持原样!!!
class DogWrapper extendsAnimal{//保持一个父类的引用
Animal an = null;//构造方法中对其赋值
publicDogWrapper(Animal an){this.an =an;
}
@Overridepublic voidtest1() {
an.test1();
}
@Overridepublic voidtest2() {
an.test2();
}
@Overridepublic voidtest3() {
an.test3();
}//增强点方法
@Overridepublic voidtest4() {
System.out.println("hello");
an.test4();
System.out.println("world");
}
}public classWrapperDemo {public static voidmain(String[] args) {//Animal a = new Dog();
Animal an= newDog();
Animal a= newDogWrapper(an);
a.test1();
a.test2();
a.test3();
a.test4();
}
}
packagecom.test1;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.Statement;importorg.junit.Test;importcom.utils.Dbutils;/** 使用工具类实现增删改查
**/
public classCRUDDemo2 {//可以自己运行的方法,不需要main方法调用!//@Testpublic void insert() throwsException{
Connection conn=Dbutils.getConnection();
Statement st=conn.createStatement();int res = st.executeUpdate("insert into stu2 values('Tyson','male','yes')");//通过返回值是否是非0判断是否执行成功
if(res != 0){
System.out.println("插入数据成功");
}//st.close();
conn.close();
}
@Testpublic void delete() throwsException{
Connection conn=Dbutils.getConnection();
Statement st=conn.createStatement();int res = st.executeUpdate("delete from stu2 where name = 'Tyson'");//通过返回值是否是非0判断是否执行成功
if(res != 0){
System.out.println("删除数据成功");
}//st.close();
conn.close();
}
@Testpublic void update() throwsException{
Connection conn=Dbutils.getConnection();
Statement st=conn.createStatement();int res = st.executeUpdate("update stu2 set zhuxiao = 'yes' where name = 'Frank'");//通过返回值是否是非0判断是否执行成功
System.out.println(res);if(res != 0){
System.out.println("更新数据成功");
}//st.close();
conn.close();
}
@Testpublic void search() throwsException{// Connection conn =Dbutils.getConnection();
Statement st=conn.createStatement();
ResultSet rs= st.executeQuery("select * from stu2");while(rs.next()){
String name= rs.getString(1);
String gender= rs.getString(2);
String zhuxiao= rs.getString(3);
System.out.println(name+","+gender+","+zhuxiao);
}//rs.close();
st.close();
conn.close();
}
}
packagecom.test1;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.ResultSetMetaData;importjava.sql.Statement;importorg.junit.Test;importcom.utils.Dbutils;/** Statement接口
*
* executeUpdate(String sql):增删改操作
* executeQuery(String sql):针对查询
* execute(String sql):执行任意的sql语句
*
* 结果集的操作:
* 游标的移动:
* next():
* previous():
* void afterLast():
* void beforFirst():
* boolean first():
* boolean last():
*
* absolute(int row):
* relative(int count):count正数,往下移动,负数,往上移动
*
* getRow():获取当前行编号!
*
* 获取结果集的特性:
* 通过获取Statement语句时指定的参数指定!!!
*
*
* 结果集的元数据:描述数据的数据!
* 如果我不知道结果集有多少列!如何遍历结果集?
* 通过结果集的元数据!!
* 元数据里可以获取列的数量.
* 通过while循环遍历行,通过for循环遍历列.
**/
public classCRUDDemo3 {
@Testpublic void search3() throwsException{// Connection conn =Dbutils.getConnection();
Statement st=conn.createStatement();
ResultSet rs= st.executeQuery("select * from stu2");//如果不知道结果集的列数,如果遍历?
ResultSetMetaData metaData =rs.getMetaData();int count =metaData.getColumnCount();//遍历结果集
while(rs.next()){//遍历列:
for(int i = 1;i<=count;i++){
Object obj=rs.getObject(i);
System.out.print(obj);if(i !=count){
System.out.print(", ");
}
}//System.out.println();
}//st.close();
conn.close();
}
@Testpublic void search() throwsException{// Connection conn =Dbutils.getConnection();
Statement st=conn.createStatement();//boolean b = st.execute("select * from stu2");//if(b){// //获取结果集//ResultSet rs = st.getResultSet();//while(rs.next()){//String name = rs.getString(1);//System.out.println(name);//}//rs.close();//}
ResultSet rs= st.executeQuery("select * from stu2");
System.out.println(rs.getRow());
rs.absolute(5);
System.out.println(rs.getRow());//获取结果集的行数
rs.afterLast();
rs.previous();
System.out.println(rs.getRow());
rs.close();//st.close();
conn.close();
}
@Testpublic void search2() throwsException{// Connection conn =Dbutils.getConnection();
Statement st=conn.createStatement();/** 第一个参数:结果集的类型:可滚动,不敏感,不可更新
* ResultSet.TYPE_FORWARD_ONLY: 结果集的游标只能往下滚动
* ResultSet.TYPE_SCROLL_INSENSITIVE : 对数据库底层数据变化不敏感
* ResultSet.TYPE_SCROLL_SENSITIVE : 对数据库底层数据变化敏感
* MySQL只支持第二种!!!
*
* 第二个参数:结果集的变化是否能更新到底层数据库,
* ResultSet.CONCUR_READ_ONLY : 结果集的更改不更新到底层的数据库
* ResultSet.CONCUR_UPDATABLE : 结果集的更改更新到底层的数据库
* 目前,所有的数据库都只支持第一种!!!
*
* MySQL获取的Statement对象,默认是以下组合!!
* ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY
**/ResultSet rs= st.executeQuery("select * from stu2");
System.out.println(rs.getRow());
rs.absolute(5);
System.out.println(rs.getRow());//获取结果集的行数
rs.afterLast();
rs.previous();
System.out.println(rs.getRow());
rs.close();//st.close();
conn.close();
}
}
packagecom.test1;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.ResultSetMetaData;importjava.sql.SQLException;importjava.sql.Statement;importorg.junit.Test;importcom.utils.Dbutils;/** 加上异常处理的程序
* 资源的释放一般放在finally块中!!
**/
public classCRUDDemo4 {
@Testpublic voidsearch3(){//作用域提升
Connection conn = null;
Statement st= null;
ResultSet rs= null;try{
conn=Dbutils.getConnection();
st=conn.createStatement();
rs= st.executeQuery("select * from stu2");//如果不知道结果集的列数,如果遍历?
ResultSetMetaData metaData =rs.getMetaData();int count =metaData.getColumnCount();//遍历结果集
while(rs.next()){//遍历列:
for(int i = 1;i<=count;i++){
Object obj=rs.getObject(i);
System.out.print(obj);if(i !=count){
System.out.print(", ");
}
}//System.out.println();
}
}catch(Exception e){
System.out.println(e.getMessage());
}finally{// try{//非空判断
if(st != null){
st.close();
}
}catch(SQLException e) {
}try{if(conn != null){
conn.close();
}
}catch(SQLException e) {
}try{if(rs != null){
rs.close();
}
}catch(SQLException e) {
}
}
}
}
packagecom.test3;importjava.io.FileInputStream;importjava.sql.Connection;importjava.sql.PreparedStatement;importcom.utils.Dbutils;/** blob:
* binary large object
* 可执行程序,图片,视频,音频....
*
* 一般不会放到数据库中,效率低:
*
* 数据库存放的绝大多数都是字符串!
* 数据库中保存的是资源的路径!!!
*
* tinyblob:255字节
* blob:64K
* midumblob:16M
* longblob:4G
**/
public classBlobDemo {public static void main(String[] args) throwsException {
insert2();
}//往数据库中存图片
private static void insert2() throwsException {
Connection conn=Dbutils.getConnection();
PreparedStatement pst= conn.prepareStatement("insert into my_blob values(null,?)");//对占位符进行赋值
pst.setBinaryStream(1, new FileInputStream("c:/dog.jpg"));//插入数据
int res =pst.executeUpdate();if (res != 0) {
System.out.println("插入图片成功");
}//pst.close();
conn.close();
}//往数据库中存图片
private static void insert() throwsException {
Connection conn=Dbutils.getConnection();
PreparedStatement pst= conn.prepareStatement("insert into my_blob values(null,?)");//对占位符进行赋值
pst.setBinaryStream(1, new FileInputStream("c:/PresionBreak.jpg"));//插入数据
int res =pst.executeUpdate();if (res != 0) {
System.out.println("插入图片成功");
}//pst.close();
conn.close();
}
}
packagecom.test3;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.InputStream;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importcom.utils.Dbutils;/** blob:
* binary large object
* 可执行程序,图片,视频,音频....
*
* 一般不会放到数据库中,效率低:
*
* 数据库存放的绝大多数都是字符串!
* 数据库中保存的是资源的路径!!!
*
* tinyblob:255字节
* blob:64K
* midumblob:16M
* longblob:4G
**/
public classBlobDemo {public static void main(String[] args) throwsException {//insert2();
read();
}//从数据库读取图片:底层使用的是流!!!
private static void read() throwsException {
Connection conn=Dbutils.getConnection();
PreparedStatement pst= conn.prepareStatement("select data from my_blob where id = 2");
ResultSet rs=pst.executeQuery();//while(rs.next()){//
//}
rs.next();//列的序号是结果集中的列的序号,而不是表设计时的序号!!
InputStream in = rs.getBinaryStream(1);//创建输出流
FileOutputStream out = new FileOutputStream("c:/dog22.jpg");byte[] buf = new byte[1024 * 8];int len = 0;while((len = in.read(buf)) != -1){
out.write(buf,0, len);
}//out.close();
in.close();
rs.close();
pst.close();
conn.close();
}//往数据库中存图片
private static void insert2() throwsException {
Connection conn=Dbutils.getConnection();
PreparedStatement pst= conn.prepareStatement("insert into my_blob values(null,?)");//对占位符进行赋值
pst.setBinaryStream(1, new FileInputStream("c:/dog.jpg"));//插入数据
int res =pst.executeUpdate();if (res != 0) {
System.out.println("插入图片成功");
}//pst.close();
conn.close();
}//往数据库中存图片
private static void insert() throwsException {
Connection conn=Dbutils.getConnection();
PreparedStatement pst= conn.prepareStatement("insert into my_blob values(null,?)");//对占位符进行赋值
pst.setBinaryStream(1, new FileInputStream("c:/PresionBreak.jpg"));//插入数据
int res =pst.executeUpdate();if (res != 0) {
System.out.println("插入图片成功");
}//pst.close();
conn.close();
}
}
packagecom.test3;importjava.io.FileReader;importjava.io.FileWriter;importjava.io.Reader;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importcom.utils.Dbutils;/** tinytext:255字节
* text:64K
* mediumtext:16M
* longtext:4G
**/
public classTextDemo {public static void main(String[] args) throwsException {//insert();
read();
}//从数据库读取文本
private static void read() throwsException {
Connection conn=Dbutils.getConnection();
PreparedStatement pst= conn.prepareStatement("select data from my_text where id = 1");
ResultSet rs=pst.executeQuery();
rs.next();
Reader r= rs.getCharacterStream(1);//创建字符输出流
FileWriter w = new FileWriter("c:/text.txt");char[] buf = new char[1024 * 8];int len = 0;while((len = r.read(buf)) != -1){
w.write(buf,0, len);
}//w.close();
r.close();
rs.close();
pst.close();
conn.close();
}//插入文本
private static void insert() throwsException {
Connection conn=Dbutils.getConnection();
PreparedStatement pst= conn.prepareStatement("insert into my_text values(null,?)");
pst.setCharacterStream(1, new FileReader("dbconfig.txt"));int res =pst.executeUpdate();if(res != 0){
System.out.println("插入数据成功");
}
pst.close();
conn.close();
}
}
packagecom.test4;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.SQLException;importjava.sql.Statement;importcom.utils.Dbutils;/** 批处理:
* Statement接口中的方法:
* PreparedStatement接口也可以使用!!!
*
* addBatch(String sql):
* executeBatch():
* clearBatch():
*
*
* Statement:适合多种类型的操作混合在一起操作
* PreparedStatement:适合同一种操作,但是参数不同!!
**/
public classBatchDemo {public static void main(String[] args) throwsException {//test1();
long start =System.currentTimeMillis();
test2();
System.out.println(System.currentTimeMillis()-start);
}//使用预编译语句的批处理
private static void test2() throwsException {
Connection conn=Dbutils.getConnection();
PreparedStatement pst= conn.prepareStatement("insert into stu values(null,?,?)");for(int i = 1;i<=1000;i++){
pst.setString(1, "name" +i);
pst.setInt(2, i);//把当前语句放到批处理中
pst.addBatch();// if(i % 200 == 0){
pst.executeBatch();
}
}//执行批处理
pst.executeBatch();//pst.close();
conn.close();
}private static void test1() throwsException, SQLException {
Connection conn=Dbutils.getConnection();
Statement st=conn.createStatement();//添加批处理
st.addBatch("insert into stu values(null,'zhangsan',10)");
st.addBatch("insert into stu values(null,'lisi',10)");
st.addBatch("insert into stu values(null,'赵六',20)");
st.addBatch("insert into stu values(null,'王五',30)");
st.addBatch("insert into stu values(null,'Tyson',50)");//st.executeBatch();//st.close();
conn.close();
}
}
packagecom.test5;importjava.sql.Connection;importjava.sql.SQLException;importjava.sql.Savepoint;importjava.sql.Statement;importcom.utils.Dbutils;/** 默认jdbc也是自动事务.
* 手动开启事务:
* 使用连接对象的方法:
* setAutoCommit(boolean on):设置为false,意味着手动事务开启
*
* commit():提交事务
* rollback():回滚到事务开启之前
* rollback(Savepoint sp):回滚到指定保存点
*
* setSavepoint():获取一个保存点
**/
public classTransactionDemo {public static voidmain(String[] args) {
Connection conn= null;
Statement st= null;
Savepoint sp1= null;try{//正常提交
conn =Dbutils.getConnection();
conn.setAutoCommit(false);// st =conn.createStatement();
st.executeUpdate("insert into student values (6,'yyy',10,20,1)");//设置保存点:
sp1 =conn.setSavepoint();int res = st.executeUpdate("update student set name = 'xxx' where id = 6");//if(res != 0){//System.out.println("更新成功");//}//异常
if(true){throw new RuntimeException("发生异常");
}//提交
conn.commit();
}catch(Exception e){//异常回滚
System.out.println(e.getMessage());//回滚到回滚点
try{if(conn != null){
conn.rollback(sp1);//结束事务:否则保存点之前的操作不能更新到底层数据库!!!
conn.commit();
}
}catch(SQLException e1) {
e1.printStackTrace();
}
}finally{try{if(st != null){
st.close();
}
}catch(SQLException e) {
e.printStackTrace();
}try{if(conn != null){
conn.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
}
}private static void test1() throwsException, SQLException {
Connection conn=Dbutils.getConnection();//手动开启事务
conn.setAutoCommit(false);// conn.createStatement().executeUpdate("delete from student where id = 2");//回滚//conn.rollback();//提交
conn.commit();//conn.close();
}
}
-----------------------------------------------------------------
作业:
对一个对象的有返回值的方法进行增强!在方法前加"hello",方法调用后,加"world"
packagecom.homework;/** 对一个对象的有返回值的方法进行增强!
在方法前加"hello",方法调用后,加"world".*/
abstract classAnimal{public abstract voidt1();public abstractString t2();
}class Dog extendsAnimal{
@Overridepublic voidt1() {
System.out.println("Dog.t1()");
}
@OverridepublicString t2() {
System.out.println("Dog.t2()");return "xxx";
}
}class DogWrapper extendsAnimal{
Animal an ;publicDogWrapper(Animal an){this.an =an;
}
@Overridepublic voidt1() {
an.t1();
}
@OverridepublicString t2() {
System.out.println("hello");
String res=an.t2();
System.out.println("world");returnres;
}
}public classDemo {public static voidmain(String[] args) {//被包装对象
Dog d = newDog();//创建包装类对象
DogWrapper dw = newDogWrapper(d);//dw.t1();// String res =dw.t2();
System.out.println(res);
}
}
--------------------------------------------------
使用set local xxx = ... 是对本地变量进行设置.
本次会话立即生效!
总结:
对客户端的会话变量进行设置:使用set local ...
对服务端的系统变量进行设置:使用set global ...