MySql
1)安装问题
第一次安装失败后,必须删除上次安装的残留信息才能继续正常安装,否则可能安装失败;
2)DDL
数据定义语言,这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象的定义。常用的语句关键字主要包括 create、drop、alter等。
3)DML
数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性,常用的语句关键字主要包括 insert、delete、udpate 和select 等。(增添改查)
4)DCL
数据控制语句,用于控制不同数据段直接的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括 grant、revoke 等。
5)DTL
什么是事务:就是将一系列的sql语句当作“一句”来执行的一种机制——该系列语句要么全部执行成功,要么一个都不执行。
事务的特点:
A:原子性:一个事务中的所有语句,应该做到:要么全做,要么一个都不做;
C:一致性:让数据保持逻辑上的“合理性”,比如:一个商品出库时,既要让商品库中的该商品数量减1,又要让对应用户的购物车中的该商品加1;
I:隔离性:如果多个事务同时并发执行,但每个事务就像各自独立执行一样。
D:持久性:一个事务执行成功,则对数据来说应该是一个明确的硬盘数据更改(而不仅仅是内存中的变化)
结束事务并保存数据的方式:提交(Commit)、DDL语句、正常退出MySql语句
结束事务不保存数据的方式:回滚(Rollback)、非正常退出MySql语句
6)数据库编码格式
创建数据库的时候指定编码格式,并且在使用Java代码连接数据库的时候在Url后面加上?useUnicode=true&characterEncoding=编码格式,如果是在属性文件中配置需要考虑到转义字符 等于号 =。
7)批量插入的问题
设置Url后面rewriteBatchedStatements=true
下面的代码可能需要在if语句中间加入清理容器(未测试)
public static void batchInsert() throws ClassNotFoundException, SQLException{
connection.setAutoCommit(false);
PreparedStatement cmd =connection.prepareStatement("insert into test1 values(?,?)");
for (int i = 0; i < 1000000; i++) {//100万条数据
cmd.setInt(1, i);
cmd.setString(2, "test");
cmd.addBatch();
if(i%1000==0){
cmd.executeBatch();
}
}
cmd.executeBatch();
connection.commit();
cmd.close();
connection.close();
}
8)MyBatis批量插入
利用Foreach标签
Item:循环体中的具体对象。在list和数组中是其中的对象,在map中是value。该参数为必选
collection:要做foreach的对象,作为入参时,该参数为必选。
Separator:元素之间的分隔符,该参数可选。
open:foreach代码的开始符号,一般是(和close=")"合用。该参数可选。
close:foreach代码的关闭符号,一般是)和open="("合用。该参数可选。
index:在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。
<foreach item="item" collection="list" separator="," open="(" close=")" index="">
#{item.id}
</foreach>
9)表数据的复制
属于数据库调优最基本,具体语法如下:
需要复制的表不存在: insert into 表名 CREATE TABLE tab_new AS SELECT * FROM tab_old;
需要复制的表存在:insert into tab_new select * from tab_old;
10)数据的删除
delete与truncate 一个可以单条删除,后者只可以截断表(清空表数据,不可回滚);
拿清空表数据来说后者性能要远远高于前者;
11)聚合函数
AVG(col):返回指定列的平均值
COUNT(*):返回表的记录的行数
MIN(col):返回指定列的最小值
MAX(col):返回指定列的最大值
SUM(col):返回指定列的所有值之和
12)常用函数之数学函数
ABS(x) 返回x的绝对值
BIN(x) 返回x的二进制(OCT返回八进制,HEX返回十六进制)
EXP(x) 返回值e(自然对数的底)的x次方
LN(x) 返回x的自然对数
LOG(x,y) 返回x的以y为底的对数
MOD(x,y) 返回x/y的模(余数)
PI() 返回pi的值(圆周率)
RAND() 返回0到1内的随机值,可以通过提供一个参数(种子)使RAND()随机数生成器生成一个指定的值。
FLOOR(x) 返回小于x的最大整数值,(去掉小数取整)
CEILING(x) 返回大于x的最小整数值,(进一取整)
ROUND(x,y) 返回参数x的四舍五入的有y位小数的值,(四舍五入)
TRUNCATE(x,y) 返回数字x截短为y位小数的结果
SIGN(x) 返回代表数字x的符号的值(正数返回1,负数返回-1,0返回0)
SQRT(x) 返回一个数的平方根
13)字符串函数
CONCAT(s1,s2...,sn) 将s1,s2...,sn连接成字符串
CONCAT_WS(sep,s1,s2...,sn) 将s1,s2...,sn连接成字符串,并用sep字符间隔
INSERT(str,x,y,instr) 将字符串str从第x位置开始,y个字符长的子串替换为字符串instr,返回结果
LCASE(str)或LOWER(str) 返回将字符串str中所有字符改变为小写后的结果
UCASE(str)或UPPER(str) 返回将字符串str中所有字符转变为大写后的结果
LEFT(str,x) 返回字符串str中最左边的x个字符
RIGHT(str,x) 返回字符串str中最右边的x个字符
LENGTH(str) 返回字符串str中的字符数
POSITION(substr,str) 返回子串substr在字符串str中第一次出现的位置
REPEAT(str,srchstr,rplcstr) 返回字符串str重复x次的结果
REVERSE(str) 返回颠倒字符串str的结果
LTRIM(str) 去掉字符串str开头的空格
RTRIM(str) 去掉字符串str尾部的空格
TRIM(str) 去除字符串首部和尾部的所有空格
14)日期和时间函数
DATE_ADD(date,INTERVAL int keyword) 返回日期date加上间隔时间int的结果(int必须按照关键字进行格式化),如SELECTDATE_ADD(CURRENT_DATE,INTERVAL 6 MONTH);
DATE_SUB(date,INTERVAL int keyword) 返回日期date加上间隔时间int的结果(int必须按照关键字进行格式化),如:SELECTDATE_SUB(CURRENT_DATE,INTERVAL 6 MONTH);
DATE_FORMAT(date,fmt) 依照指定的fmt格式格式化日期date值
FROM_UNIXTIME(ts,fmt) 根据指定的fmt格式,格式化UNIX时间戳ts
MONTHNAME(date) 返回date的月份名(英语月份,如October)
DAYNAME(date) 返回date的星期名(英语星期几,如Saturday)
NOW() 返回当前的日期和时间 如:2016-10-08 18:57:39
CURDATE()或CURRENT_DATE() 返回当前的日期
CURTIME()或CURRENT_TIME() 返回当前的时间
QUARTER(date) 返回date在一年中的季度(1~4)
WEEK(date) 返回日期date为一年中第几周(0~53)
DAYOFYEAR(date) 返回date是一年的第几天(1~366)
DAYOFMONTH(date) 返回date是一个月的第几天(1~31)
DAYOFWEEK(date) 返回date所代表的一星期中的第几天(1~7)
YEAR(date) 返回日期date的年份(1000~9999)
MONTH(date) 返回date的月份值(1~12)
DAY(date) 返回date的天数部分
HOUR(time) 返回time的小时值(0~23)
MINUTE(time) 返回time的分钟值(0~59)
SECOND(time) 返回time的秒值(0-59)
DATE(datetime) 返回datetime的日期值
TIME(datetime) 返回datetime的时间值
15)加密函数
AES_ENCRYPT(str,key) 返回用密钥key对字符串str利用高级加密标准算法加密后的结果,调用AES_ENCRYPT的结果是一个二进制字符串,以BLOB类型存储
AES_DECRYPT(str,key) 返回用密钥key对字符串str利用高级加密标准算法解密后的结果
DECODE(str,key) 使用key作为密钥解密加密字符串str
ENCRYPT(str,salt) 使用UNIXcrypt()函数,用关键词salt(一个可以惟一确定口令的字符串,就像钥匙一样)加密字符串str
ENCODE(str,key) 使用key作为密钥加密字符串str,调用ENCODE()的结果是一个二进制字符串,它以BLOB类型存储
MD5() 计算字符串str的MD5校验和
PASSWORD(str) 返回字符串str的加密版本,这个加密过程是不可逆转的,和UNIX密码加密过程使用不同的算法。
SHA() 计算字符串str的安全散列算法(SHA)校验和
16)格式化函数
DATE_FORMAT(date,fmt) 依照字符串fmt格式化日期date值
FORMAT(x,y) 把x格式化为以逗号隔开的数字序列,y是结果的小数位数
INET_ATON(ip) 返回IP地址的数字表示
INET_NTOA(num) 返回数字所代表的IP地址
TIME_FORMAT(time,fmt) 依照字符串fmt格式化时间time值
其中最简单的是FORMAT()函数,它可以把大的数值格式化为以逗号间隔的易读的序列。
17)数据类型转换函数
CAST()函数,将一个值转换为指定的数据类型(类型有:BINARY,CHAR,DATE,TIME,DATETIME,SIGNED,UNSIGNED)
SELECT CAST(NOW() AS SIGNED INTEGER),CURDATE()+0;
18)分组
group by 属性名 [having 条件表达式][ with rollup]
“属性名 ”指按照该字段值进行分组;“having 条件表达式 ”用来限制分组后的显示,满足条件的结果将被显示;with rollup 将会在所有记录的最后加上一条记录,该记录是上面所有记录的总和。
1.单独使用
group by 单独使用,查询结果只显示一个分组的一条记录。
实例:select * from employee group by sex;
将只显示男女两条记录。
2.与group_concat()函数一起使用
每个分组中指定字段值都显示出来
实例:select sex,group_concat(name) from employee group by sex;
显示结果中“女”会显示所有sex为“女”的名字name
3.与集合函数一起使用
实例:select sex,count(sex) from employee group by sex;
结果:
count()为计算个数的方法。
4.与having一起使用
“having条件表达式”,可以限制输出结果。只有满足条件表达式的结果才显示。
实例:select sex,count(sex) from employee group by sex having count(sex) >= 3;
结果:
“having条件表达式”作用于分组后的记录。
按多字段进行分组
select * from employee group by d_id,sex;
查询结果先按d_id分组,再按sex进行分组
5.与with rollup一起使用
使用with rollup将会在所有记录的最后加上一条记录,这条记录是上面所有记录的总和
实例:select sex,count(sex) from employee group by sex with rollup;
结果:
如果是字符串的话,比如姓名就会生成“张三,李四,王五”这种类型的结果,即name总和。
19)索引
使用索引的目的
使用索引的目的是提高数据库查询的效率。索引是怎么提高数据库查询的效率的呢?举个通俗的例子,查字典。数据库中的数据就好比新华字典中的词条,索引就是新华字典的目录。没有建立索引的数据库就好像被撕掉目录的新华字典,只能从头到尾一条一条地查询,效率极其低下。为了能更快地查询数据库,我们就需要为数据库建立索引。
索引的原理
索引的主要思想是将数据分段,从而减少查询时的无效数据,提高查询效率。比如有1000条数据,1到100分成第一段,101到200分成第二段,201到300分成第三段……这样查第250条数据,只要找第三段就可以了,一下子去除了90%的无效数据。
mysql不支持位图索引
20)预处理与普通处理的区别
PreparedStatement是预编译的,对于批量处理可以大大提高效率.也叫JDBC存储过程
使用 Statement 对象。在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理。PreparedStatement对象的开销比Statement大,对于一次性操作并不会带来额外的好处。
Statement每次执行sql语句,相关数据库都要执行sql语句的编译,preparedstatement是预编译得,preparedstatement支持批处理
在Web环境中,有恶意的用户会利用那些设计不完善的、不能正确处理字符串的应用程序。特别是在公共Web站点上,在没有首先通过PreparedStatement对象处理的情况下,所有的用户输入都不应该传递给SQL语句。此外,在用户有机会修改SQL语句的地方,如HTML的隐藏区域或一个查询字符串上,SQL语句都不应该被显示出来。
在执行SQL命令时,我们有二种选择:可以使用PreparedStatement对象,也可以使用Statement对象。无论多少次地使用同一个SQL命令,PreparedStatement都只对它解析和编译一次。当使用Statement对象时,每次执行一个SQL命令时,都会对它进行解析和编译。
prepareStatement会先初始化SQL,先把这个SQL提交到数据库中进行预处理,多次使用可提高效率。
createStatement不会初始化,没有预处理,没次都是从0开始执行SQL
21)通过Jdbc如何来调用存储过程和函数
存储过程
String sql = "{call getStudentCount(?)}";
CallableStatement proc = conn.prepareCall(sql);
proc.registerOutParameter(1, java.sql.Types.INTEGER);
proc.execute();
studentCount = proc.getInt(1);
函数
String callFunctionSql = "{?= call getTreeChildList(?)}";
CallableStatement callableStatement = conn.prepareCall(callFunctionSql); callableStatement.registerOutParameter(1,Types.LONGVARCHAR); callableStatement.setString(2, inputStr);
22)CSV数据的备份与还原:
SELECT * INTO OUTFILE 导出路劲(绝对路劲-csv文件)
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY ' '
FROM 表名;
LOAD DATA INFILE 导入路劲(绝对路劲-csv文件)
INTO TABLE 表名
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY ' ';
Oracle
1)数据库实例的编码格式
创建数据库实例的时候要设置好数据库所要使用的编码格式。
2)Oracle的体系结构
方案 数据库实例下有用户,用户下才有对象
3)Oracle与Mysql的区别
1.Oracle是大型数据库而Mysql是中小型数据库,Oracle市场占有率达40%,Mysql只有20%左右,同时Mysql是开源的而Oracle价格非常高。
2. Oracle支持大并发,大访问量。
3. 安装所用的空间差别也是很大的,Mysql安装完后只有几百兆而Oracle有几个G左右,且使用的时候Oracle占用特别大的内存空间和其他机器性能。
4.Oracle也Mysql操作上的一些区别
①主键
Mysql一般使用自动增长类型,在创建表时只要指定表的主键为auto increment,插入记录时,不需要再指定该记录的主键值,Mysql将自动增长;Oracle没有自动增长类型,主键一般使用的序列,通过触发器在执行插入语句之前将序列的下一个值插入到主键;
②单引号的处理
MYSQL里可以用双引号包起字符串,ORACLE里只可以用单引号包起字符串。在插入和修改字符串前必须做单引号的替换:把所有出现的一个单引号替换成两个单引号。
③分页的SQL语句的处理
MYSQL处理分页的SQL语句比较简单,用LIMIT 开始位置, 记录个数;ORACLE处理翻页的SQL语句就比较繁琐了。每个结果集只有一个ROWNUM字段标明它的位置, 并且只能用ROWNUM<100, 不能用ROWNUM>80
⑤空字符的处理
MYSQL的非空字段也有空的内容,ORACLE里定义了非空字段就不容许有空的内容。按MYSQL的NOT NULL来定义ORACLE表结构, 导数据的时候会产生错误。因此导数据时要对空字符进行判断,如果为NULL或空字符,需要把它改成一个空格的字符串。
⑥字符串的模糊比较
MYSQL里用 字段名 like '%字符串%',ORACLE里也可以用 字段名 like '%字符串%' 但这种方法不能使用索引, 速度不快。
4)外键
表的约束里,如果存在外键:
删除数据 先删除子表的数据 在删除父表数据
如果非要先删除父表 可以级联删除,或者创建触发器进行操作。
5)模糊查之MyBatis
LIKE CONCAT(CONCAT('%', #{text}), '%');
6)分组
语法:
select to_char(date_column, 'yyyy-Q'),count(*)
from xxx
where date_column between '01-Jan-2007' and '31-Dec-2009'
group by to_char(date_column, 'yyyy-Q')//分组查询
分组之后结果的过滤:
SELECT deptno 部门编号, job 职位, SUM (sal) 薪资小计
FROM emp
WHERE deptno IN (20, 30)
GROUP BY deptno, job
HAVING SUM (sal) > 2000;
7)内连接 外连接 左连接 右连接
表t_user1,t_user2,t_user3,各有id,name两列
id |
name |
1 |
10A |
2 |
20A |
id |
name |
1 |
10B |
3 |
30B |
id |
name |
1 |
10C |
4 |
40C |
连接分为两种:内连接与外连接。
A.内连接
内连接,即最常见的等值连接,例:
SELECT *
FROM t_user1,t_user2
WHERE t_user1.id = t_user2.id
结果
id |
name |
id |
name |
1 |
10A |
1 |
10B |
B.外连接
外连接分为左外连接,右外连接和全外连接。
1. 左外连接 left outer join 或者 left join
左外连接就是在等值连接的基础上加上主表中的未匹配数据,例:
SELECT *
FROM t_user1
LEFT OUTER JOIN t_user2
ON t_user1.id = t_user2.id
Oracle 支持另一种写法
SELECT *
FROM t_user1 ,t_user2
WHERE t_user1.id=t_user2.id(+)
结果:
id |
name |
id |
name |
1 |
10A |
1 |
10B |
2 |
20A |
三个表做左外连接
SELECT *
FROM t_user1
LEFT OUTER JOIN t_user2
ON t_user1.id=t_user2.id
LEFT OUTER JOIN t_user3
ON t_user1.id=t_user3.id
Oracle 支持的另外一种写法
SELECT *
FROM t_user1,t_user2,t_user3
WHERE t_user1.id=t_user2.id(+)
AND t_user1.id=t_user3.id(+)
结果:
id |
name |
id |
name |
id |
name |
1 |
10A |
1 |
10B |
1 |
10C |
2 |
20A |
2. 右外连接 right outer join 或者 right join
右外连接是在等值连接的基础上加上被连接表的不匹配数据
SELECT *
FROM t_user1
RIGHT OUTER JOIN t_user2
ON t_user1.id=t_user2.id
Oracle支持的另一种写法
SELECT *
FROM t_user1,t_user2
WHERE t_user1.id(+)=t_user2.id
结果:
id |
name |
id |
name |
1 |
10A |
1 |
10B |
3 |
30B |
3.全外连接 full outer join 或者 full join
全外连接是在等值连接的基础上将左表和右表的未匹配数据都加上
SELECT *
FROM t_user1
FULL OUTER JOIN t_user2
ON t_user1.id=t_user2.id
全外连接的等价写法,对同一表先做左连接,然后右连接
SELECT t_user1.*,t_user2.*
FROM t_user1
LEFT OUTER JOIN t_user2
ON t_user1.id = t_user2.id
UNION
SELECT t_user1.*,t_user2.*
FROM t_user2
LEFT OUTER JOIN t_user1
ON t_user1.id = t_user2.id
结果:
id |
name |
id |
name |
1 |
10A |
1 |
10B |
2 |
20A |
||
3 |
30B |
8)集合查询
Select * from emp where deptno=10 union select * from emp where deptno=20;//去掉共有部分
Select * from emp where deptno=10 union all select * from emp where deptno=20;//不去掉
In
select * from A
where id in(select id from B)
以上查询使用了in语句,in()只执行一次,它查出B表中的所有id字段并缓存起来.之后,检查A表的id是否与B表中的id相等,如果相等则将A表的记录加入结果集中,直到遍历完A表的所有记录.
当B表数据较大时不适合使用in(),因为它会B表数据全部遍历一次.
如:A表有10000条记录,B表有1000000条记录,那么最多有可能遍历10000*1000000次,效率很差.
再如:A表有10000条记录,B表有100条记录,那么最多有可能遍历10000*100次,遍历次数大大减少,效率大大提升.
结论:in()适合B表比A表数据小的情况
exists
select a.* from A a
where exists(select 1 from B b where a.id=b.id)
以上查询使用了exists语句,exists()会执行A.length次,它并不缓存exists()结果集,因为exists()结果集的内容并不重要,重要的是结果集中是否有记录,如果有则返回true,没有则返回false.
当B表比A表数据大时适合使用exists(),因为它没有那么遍历操作,只需要再执行一次查询就行.
如:A表有10000条记录,B表有1000000条记录,那么exists()会执行10000次去判断A表中的id是否与B表中的id相等.
如:A表有10000条记录,B表有100000000条记录,那么exists()还是执行10000次,因为它只执行A.length次,可见B表数据越多,越适合exists()发挥效果.
再如:A表有10000条记录,B表有100条记录,那么exists()还是执行10000次,还不如使用in()遍历10000*100次,因为in()是在内存里遍历比较,而exists()需要查询数据库,我们都知道查询数据库所消耗的性能更高,而内存比较很快.
9)临时表
客户数据库数量越来越大,那段语句的劣性就体现的非常明显。优化时,发现查询关系逻辑混乱又复杂(虽然数据查询结果并没有错),多个类似的子查询嵌套,导致查询性能变的很低。寻求资料知道ORACLE有个WITH as 用法及其好用
写法大致如下:
WITH query1 AS
(select ...from ....where ..),
query2 AS
(select...from ...where..),
query3 AS
(select...from ...where..)
SELECT ...FROM query1,quer2,query3
where ....;
上述代码,每一个逗号(必不可少)代表一段子查询,观察执行计划发现,执行时with as 中的子查询结果会以临时表的形式存在。
这样写每段子查询相应的表仅会被检索一次,不会像原来嵌套的一样反复扫描相同的表,达到了“少读的目的”,大大提高了数据分析以及查询效率.
10)递归
例:
select * from table
start with org_id = 'HBHqfWGWPy'
connect by prior org_id = parent_id;
简单说来是将一个树状结构存储在一张表里,比如一个表中存在两个字段:
org_id,parent_id那么通过表示每一条记录的parent是谁,就可以形成一个树状结构。
用上述语法的查询可以取得这棵树的所有记录。
其中:
条件1 是根结点的限定语句,当然可以放宽限定条件,以取得多个根结点,实际就是多棵树。
条件2 是连接条件,其中用PRIOR表示上一条记录,比如 CONNECT BY PRIOR org_id = parent_id就是说上一条记录的org_id 是本条记录的parent_id,即本记录的父亲是上一条记录。
条件3 是过滤条件,用于对返回的所有记录进行过滤。
11)Oracle主键自增加
Oracle没有自动增长类型,主键一般使用的序列,通过触发器在执行插入语句之前将序列的下一个值插入到主键;
Select 序列.下一个值 into :new.id from dual;
12)Oracle的分页
ORACLE处理翻页的SQL语句就比较繁琐了。每个结果集只有一个ROWNUM字段标明它的位置, 并且只能用ROWNUM<100, 不能用ROWNUM>80
SELECT rowtable.* from (select ROWNUM rowhang, 表名.* from 表名) rowtable WHERE rowhang BETWEEN 开始单位 and 结束单位;
13)索引
缺点:
1:建立索引,系统要占用大约为表的1.2倍的硬盘和内存空间来保存索引。
2:更新数据的时候,系统必须要有额外的时间来同时对索引进行更新,以维持数据和索引的一致性——这就如同图书馆要有专门的位置来摆放索引柜,并且每当库存图书发生变化时都需要有人将索引卡片重整以保持索引与库存的一致。
优点:
在海量数据的情况下,如果合理的建立了索引,则会大大加强SQLS执行查询、对结果进行排序、分组的操作效率。
当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度
自动创建的索引: 主键索引 唯一约束
手动创建的索引: 普通索引 位图索引(数据类别较少 比如性别)
什么情况下需要使用索引:
数据量比较大,查询次数比较多,符合条件的记录数少于15%,由执行计划决定是否用到索引。
创建索引的 语句
创建 create index index_xxx on 表名(字段1 asc|desc,字段2 asc|desc……)
14)视图
简单 安全
有些拥有大量用户数据的表 可以使用视图来隐藏部分列 和只读视图 防止修改。
create or REPLACE view p_rate
AS
select r.userid,r.rateset,p.usercode,p.username,p.alipayid
from rate r,pro_user p where r.userid=p.userid;
15)事务
什么是事务:就是将一系列的sql语句当作“一句”来执行的一种机制——该系列语句要么全部执行成功,要么一个都不执行。
事务的特点:
A:原子性:一个事务中的所有语句,应该做到:要么全做,要么一个都不做;
C:一致性:让数据保持逻辑上的“合理性”,比如:一个商品出库时,既要让商品库中的该商品数量减1,又要让对应用户的购物车中的该商品加1;
I:隔离性:如果多个事务同时并发执行,但每个事务就像各自独立执行一样。
D:持久性:一个事务执行成功,则对数据来说应该是一个明确的硬盘数据更改(而不仅仅是内存中的变化)
结束事务并保存数据的方式:提交(Commit)、DDL语句、正常退出MySql语句
结束事务不保存数据的方式:回滚(Rollback)、非正常退出MySql语句
用到事务的地方:
实现一系列操作的地方要么全部成功,要么全部失败;a.日志表,b.批量插入
16)jdbc调用存储过程或者函数
存储过程
String sql = "{call getStudentCount(?)}";
CallableStatement proc = conn.prepareCall(sql);
proc.registerOutParameter(1, java.sql.Types.INTEGER);
proc.execute();
studentCount = proc.getInt(1);
函数
String callFunctionSql = "{?= call getTreeChildList(?)}";
CallableStatement callableStatement = conn.prepareCall(callFunctionSql); callableStatement.registerOutParameter(1,Types.LONGVARCHAR); callableStatement.setString(2, inputStr);
17)MyBatist调用存储过程或者函数
<!-- 调用存储过程 -->
<select id="getUserCount" parametermap="getMap" statementtype="CALLABLE">
CALL mybatis.get_user_count(?, ?);
</select>
<!-- 调用存储过程时的参数为一个Map,他具体的参数通过下面的方式来指定 -->
<parametermap id="getMap" type="java.util.Map">
<!-- 指定参数映射到指定的property并且 mode设置为IN 或OUT 作为调用存储过程的输入和输出 -->
<parameter jdbctype="INTEGER" mode="IN" property="id"></parameter>
<parameter jdbctype="INTEGER" mode="OUT" property="user_count"></parameter>
</parametermap>
使用
SqlSession session = MybatisUtils.getSession();
String statement = "com.mybatis.bean.puserMapper.getUserCount";
Map<string, integer=""> pMap = new HashMap<string, integer="">();
pMap.put("id", 0); //传入参数为0
pMap.put("user_count", -1); // 给user_count一个初始值为-1
session.selectOne(statement, pMap);
Integer rs = pMap.get("user_count");
System.out.println(rs);
session.close();
18)游标
如何使用Oracle的游标?
1. oracle中的游标分为显示游标和隐式游标
2. 显示游标是用cursor...is命令定义的游标,它可以对查询语句(select)返回的多条记录进行处理;隐式游标是在执行插入 (insert)、删除(delete)、修改(update)和返回单条记录的查询(select)语句时由PL/SQL自动定义的。
3. 显式游标的操作:打开游标、操作游标、关闭游标;PL/SQL隐式地打开SQL游标,并在它内部处理SQL语句,然后关闭它
19)具体业务
用户 角色 权限
用户表 角色表 权限表 表与表多对多关联
生成两张中间表 用户角色表 角色权限表 通过SQL可以查询到每个登录的用户是什么角色和角色所对应的权限都有什么。动态显示在页面上。
用户 角色 权限 操作
不同的人登录之后具有相同的页面级权限的情况下,打开权限后所显示的页面具体操作的权限内容有差别。
业务逻辑
从数据库数据表面的操作,就是对数据的增删改查在service层做相应的组合来完成项目业务逻辑功能。
从业务上来说,比如对订单的操作,都是操作了订单的相应实体。
要对某个功能模块进行业务逻辑的操作,也就是数据的增删改查,首项要从前台获取到数据,然后调用服务层的方法,通过mapper层对数据进行数据库操作。
工作流
工作流原理
针对工作中具有固定程序的常规活动而提出的一个概念,通过将工作活动分解定义良好的任务、角色、规则和过程来进行执行和监控,达到提高生产组织水平和工作效率的目的。
什么是工作流?
简单的来说,工作流(Workflow)就是业务流程的计算机化或自动化,两个或两个以上的人,为了共同的目标,连续的以串行或并行的方式去完成某一业务。
在以前,许多公司采用纸张表单,手工传递的方式,一级一级审批签字,工作效率非常低下。而采用工作流后,用户只需在电脑上填写有关表单,系统会按照事先定义好的流程自动向下进行,下一级审批者将会收到相关通知,并可以根据需要修改、跟踪、管理、查询、统计等,大大提高了工作效率。
资料来源--各种网站整理