您的位置:首页 > 数据库

数据库学习第五天之存储过程和事务

2016-11-05 12:46 204 查看
知识点1:存储过程:

存储过程是保存在数据库上的一段可执行代码。

它的语法是:

delimiter $$//DELIMITER用于定义结束符

Create procedure sp_name (参数..)

Begin

SQL语句

End;

调用它的方法:

delimiter ;//DELIMITER用于定义结束符(还原结束符)

Call sp_name(参数…); //空参时则括号中不填内容

存储过程有三种:

1)不带参数的存储过程

2)带输入参数的存储过程

3)带输入输出参数的存储过程

知识点2:事务transaction

原子性(atomicity):组成事务处理的语句形成了一个逻辑单元,不能只执行其中的一部分。

一致性(consistency):在事务处理执行前后,数据库是一致的(数据库数据完整性约束)。

隔离性(isolcation):一个事务处理对另一个事务处理的影响。

持续性(durability):事务处理的效果能够被永久保存下来 。

一个事务只会有一个结果:要么成功、要么失败。

事务:

Start transaction;开始一个事务。

Commit;提交所做的修改。

Rollback;回滚所做的修改。如果在操作时出错,应该从新开始一个事务。



设置事务的隔离级别:

在mySql的命令行设置隔离级别。

在MySql的命令行设置隔离级别,只对此打开的命令行窗口有效。第一个命令行窗口,就是一个独立的客户端。

Select @@tx_isolation; 可以查看目前的隔离级别。

Set Session transaction isolation level <级别名称>可以设置隔离级别。

级别名称为:{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }

需要注意的是,隔离级别必须要在事务当中使用,没有事务,隔离级别也没有意义了。

※存储过程
存储过程是保存在数据库上的一段可执行代码。
1、定义存储过程的语法是:
CREATE PROCEDURE sp_name (参数..)
BEGIN
SQL语句
END;
2、调用它的方法:
CALL sp_name(参数…);   //空参时则括号中不填内容

3、演示
1)不带参数
定义(DELIMITER用于定义结束符):
DELIMITER $$
CREATE PROCEDURE p1()
BEGIN
INSERT INTO person VALUES('7','蒙奇D-路飞2','1');
SELECT * FROM person;//妈的!坑,错误的代码也能够执行成功!
END$$
//调用存储过程
//还原原来的结束符号!
DELIMITER ;
CALL p1();

----------

//带输入参数
DELIMITER $$
CREATE PROCEDURE p2(IN id VARCHAR(32),IN NAME VARCHAR(30))
BEGIN
INSERT INTO person VALUES(id,NAME,'0');
SELECT * FROM person;
END$$
//传参数进去
DELIMITER ;
CALL p2('9','进击的女帝');
CALL p2('10','张碧晨','0');

------------

3) 带输入、输出参数
定义:
DELIMITER $$
CREATE PROCEDURE p3()
BEGIN
DELETE FROM person WHERE NAME LIKE "进击%";//模糊查询!
SELECT * FROM person;
END$$
DELIMITER ;
CALL p3();

3) 带输入、输出参数
DELETE FROM person WHERE id IN (SELECT id FROM person WHERE id%==0);
定义:
DELIMITER %%
CREATE PROCEDURE p4(IN id VARCHAR(32),IN NAME VARCHAR(30),OUT num INT)
BEGIN
INSERT INTO person VALUES(id,NAME,'1');
SELECT COUNT(*) INTO num FROM person;
SELECT * FROM person;
END%%
DELIMITER ;
CALL p4('8','张碧晨',@abcd); //一个@为用户变量,两个@为系统变量
输出返回值(输出参数)
SELECT @abcd;

//输出系统变量“@@VERSION”的值
SELECT @@VERSION;//5.6.22-LOG

-----------

※查询内容区分大小写
mysql查询默认是不区分大小写的 如:
SELECT * FROM table_name WHERE a LIKE 'a%'
SELECT * FROM table_name WHERE a LIKE 'A%'
SELECT *
4000
FROM table_name WHERE a LIKE 'a%'
SELECT * FROM table_name WHERE a LIKE 'A%'
效果是一样的。
要让mysql查询区分大小写,可以:
SELECT * FROM table_name WHERE BINARY a LIKE 'a%'
SELECT * FROM table_name WHERE BINARY a LIKE 'A%'
SELECT * FROM table_name WHERE BINARY a LIKE 'a%'
SELECT * FROM table_name WHERE BINARY a LIKE 'A%'
也可以在建表时,加以标识
CREATE TABLE table_name(
a VARCHAR(20) BINARY
);

//MySql区别大小写的查询演示:
SELECT * FROM person;
INSERT INTO person VALUES('9','java进击的女帝','0');
//MySQL本身查询时是不区分大小写的但是一定要区分大小写的话用以下方式进行解决
//不区分大小写
SELECT NAME FROM person WHERE NAME LIKE "j%";
SELECT * FROM person WHERE NAME LIKE "J%";
//区分大小写的解决办法
SELECT NAME AS 姓名 FROM person WHERE BINARY NAME LIKE "j%";
SELECT * FROM person WHERE BINARY NAME LIKE "J%";

------------------------------

//接下来演示数据库中一个很重要的知识点(以上的只需大概了解,会用就行!但接下来的必须熟练掌握!)
※事务: 一个事务只会有一个结果,要么成功,要么失败。
举例:
8,'张碧晨' 一次买了两辆车,需要把张碧晨的信息存储到person表,同时还要把两辆车的信息存储到car表-----两个表的存储动作就是一个事务,要么成功(两个表的信息都成功存储), 要么失败(只要其中一个表的一条数据存储失败,其它表的信息都不能存储进去,如果存进去则要还原)。
类似的例子,还有:银行转账!   销售单和销售明细!
SQL演示:
事务的两种处理方式:ROLLBACK回滚,COMMIT提交-----意思就是在一个事务内执行了以上两个中的任意一条语句,则代表当前的事务结束!
//开启事务
START TRANSACTION;
DELETE FROM person WHERE id IN('7','9');
ROLLBACK;//演示回滚!
SELECT * FROM person;

INSERT INTO person VALUES('7','被扇贝','1');
INSERT INTO person VALUES('9','进击的女帝','0');
START TRANSACTION;
DELETE FROM person WHERE id='7';
DELETE FROM person WHERE id='9';
COMMIT;

※事务的隔离

//创建一个学生表2用来进行java的事务代码演示
CREATE TABLE stud2(
id VARCHAR(32) PRIMARY KEY,
NAME VARCHAR(30)
);
INSERT INTO stud2 VALUES('s1','张三');
INSERT INTO stud2 VALUES('s2','关羽');
INSERT INTO stud2 VALUES('s3','Rose玫瑰');

INSERT INTO car VALUES('C008','宝马s系',85.5,'2');


Java对数据库中的事务处理(JDBC):

Java实现事务处理的简单模板:

package cn.hncu.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

//import com.mysql.jdbc.Driver;

public class TxDemo {
public static void main(String[] args) {
//四部曲
//第一步:加载连接器
try {
Class.forName("com.mysql.jdbc.Driver");
//第二步:申明连接哪台主机的哪个数据库,同时指定编码,比较全的!模板是死的记住就行!
//jdbc:mysql://<hostname>[<:3306>]/<dbname>
//下面指定编码时一定要注意:MySQL中的编码为utf8中间没有斜杠,但是在MyEclipse中是带有斜杠的!
String url = "jdbc:mysql://127.0.0.1:3306/abc?useUnicode=true&characterEncoding=utf-8";
//第三步:建立连接
Connection con = null;
Statement st = null;
try {
con = DriverManager.getConnection(url, "root", "1234");
//第四步:对数据库中的内容进行操作
st = con.createStatement();

/*
* ※Java实现事务处理的简单模板
*/
con.setAutoCommit(false);//开启事务,-->sql:start transaction;
//插入数据
st.execute("insert into person values('11','我爱罗','1')");
//给新增的数据买两辆车!
//st.execute("insert into car values('C008','宝马s系',85.5,'11')");
st.execute("insert into car values('C009','宝马w系',55.5,'11')");
//st.execute("insert into car values('C009','宝马o系',5.74,'11')");//测试回滚操作,故意演示失败案例!
st.execute("insert into car values('C010','宝马x系',41.02,'11')");
System.out.println("提交了一个事物......");
con.commit();//提交事务-->sql:commit;
} catch (SQLException e) {
System.out.println("提交事务失败,已经回滚到操作之前");
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}

//查询操作
try {
ResultSet res = st.executeQuery("select * from person");
while(res.next()){//表示有没有移到数据行,有则返回true
Object id = res.getObject(1);
String name = res.getString("name");
String ch = res.getString("sex");//这里还他妈的不能强转!明明是字符类型!
if(ch.equals("0")){
ch = "女";
}else if(ch.equals("1")){
ch="男";
}else{
ch="其它";
}
System.out.println(id+", "+name+", "+ch);
}
} catch (SQLException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}


下面演示Java对数据库的增删改查操作!

配置文件(jdbc.properties)

##MySQL
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/abc?useUnicode=true&characterEncoding=utf-8
usename=root
password=1234

##Oracle
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
#username=scott
#password=tiger


工厂类(ConnFactory.java):

package cn.hncu.jdbc.pubs;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

public class ConnFactory {
//工厂类---单例(饿汉式)
private static Connection con;
//私有化构造方法---防止外部直接调用
private ConnFactory(){
}
static{//静态块
//通过配置文件加载可移植性更强!
try {
Properties p = new Properties();
System.out.println("通过类加载器拿到文件的路径(很强):"+ConnFactory.class.getClassLoader().getResourceAsStream("jdbc.properties"));
p.load(ConnFactory.class.getClassLoader().getResourceAsStream("jdbc.properties"));//读取classpath下的资源文件
String driver = p.getProperty("driver");
String url = p.getProperty("url");
String user = p.getProperty("usename");
String password = p.getProperty("password");

//jdbc四部曲(牢记)
Class.forName(driver);
con = DriverManager.getConnection(url, user, password);
System.out.println("获取连接......");
} catch (Exception e) {
e.printStackTrace();
}
}

//静态方法供外部访问
public static Connection getCon(){
return con;
}
}


实现类(JdbcDemo.java):

package cn.hncu.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
import java.util.UUID;

import org.junit.Test;

import cn.hncu.jdbc.pubs.ConnFactory;

//import com.mysql.jdbc.Driver;

public class JdbcDemo {
//jdbc演示增删改查的操作!
//查询
@Test
public void readDemo() throws Exception{
//jdbc四部曲
//第一步:加载连接器---在此注意一点:驱动 ---jdbc4.0开始,这一句可以省略。
Class.forName("com.mysql.jdbc.Driver");//通过类反射加载连接器!
//hibernate框架,上一句不要省。 所以还是不省的好!以免后面坑了自己!
//第二步:申明连接哪台主机的哪个数据库,比并且制定编码格式,与数据库中保持一致以防乱码!比较全的
String url = "jdbc:mysql://127.0.0.1:3306/abc?useUnicode=true&characterEncoding=utf-8";
//上句中制定编码时注意一下:在数据库中为utf8中间不带斜杠,但是在myeclipse中需要带上斜杠!注意这点
//第三步:建立连接
Connection con = DriverManager.getConnection(url, "root", "1234");

//第四步:对数据库中的内容进行操作
Statement st = con.createStatement();
//演示对数据库中的数据进行查询操作
ResultSet res= st.executeQuery("select * from person");//该方法专用于查询---返回一个结果集
//迭代遍历输出
while(res.next()){
String id = res.getString(1);
String name = res.getString("name");
String sex = res.getString("sex");
if(sex.equals("0")){
sex = "女";
}else if(sex.equals("1")){
sex = "男";
}else{
sex = "其他";
}
System.out.println(id+", "+name+", "+sex);
}

//养成好习惯:关流操作(本质上是socket通信!)
con.close();
}

//增删改!
@Test
public void saveDemo() throws Exception{
//由于我们发现上面得一部分代码是一样的,我们将把它们抽取出来--工厂类(模板基本上是死的,针对于同一个数据库来说)
//这样能够大大的提高效率!
//拿到连接器对象
Connection con = ConnFactory.getCon();
System.out.println(con);
Scanner sc = new Scanner(System.in);
String name = sc.nextLine();
//增
String uuid = UUID.randomUUID().toString().replace("-", "");
String sql = "insert into person values('"+uuid+"','"+name+"','0')";

//第四步:数据库语句操作
Statement st = con.createStatement();
int column = st.executeUpdate(sql);//该方法一般用于如下操作:增insert、删delete、改update
//上面方法的返回值: 影响的行数
System.out.println("影响的行数:"+column);
con.close();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据库 存储 事务 sql