SpringBoot使用Druid数据库加密链接完整方案

Druid介绍,Druid链接加密

网上的坑

springboot使用Druid数据库加密链接方案,不建议采用网上的一篇文章《springboot结合Druid加密数据库密码遇到的坑!》介绍的方式来进行加密链接实现。以下方式兼容SpringBoot1和SpringBoot2.0及以上。本文章下文分享Druid源码后就知道为什么不建议采用该方式的原因了。

加密准备

首先使用CMD生成数据库加密字符串,该命令会产生三个值 privateKey=公钥、publicKey=密码加密后的结果、password=密码加密串

java -cp druid-1.0.28.jar com.alibaba.druid.filter.config.ConfigTools pcds123123456

使用Durid的工具类ConfigTools验证加密字符串

@Test
public void db_decrypt_test() throws Exception {
   String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJggkaRJ+bqLMF6pefubEDLViboxYKGTdGe+78DziIta8Nv8crOA83M0tFG8y8CqHcFYIbG89q9zcnNvL+E2/CECAwEAAQ==";
   String password = "AgDRyKJ81Ku3o0HSyalDgCTtGsWcKz3fC0iM5pLur2QJnIF+fKWKFZ6c6e36M06tF2uCadvS/EodWxmRDWwvIA==";
   System.out.println(ConfigTools.decrypt(publicKey, password));
}

实现方案

SpringBoot集成Druid数据库链接加密的方式,推荐使用配置注入方式初始化DataSource。方法如下:

一、增加配置注入Bean

import java.sql.SQLException;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import com.alibaba.druid.pool.DruidDataSource;
 
@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
public class DbConfig {
    private static final Logger LOGGER = LoggerFactory.getLogger(DbConfig.class);
 
    private String url;
    private String driverClassName;
    private String username;
    private String password;
    private Integer initialSize;
    private Integer minIdle;
    private Integer maxActive;
    private Integer maxWait;
    private Integer timeBetweenEvictionRunsMillis;
    private Integer minEvictableIdleTimeMillis;
    private String validationQuery;
    private Boolean testWhileIdle;
    private Boolean testOnBorrow;
    private Boolean testOnReturn;
    private Boolean poolPreparedStatements;
    private Integer maxOpenPreparedStatements;
    private Integer maxPoolPreparedStatementPerConnectionSize;
    private String filters;
    private String publicKey;
    private String connectionProperties;
 
    @Primary
    @Bean(name = "dataSource")
    public DataSource dataSource() {
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(url);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);
        datasource.setInitialSize(initialSize);
        datasource.setMinIdle(minIdle);
        datasource.setMaxActive(maxActive);
        datasource.setMaxWait(maxWait);
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setValidationQuery(validationQuery);
        datasource.setTestWhileIdle(testWhileIdle);
        datasource.setTestOnBorrow(testOnBorrow);
        datasource.setTestOnReturn(testOnReturn);
        datasource.setPoolPreparedStatements(poolPreparedStatements);
        datasource.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        datasource.setConnectionProperties(connectionProperties.replace("${publicKey}", publicKey));
        try {
            datasource.setFilters(filters);
        } catch (SQLException e) {
            LOGGER.error("druid configuration initialization filter", e);
        }
        return datasource;
    }
 
    public String getUrl() {
        return url;
    }
 
    public void setUrl(String url) {
        this.url = url;
    }
 
    public String getDriverClassName() {
        return driverClassName;
    }
 
    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }
 
    public String getUsername() {
        return username;
    }
 
    public void setUsername(String username) {
        this.username = username;
    }
 
    public String getPassword() {
        return password;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
 
    public Integer getInitialSize() {
        return initialSize;
    }
 
    public void setInitialSize(Integer initialSize) {
        this.initialSize = initialSize;
    }
 
    public Integer getMinIdle() {
        return minIdle;
    }
 
    public void setMinIdle(Integer minIdle) {
        this.minIdle = minIdle;
    }
 
    public Integer getMaxActive() {
        return maxActive;
    }
 
    public void setMaxActive(Integer maxActive) {
        this.maxActive = maxActive;
    }
 
    public Integer getMaxWait() {
        return maxWait;
    }
 
    public void setMaxWait(Integer maxWait) {
        this.maxWait = maxWait;
    }
 
    public Integer getTimeBetweenEvictionRunsMillis() {
        return timeBetweenEvictionRunsMillis;
    }
 
    public void setTimeBetweenEvictionRunsMillis(Integer timeBetweenEvictionRunsMillis) {
        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    }
 
    public Integer getMinEvictableIdleTimeMillis() {
        return minEvictableIdleTimeMillis;
    }
 
    public void setMinEvictableIdleTimeMillis(Integer minEvictableIdleTimeMillis) {
        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    }
 
    public String getValidationQuery() {
        return validationQuery;
    }
 
    public void setValidationQuery(String validationQuery) {
        this.validationQuery = validationQuery;
    }
 
    public Boolean getTestWhileIdle() {
        return testWhileIdle;
    }
 
    public void setTestWhileIdle(Boolean testWhileIdle) {
        this.testWhileIdle = testWhileIdle;
    }
 
    public Boolean getTestOnBorrow() {
        return testOnBorrow;
    }
 
    public void setTestOnBorrow(Boolean testOnBorrow) {
        this.testOnBorrow = testOnBorrow;
    }
 
    public Boolean getTestOnReturn() {
        return testOnReturn;
    }
 
    public void setTestOnReturn(Boolean testOnReturn) {
        this.testOnReturn = testOnReturn;
    }
 
    public Boolean getPoolPreparedStatements() {
        return poolPreparedStatements;
    }
 
    public void setPoolPreparedStatements(Boolean poolPreparedStatements) {
        this.poolPreparedStatements = poolPreparedStatements;
    }
 
    public Integer getMaxOpenPreparedStatements() {
        return maxOpenPreparedStatements;
    }
 
    public void setMaxOpenPreparedStatements(Integer maxOpenPreparedStatements) {
        this.maxOpenPreparedStatements = maxOpenPreparedStatements;
    }
 
    public Integer getMaxPoolPreparedStatementPerConnectionSize() {
        return maxPoolPreparedStatementPerConnectionSize;
    }
 
    public void setMaxPoolPreparedStatementPerConnectionSize(Integer maxPoolPreparedStatementPerConnectionSize) {
        this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
    }
 
    public String getFilters() {
        return filters;
    }
 
    public void setFilters(String filters) {
        this.filters = filters;
    }
 
    public String getPublicKey() {
        return publicKey;
    }
 
    public void setPublicKey(String publicKey) {
        this.publicKey = publicKey;
    }
 
    public String getConnectionProperties() {
        return connectionProperties;
    }
 
    public void setConnectionProperties(String connectionProperties) {
        this.connectionProperties = connectionProperties;
    }
}

二、增加配置文件

# mysql config
spring.datasource.name=pcdsdata
spring.datasource.url=jdbc:mysql://192.168.1.1/mydb
spring.datasource.username=root
spring.datasource.password=AgDRyKJ81Ku3o0HSyalDgCTtGsWcKz3fC0iM5pLur2QJnIF+fKWKFZ6c6e36M06tF2uCadvS/EodWxmRDWwvIA==
 
# druid datasource config
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.maxActive=20
spring.datasource.initialSize=1
spring.datasource.minIdle=1
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=select 1 from dual
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxOpenPreparedStatements=20
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.filters=config,stat,wall,log4j
spring.datasource.publicKey=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJggkaRJ+bqLMF6pefubEDLViboxYKGTdGe+78DziIta8Nv8crOA83M0tFG8y8CqHcFYIbG89q9zcnNvL+E2/CECAwEAAQ==
spring.datasource.connectionProperties=config.decrypt=true;config.decrypt.key=${spring.datasource.publicKey}

注意事项

1)config.decrypt=true;config.decrypt.key=  该两项配置为Druid内部固定Key。网上很多案例配置为publicKey,这是有问题的。
2)其他教程会配置DbType为 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource 实际在Druid源码中会判断DbType为 MySql 或者Db2等类型。可删除此项 原逻辑将从  this.dbType = JdbcUtils.getDbType(jdbcUrl, null);//数据库链接字符串 获取DbType值

经过以上配置,SpringBoot使用Druid加密链接完成。如果过程中遇到其他问题可在下方留言,方便更多人解决类似问题。

经测试以上配置兼容SpringBoot2.0以上2.0.3/2.06等. 升级测试时需要注意jar包版本问题:
1)Gson升级到最新版本,如gson-2.8.5.jar. 否则报错 com.google.gson.GsonBuilder.setLenient()Lcom/google/gson/GsonBuilder; but it does not exist. Its class, com.google.gson.GsonBuilder, is available from the following locations:

2)log4j升级到log4j-1.2.17以上, 否则报错 Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Priority


源码分析

1) 根据源码逻辑,如果不自定义注入Bean, 在SpringBoot初始化时只会读取系统配置参数,如下

public DruidDataSource(){
        this(false);
    }
 
    public DruidDataSource(boolean fairLock){
        super(fairLock);
 
        configFromPropety(System.getProperties());
    }
 
    public void configFromPropety(Properties properties) {
        {
            Boolean value = getBoolean(properties, "druid.testWhileIdle");
            if (value != null) {
                this.setTestWhileIdle(value);
            }
        }
        {
            Boolean value = getBoolean(properties, "druid.testOnBorrow");
            if (value != null) {
                this.setTestOnBorrow(value);
            }
        }
 
 
...

2) 所有的配置在类DruidAbstractDataSource中,自定义注入Bean,将在这个类中设置相关属性

3) 在首次初始化数据库链接时将调用DruidDataSource.init(),并进入到ConfigFilter.init ,初始化建立链接。根据配置config.decrypt决定是否要进行解密动作,如需解密则加载config.decrypt.key和password(首先加载connectionProperties链接字符串中的password,没有再加载默认的spring.datasource.password)  ConfigFilter.decrypt执行解密动作。

4) 文章《springboot结合Druid加密数据库密码遇到的坑!》中其实是绕过了是否要进行加密等配置,自己实现了解密动作再把数据库链接密码替换掉,这违背了Druid设计的初衷了。​

参考资料

参考资料 https://github.com/alibaba/druid/wiki

Oracle体系结构:SGA和五个必须的ORACLE后台进程

系统全局区又称SGA(SGA)等一定的内存和ORACLE后台进程组成了ORACLE实例(Instance) ,而数据库(Database)指的是数据库物理文件。oracle五个必须的ORACLE后台进程有是什么?以及什么是SGA?下面做如下详细介绍。

(1)五个必须的ORACLE后台进程:SMON、PMON、DBWn、CKPT、LGWR

系统监控进程(System Monitor SMON) 在数据库系统启动时执行恢复工作的强制性进程
进程监控进程(Process Monitor PMON) 用于恢复失败的数据库用户的强制性进程,它先获取失败用户的标识,释放该用户占有的所有数据库资源。
数据库写入进程(Database Writer, DBWn) 它将修改后的数据块写回数据库文件。日志写入进程(Log Writer , LGWR) 一个专门用于将重做项写入重做日志的进程。
校验点进程(Checkpoint Process CKPT ) ORACLE把内存中脏数据块中的信息写回磁盘的判断进程。

(2)什么是SGA?

系统全局区又称SGA (System Global Area 也称 Shared Global Area) 是Oracle Instance的 基本组成部分,在实例启动时分配。是一组包含一个Oracle实例的数据和控制信息的共享内存结构。主要是用于存储数据库信息的内存区,该信息为数据库进程所共享(PGA不能共享的)。它包含Oracle 服务器的数据和控制信息,它是在Oracle服务器所驻留的计算机的实际内存中得以分配,如果实际内存不够再往虚拟内存中写。

SGA重要组成的三部分

共享池(Shared Pool) 主要用来存储最近执行过的SQL语句和最近使用过的数据字典的数据;它主要通过INIT.ORA文件中的shared_pool_size和shared_pool_reserved_size两个参数来设置。

数据高速缓存区(Data Buffer Cache) 主要用来存储最近使用过的数据,可能是要写到数据文件的,也可能是从数据文件读取的;它主要通过INIT.ORA文件中db_block_buffers参数来设置;Data Buffer的大小=db_block_buffers* db_block_size;

重做日志缓存区(Redo Log Buffer) 主要存储服务进程和后台进程的变化信息;它主要通过INIT.ORA文件中的log_buffer参数来设置; Redo Log Buffer的大小=log_buffer* db_block_size;

当然,SGA不仅仅只是上面的三部分,还包括如Java pool(用来存储java代码)、Large pool(供不是和SQL直接相关的进程使用,如:当数据备份或恢复操作时,RMAN backup 用作磁盘I/O缓存器;Parallel时用作消息缓存器;MTS回话内存)等部分,我们可以通过v$sysstat、v$rowcache、v$librarycache等系统视图来监控SGA。

Oracle维护必会的基础SQL

1.查询当前数据库谁在运行什么sql
SELECT  OSUSER, USERNAME, SQL_TEXT FROM V$SESSION A, V$SQLTEXT B    WHERE A.SQL_ADDRESS =B.ADDRESS ORDER BY ADDRESS, PIECE;

2.如何查询和删除重复记录?
   DELETE FROM TABLE_NAME  T1
   WHERE ROWID!=(SELECT MAX(ROWID) FROM TABLE_NAME T2
  WHERE T1.COL1= T2.COL1   AND T1.COL2= T2.COL2);
 
3.如何用BBB表的数据去更新AAA表数据 (有关联的字段)
UPDATE AAA SET BNS_SNM=(SELECT BNS_SNM FROM BBB WHERE AAA.DPT_NO=BBB.DPT_NO) WHERE  EXISTS  (SELECT BNS_SNM FROM BBB WHERE AAA.DPT_NO=BBB.DPT_NO) ;
ORA-28000:the account is locked
 
4.关于Rownum
(1)仔细阅读下面三条命令,猜想其结果
Select * from users where rownum>0;
Select * from users where rownum>1;
Select * from users where rownum<2;
 
猜想     根据时间倒序查询10笔订单
select * from  ord_order  b  where rownum<11 order by create_time desc  ;
select * from (select * from ord_order b  order by create_time desc )  where rownum<11 ;
以上2条sql语句得到的数据一样吗?哪个数据是符合要求的。
 
(2)rownum的值来源原理
1 Oracle executes your query.
2 Oracle fetches the first row and calls it row number 1.
3 Have we gotten past row number meets the criteria? If no, then Oracle discards the row, If yes, then Oracle return the row.
4 Oracle fetches the next row and advances the row number (to 2, and then to 3, and then to 4, and so forth).
5 Go to step
 
(3). 总结:因为ROWNUM是对结果集加的一 个伪列,即先查到结果集之后再加上去的一个列 (强调:先要有结果集)。简单的说rownum是对符合条件结果的序列号。它总是从1开始排起的。所以你选出的结果不可能没有1,而有其他大于1的值。

从Oracle迁移数据到MySql方法大全

最近工作需要从Oracle迁移大量数据到MySql,由于涉及不深,便网上学习了很多的方法,现总结Oracle迁移大量数据到MySql如下:

一,使用mysql工具迁移数据

1. MySQL Administrator —— MySQL 服务器的管理利器。这个工具解决了MySQL管理的很多问题,譬如:可以让你简单通过GUI界面模式选择热备份数据库计划,或者是冷备份,你可以方便的选择备份时间,每周或是每日的什么时候进行。
2.MySQL Query Browser —— 查询工具,使用起来也很简单,而且支持调试等功能。
3.MySQL Migration Kit —— 管理工具
4.Navicat for MySQL —— 数据库管理工具

推荐使用Navicat for MySQL功能强大,简单方便(2018/12/18更新)效果如下

oracletomysql

 

二,从oracle导数据到mysql,使用命令
(1)在使用pl/sql developer生成的sql文件然后插入到mysql时由于to_date()和chr()问题,insert时会失败。
(2)phpmyadmin里面有个SQL compatibility mode 的 Oracle选项,具体作用还未知。
(3)DBA高效数据迁移方法:先导出成文本,然后LOAD DATA 命令直接导入。
建议用

select u_id||’&’||u_pid||’&’||str_1||’&’ ||str_2||’&’ ||str_3||’&’||tm_create_time   from table_foo

这样的形式,在sql plus里面导出用&分割的数据,然后在mysql里面用

load data local infile ‘~/table_foo’ into table tbl_gbase_inf fields terminated by ‘&’;

导入。

如果str里面包含多行文本,而默认是文本文件里一行对应数据库里一行数据的,多行文本被误认为是多行数据,格式就不对,导入出错。可以在pl/sql developer里面进行以下查询:

select t.*,’$’ from tbl_foo t

用$作为一行数据的结束符,这样即使遇到回车,mysql仍然能够正确处理了。然后把结果全选,右键菜单导出结果到TSV文件(”导出结果”->”TSV 文件”)。这个文件的格式就是一行一项数据的文本文件了,而且字段之间是用tab分隔的,正好就是load data命令的默认分隔符。
在select语句里加了一个’$’作为最后一个域,也就是说在文本文件里,它前面会有一个tab,后面会有一个回车换行。所以要用ultraedit把’\t\$\r\n'(Ultredit正则)都替换成’$’,这样一搞,文本文件基本上没法看了,但在load edit眼里,它就是一个正好合胃口的美味的数据源了。用如下命令导入:

load data local infile ‘~/table_foo’ into table tbl_gbase_inf lines terminated by ‘%’;show warnings;

回车搞定。可以在文件名和into之间插上replace关键字,自动替换掉原有数据。 注意,load data可能不是立即生效的,可以show processlist;看看是否被delay了,过一段时间表没人访问应该就会插进去了。  另外,如果插入的中文显示出来是乱码,就用
show   variables   like   “%char%”;

看看结果是不是长这样的:

+————————–+—————————-+
| Variable_name            | Value                      |
+————————–+—————————-+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+————————–+—————————-+

如果database或server的字符集不是utf8,用set 命令将其改为utf8,然后重新load data,应该就不会是乱码。

三,牛人编写的Oracle到MySQL的数据迁移工具

从Oracle迁移数据到MySQL的小程序,ora2mysql下载 ora2mysql
使用方法如下:
D:\>ora2mysql user1=scott/tiger user2=/@localhost:3306:test table=emp
0 rows processed at 2011-04-02 15:03:08.
2 rows processed at 2011-04-02 15:03:08.

在速度方面,由于不支持Array操作,因此速度比较慢,希望Oracle能让SQL * Plus也能连接MySQL库,或改造一下MySQL客户端,增加Array接口。

D:\>ora2mysql user1=scott/tiger user2=/@::test table1=emp_bak table2=emp
0 rows processed at 2011-04-02 19:48:51.
100000 rows processed at 2011-04-02 19:49:17.
200000 rows processed at 2011-04-02 19:49:42.
300000 rows processed at 2011-04-02 19:50:07.
400000 rows processed at 2011-04-02 19:50:32.
500000 rows processed at 2011-04-02 19:50:57.
600000 rows processed at 2011-04-02 19:51:23.
700000 rows processed at 2011-04-02 19:51:48.
800000 rows processed at 2011-04-02 19:52:14.
900000 rows processed at 2011-04-02 19:52:39.
1000000 rows processed at 2011-04-02 19:53:03.
1100000 rows processed at 2011-04-02 19:53:29.
1200000 rows processed at 2011-04-02 19:53:56.
1300000 rows processed at 2011-04-02 19:54:24.
1400000 rows processed at 2011-04-02 19:54:53.

目前还不支持BLOB类型, 也不支持字符集的设置

作者地址:http://www.anysql.net/tools/oracle-mysql-data-migration-tool.html/comment-page-1#comment-4146

 

CMD命令查看端口被什么程序占用

在安装Nginx for windows  时,每次启动都会如下信息:

2011/08/25 09:39:53 [emerg] 948#972: bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions)

意思是80端口被占用,自己并没有开启特别的软件,端口肯定被我不知道的程序占用了,于是上网查了一下,下面的方式更方便。

    在windows命令行窗口下执行:

运行–cmd

C:\>netstat -aon|findstr "8080"
TCP     127.0.0.1:80         0.0.0.0:0               LISTENING       2448
端口被进程号为2448的进程占用,继续执行下面命令:
C:\>tasklist|findstr "2448"
thread.exe                     2016 Console                 0     16,064 K
很清楚,thread占用了你的端口,Kill it
如果第二步查不到,那就开任务管理器,进程—查看—选择列—pid(进程位标识符)打个勾就可以了
看哪个进程是2448,然后杀之即可。

 

原来是:Msdepsvc.exe 进程

What is Msdepsvc.exe

Msdepsvc.exe with description Web Deployment Agent Service is a process file from company Microsoft Corporation belonging to product Microsoft IIS Extensions.
The file is digitally signed from Microsoft Corporation – Microsoft Time-Stamp Service
We do not recommend removing digitally signed files from Microsoft Corporation

所以请注意安装了IIS7的朋友要特别注意这个Msdepsvc.exe他默认开启的占用了80端口

 强制终止进程:

      CMD命令:taskkill /F /pid 1408

 

 

详解ORACLE锁的教程

1.什么是ORACLE锁
数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。加锁就是实现数据库并发控制的一个非常重要的技术。

2.ORACLE锁的类型
在 数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它修改。加了共享锁的数据对象可以被其他事务读取,但不能被删除和修改。数据库利用这 两种基本的锁类型来对数据库的事务进行并发控制。

?
根据保护的对象不同,Oracle数据库锁可以分为以下几大类:DML锁 (data locks,数据锁),用于保护数据的完整性;DDL锁(dictionary locks,字典锁),用于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩(internal locks and latches),保护 数据库的内部结构。

在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。?
当 Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再自动申请TX类型的锁,并将实际锁定的数据行的锁标志 位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了SS、 SX、S、X 等多种模式,在数据库中用0-6来表示。不同的SQL操作产生不同类型的TM锁。

TM锁的类型 0 none? 1 NULL 空 Select? 2 SS(Row-S) 行级共享锁,其他对象? 只能查询这些数据行 Select for update、Lock for?update、
Lock row share? 3 SX(Row-X) 行级排它锁,? 在提交前不允许做DML操作 Insert、Update、? Delete、Lock row share? 4 S(Share) 共享锁 Create index、Lock share? 5 SSX(S/Row-X) 共享行级排它锁 Lock share row exclusive? 6 X(Exclusive) 排它锁 Alter table、Drop able、Drop index、Truncate table 、Lock exclusive

Oracle举例 

 

synergy一台电脑控制两台电脑的配置方法

公司闲置了一台电脑,开发的项目是在Ubuntu系统下配置的开发环境,而我开发的主要代码还是在windows下编写的,所以我使用synergy实现了两台电脑使用一套鼠标键盘的功能~这样自己就舒服多了~

Synergy 是一款远程控制软件。一般的远程控制软件都是将服务器的画面提供给客户端使用, 而Synergy的创意很独特,它将客户端的键盘和鼠标提供给服务器使用。 这样如果你有多台电脑并且每台电脑都有自己的显示器,你可以通过 Synergy 用一组键盘和鼠标控制所有电脑, 而且每台电脑的屏幕可以连接起来,就像在同一台电脑上使用多个显示器一样。

Synergy可以运行在多个平台上,包括Unix/Linux,Mac OS X, Windows98/xp/vista/windows7,而且多台机器的操作系统不同也没有关系。唯一的要求就是这些机器都需要支持TCP/IP网络,彼此间可以通过IP访问。

 

windows服务器设置

首先在 computerA 上启动 Synergy, 选择 Share this computer’s keyboard and mouse (server)。
然后单击下面的Configure…按钮,以配置各个屏幕。单击 Screens 下面的 + 按钮,输入 Screen Name 为 computerA,确定。同样的方法依次添加 computerB 和 computerC。

 

然后我们要设置这三个屏幕的布局。在 Links 的列表框下方有一排输入框和选择框,将其依次设置为以下的内容然后单击下方的 + 按钮。

* 0 to 100% of the left of computerA goes to 0 to 100% of computerB
* 0 to 100% of the right of computerB goes to 0 to 100% of computerA
* 0 to 100% of the left of computerC goes to 0 to 100% of computerA
* 0 to 100% of the right of computerA goes to 0 to 100% of computerC

这样我们就将三个屏幕设置为 B – A – C 的布局了。

注意两个屏幕之间的连接是双向的,比如我们设置了 B <- A,也要同时设置 B -> A,否则鼠标从 A 移动到 B 之后就无法回到 A 了。最终的结果如下。

回到主界面,单击 Advanced… 按钮,确认Screen Name的内容为 computerA,确定。
至此服务器端设置完毕,先不要关闭 Synergy 的对话框。

 

windows客户端设置

在 computerB 上启动 Synergy,选择Use another computer’s shared keybord and mouse(client),并在下面的主机名处填写 computerA。

然后单击 Advanced… 按钮,确认Screen Name的内容为 computerB。

 

在 computerC 上用同样的方法进行设置。

在 computerA 上单击 Test 按钮,然后依次在 computerB 和 computerC 上单击 Test 按钮。我们试着在 computerA 上将鼠标移动到屏幕左侧,就会看到鼠标移动到了 computerB 上,而此时键盘也在控制 computerB;然后将鼠标移动到 computerB 屏幕右侧,鼠标就会回到 computerA;再将鼠标移动到 computerA 右侧,鼠标就会移动到 computerC 上。

Oracle学习笔记,Oracle完全学习文档

Oracle推荐学习图书:

1.常用用户:scott,sys,system
2.常用设置:
set linesize 长度;
set pagesize 页数;

(注明:演示表(emp))
常用命令:
1.ed 名称 可用可以创建记事本编辑sql信息
@名称/路径 调用
2.conn 用户名/密码 [as sysdba]   用户链接
3.select * from scott.emp; 查询其他用户下的表
4.show user; 显示当前链接的用户
5.select * from tab; 查询所有的表
6.desc emp;  显示表结构
7.类型:
NUMBER(4) 长度为4的数字
VARCHAR2(10) 只能容纳长度为10的字符串
DATE 日期
NUMBER(7,2) 小数位占2位,整数位站5位的数字
8.’/’ 表示继续执行上一个操作

SQL(Structured Query Language 结构化查询语言)语句
DML 数据操作语言
DDL 数据定义语言
DCL 数据控制语言

注:{}表示可选的
1.简单查询语句
select 字段 as 别名 from 表名;
2.去除重复选项 select {distinct} 字段 from 表名;
3.字符串的链接: select ‘字符串’||字段||’字符串’ from 表名;
4.运算符: select 字段[运算符(+/-/*//)]字段 from 表名;
5.限定查询: select * from 表名 where 条件;
>,<,>=,<=,= 条件运算
is not null  不为空
and,or  逻辑运算
between ** and **  在范围之间,包含等于
in  在范围之中:select * from emp where empno in (7369,7499);
like 模糊查询,通配符(%:可以匹配任意长度的内容 _:可以匹配一个长度的内容)
6.结果排序:order by 字段  [asc/desc] 排序
7.单行函数:
select upper(‘字母’) from dual;  –转换为大写
lower(‘字符串’)  –转换为小写
initcap()  –将单词的首字母转换为大写
|| –链接字符串 或者使用 concat()
substr(‘字符串’,开始(可以为负数,表示从后截取),结束)  截取字符串,开始可以从0或者1开始,并且可以使用负数
length(‘字符串’) 长度
replace(‘字符串’,’需要替换的字符串’,’替换为的字符串’)  字符串替换
round(5534.23434,2)  =5534.23 四舍五入
trunc(5534.23434)  将舍弃小数位 trunc(5534.23434,2) 保留后两位小数
mod(10,3)  =1   求余
8.日期函数
select sysdate from dual;  获取当前日期
months_between()   求出给定日期的范围的月数
add_months();   在制定日期上加上之的那个的月数,求出只够的月数
next_day();下一个今天是那一个日期
last_day() 求出给定日期的最后一天的日期
9.转换函数(重要)
to_char()  转换为字符串
to_number() 转换为数字
to_date(‘字符串’,’yyyy’)  转换为日期
nvl(‘字段’,0)  将null值变为指定的内容
重要 decode() 类似于if else
select decode(1,1,’内容是1′,2,’内容是2′,3,’内容是3′) from dual;

多表查询,分组查询,子查询

(后续再发布…)

Oracle/Mysql/SqlServer函数区别

Oracle/Mysql/SqlServer函数区别
文章分类:数据库
Sql代码 

1.类型转换

–Oracle
select to_number(‘123’) from dual; –123;
select to_char(33) from dual;  –33;
select to_date(‘2004-11-27′,’yyyy/mm/dd’) from dual;–2004-11-27

–Mysql
select cast(‘123’ as signed integer); –123
select cast(33 as char(2));  –33;
select to_days(‘2000-01-01’);  –730485

–SqlServer
select cast(‘123’ as decimal(30,2)); –123.00
select cast(33 as char(2));  –33;
select convert(varchar(12) , getdate(), 120)

2.四舍五入函数区别

–Oracle
select round(12.86*10)/10 from dual;    –12.9

–Mysql
select format(12.89,1);   –12.9

–SqlServer
select round(12.89,1);   –12.9

3.日期时间函数

–Oracle
select sysdate from dual;  –日期时间

–Mysql
select sysdate();   –日期时间
select current_date();   –日期

–SqlServer
select getdate();   –日期时间
select datediff(day,’2010-01-01′,cast(getdate() as varchar(10)));–日期相差天数

4.Decode函数

–Oracle
select decode(sign(12),1,1,0,0,-1) from dual;–1

–Mysql/SqlServer
select case when sign(12)=1 then 1 when sign(12)=0 then 0 else -1 end;–1

5.判空函数

–Oracle
select nvl(1,0) from dual;  –1

–Mysql
select ifnull(1,0);   –1

–SqlServer
select isnull(1,0);   –1

6.字符串连接函数

–Oracle
select ‘1’||’2′ from dual;  –12
select concat(‘1′,’2’);   –12

–Mysql
select concat(‘1′,’2’);   –12

–SqlServer
select ‘1’+’2′;    –12

7.记录限制函数

–Oracle
select 1 from dual where rownum <= 10;

–Mysql
select 1 from dual limit 10;

–SqlServer
select top 10 1

8.字符串截取函数

–Oracle
select substr(‘12345’,1,3) from dual;

–Mysql/SqlServer
select substring(‘12345’,1,3);

8.把多行转换成一合并列

–Oracle
select wm_concat(列名) from dual; –多行记录转换成一列之间用,分割

–Mysql/SqlServer
select group_concat(列名);

 

SQLServer和Oracle的常用函数对比

  1.绝对值
  S:select abs(-1) value
  O:select abs(-1) value from dual

  2.取整(大)
  S:select ceiling(-1.001) value
  O:select ceil(-1.001) value from dual

  3.取整(小)
  S:select floor(-1.001) value
  O:select floor(-1.001) value from dual

  4.取整(截取)
  S:select cast(-1.002 as int) value
  O:select trunc(-1.002) value from dual

  5.四舍五入
  S:select round(1.23456,4) value 1.23460
  O:select round(1.23456,4) value from dual 1.2346

  6.e为底的幂
  S:select Exp(1) value 2.7182818284590451
  O:select Exp(1) value from dual 2.71828182

  7.取e为底的对数
  S:select log(2.7182818284590451) value 1
  O:select ln(2.7182818284590451) value from dual; 1

  8.取10为底对数
  S:select log10(10) value 1
  O:select log(10,10) value from dual; 1

  9.取平方
  S:select SQUARE(4) value 16
  O:select power(4,2) value from dual 16

  10.取平方根
  S:select SQRT(4) value 2
  O:select SQRT(4) value from dual 2

  11.求任意数为底的幂
  S:select power(3,4) value 81
  O:select power(3,4) value from dual 81

  12.取随机数
  S:select rand() value
  O:select sys.dbms_random.value(0,1) value from dual;

  13.取符号
  S:select sign(-8) value -1
  O:select sign(-8) value from dual -1
  ———-数学函数

  14.圆周率
  S:SELECT PI() value 3.1415926535897931
  O:不知道

  15.sin,cos,tan 参数都以弧度为单位
  例如:select sin(PI()/2) value 得到1(SQLServer)

  16.Asin,Acos,Atan,Atan2 返回弧度

  17.弧度角度互换(SQLServer,Oracle不知道)
  DEGREES:弧度-〉角度
  RADIANS:角度-〉弧度

  ———数值间比较

  18. 求集合最大值
  S:select max(value) value from
  (select 1 value
  union
  select -2 value
  union
  select 4 value
  union
  select 3 value)a

  O:select greatest(1,-2,4,3) value from dual

  19. 求集合最小值
  S:select min(value) value from
  (select 1 value
  union
  select -2 value
  union
  select 4 value
  union
  select 3 value)a

  O:select least(1,-2,4,3) value from dual

  20.如何处理null值(F2中的null以10代替)
  S:select F1,IsNull(F2,10) value from Tbl
  O:select F1,nvl(F2,10) value from Tbl
——–数值间比较

  21.求字符序号
  S:select ascii(‘a’) value
  O:select ascii(‘a’) value from dual

  22.从序号求字符
  S:select char(97) value
  O:select chr(97) value from dual

  23.连接
  S:select ’11’+’22’+’33’ value
  O:select CONCAT(’11’,’22’)||33 value from dual

  23.子串位置 –返回3
  S:select CHARINDEX(‘s’,’sdsq’,2) value
  O:select INSTR(‘sdsq’,’s’,2) value from dual

  23.模糊子串的位置 –返回2,参数去掉中间%则返回7
  S:select patindex(‘%d%q%’,’sdsfasdqe’) value
  O:oracle没发现,但是instr可以通过第四霾问刂瞥鱿执问?BR>  select INSTR(‘sdsfasdqe’,’sd’,1,2) value from dual 返回6

  24.求子串
  S:select substring(‘abcd’,2,2) value
  O:select substr(‘abcd’,2,2) value from dual

  25.子串代替 返回aijklmnef
  S:SELECT STUFF(‘abcdef’, 2, 3, ‘ijklmn’) value
  O:SELECT Replace(‘abcdef’, ‘bcd’, ‘ijklmn’) value from dual

  26.子串全部替换
  S:没发现
  O:select Translate(‘fasdbfasegas’,’fa’,’我’ ) value from dual

  27.长度
  S:len,datalength
  O:length

  28.大小写转换 lower,upper

  29.单词首字母大写
  S:没发现
  O:select INITCAP(‘abcd dsaf df’) value from dual

  30.左补空格(LPAD的第一个参数为空格则同space函数)
  S:select space(10)+’abcd’ value
  O:select LPAD(‘abcd’,14) value from dual

  31.右补空格(RPAD的第一个参数为空格则同space函数)
  S:select ‘abcd’+space(10) value
  O:select RPAD(‘abcd’,14) value from dual

  32.删除空格
  S:ltrim,rtrim
  O:ltrim,rtrim,trim

  33. 重复字符串
  S:select REPLICATE(‘abcd’,2) value
  O:没发现

  34.发音相似性比较(这两个单词返回值一样,发音相同)
  S:SELECT SOUNDEX (‘Smith’), SOUNDEX (‘Smythe’)
  O:SELECT SOUNDEX (‘Smith’), SOUNDEX (‘Smythe’) from dual
  SQLServer中用SELECT DIFFERENCE(‘Smithers’, ‘Smythers’) 比较soundex的差
  返回0-4,4为同音,1最高

  ————–日期函数

  35.系统时间
  S:select getdate() value
  O:select sysdate value from dual

  36.前后几日
  直接与整数相加减

  37.求日期
  S:select convert(char(10),getdate(),20) value
  O:select
trunc(sysdate) value from dual
  select to_char(sysdate,’yyyy-mm-dd’) value from dual

  38.求时间
  S:select convert(char(8),getdate(),108) value
  O:select to_char(sysdate,’hh24:mm:ss’) value from dual

  39.取日期时间的其他部分
  S:DATEPART 和 DATENAME 函数 (第一个参数决定)
  O:to_char函数 第二个参数决定
参数———————————下表需要补充
  year yy, yyyy
  quarter qq, q (季度)
  month mm, m (m O无效)
  dayofyear dy, y (O表星期)
  day dd, d (d O无效)
  week wk, ww (wk O无效)
  weekday dw (O不清楚)
  Hour hh,hh12,hh24 (hh12,hh24 S无效)
  minute mi, n (n O无效)
  second ss, s (s O无效)
  millisecond ms (O无效)
  ———————————————-

  40.当月最后一天
  S:不知道
  O:select LAST_DAY(sysdate) value from dual

  41.本星期的某一天(比如星期日)
  S:不知道
  O:SELECT Next_day(sysdate,7) vaule FROM DUAL;

  42.字符串转时间
  S:可以直接转或者select cast(‘2004-09-08’as datetime) value
  O:SELECT To_date(‘2004-01-05 22:09:38′,’yyyy-mm-dd hh24-mi-ss’) vaule FROM DUAL;

  43.求两日期某一部分的差(比如秒)
  S:select datediff(ss,getdate(),getdate()+12.3) value
  O:直接用两个日期相减(比如d1-d2=12.3)
  SELECT (d1-d2)*24*60*60 vaule FROM DUAL;

  44.根据差值求新的日期(比如分钟)
  S:select dateadd(mi,8,getdate()) value
  O:SELECT sysdate+8/60/24 vaule FROM DUAL;

  45.求不同时区时间
  S:不知道
  O:SELECT New_time(sysdate,’ydt’,’gmt’ ) vaule FROM DUAL;

  —–时区参数,北京在东8区应该是Ydt——-
  AST ADT 大西洋标准时间
  BST BDT 白令海标准时间
  CST CDT 中部标准时间
  EST EDT 东部标准时间
  GMT 格林尼治标准时间
  HST HDT 阿拉斯加—夏威夷标准时间
  MST MDT 山区标准时间
  NST 纽芬兰标准时间
  PST PDT 太平洋标准时间
  YST YDT YUKON标准时间

Oracle 11g安装问题解决方法大全

oracle 11g安装先决条件检查全部失败,详细信息如下:
//物理内存
物理内存 – 此先决条件将测试系统物理内存总量是否至少为 922MB (944128.0KB)。
预期值
 : N/A
实际值
 : N/A
 错误列表:
 –
//可用物理内存
PRVF-7531 : 无法在节点 "LENOVO-F4F9938F" 上执行物理内存检查  – Cause:  无法在指示的节点上执行物理内存检查。  – Action:  确保可以访问指定的节点并可以查看内存信息。 
可用物理内存 – 此先决条件将测试系统可用物理内存是否至少为 50MB (51200.0KB)。
预期值
 : N/A
实际值
 : N/A
 错误列表: 
 –
PRVF-7563 : 无法在节点 "LENOVO-F4F9938F" 上执行可用内存检查  – Cause:  无法在指示的节点上执行可用内存检查。  – Action:  确保可以访问指定的节点并可以查看内存信息。
//交换空间大小
交换空间大小 – 此先决条件将测试系统是否具有足够的总交换空间。
预期值
 : N/A
实际值
 : N/A
 错误列表: 
 –
PRVF-7574 : 无法在节点 "LENOVO-F4F9938F" 上执行交换空间大小检查  – Cause:  无法在指示的节点上执行交换空间检查。  – Action:  确保可以访问指定的节点并可以查看交换空间信息。 
 –
PRVF-7531 : 无法在节点 "LENOVO-F4F9938F" 上执行物理内存检查  – Cause:  无法在指示的节点上执行物理内存检查。  – Action:  确保可以访问指定的节点并可以查看内存信息。
……
总之,所有检查都无法执行
电脑内存2G,硬盘250G的,在各个盘装都无法坚持先决条件,换成超级管理员登录,关闭杀毒软件,都不行。实在不解,请高人指点。

回复:oracle11g无法安装

——————————————————————————–

如果是官方下载的 Oracle 11g 肯定是没有问题的!!版本对不对!

——————————————————————————–

//物理内存
物理内存 – 此先决条件将测试系统物理内存总量是否至少为 922MB (944128.0KB)。
内存太小了. 如果不能加内存,就换个Oracle 版本. 比如10g或者9i. 
—————————————————————————— 
Blog:  
网上资源:  
相关视频: 
DBA1 群:62697716(满); DBA2 群:62697977

——————————————————————————–

电脑内存2G,硬盘250G的,在各个盘装都无法检查先决条件,换成超级管理员登录,关闭杀毒软件,都不行。实在不解,请高人指点。

——————————————————————————–

oracle 11g安装先决条件检查全部失败,详细信息如下:
//物理内存
物理内存 – 此先决条件将测试系统物理内存总量是否至少为 922MB (944128.0KB)。
预期值
 : N/A
实际值
 : N/A
 错误列表:
 –
//可用物理内存
PRVF-7531 : 无法在节点 "LENOVO-F4F9938F" 上执行物理内存检查 – Cause: ……
你上面的有几个错误我也有出现过,但只要有2g的内存和足够的交换区,硬盘空间,那些所需的包都有装上的话,那些失败选项可以忽略,照样可以安装成功。
另一个可能是你所选的软件与你系统不搭配。
如:32位的与系统X86是相对应的(个人用的较常见)
   64位的与X86_64

——————————————————————————–

不过如果在windows 下装的呢要注意端口是否与登录上网的有冲突

——————————————————————————–

//物理内存
物理内存 – 此先决条件将测试系统物理内存总量是否至少为 922MB (944128.0KB)。
内存太小了. 如果不能加内存,就换个Oracle 版本. 比如10g或者9i.
内存就是1G的也可以装得了,只是较卡而已。这个问题是可以忽略的。
交换区是可以扩展的,修改一下就行了。总体上还是得看你出了什么样的错误。

能截个图看下吗?
无法检查先决条件,图片如下:
win32_11gR2_database_1of2.zip,win32_11gR2_database_2of2.zip版本

——————————————————————————–

电脑内存2G,硬盘250G的,在各个盘装都无法检查先决条件,换成超级管理员登录,关闭杀毒软件,都不行。实在不解,请高人指点。
先把交换区和temp的空间都搞大些,在试试,我在linux下遇到过这样的情况,不过把其他的错误解决后,这个就消失了。

——————————————————————————–

引用 4 楼 shizhijie737 的回复:
先把交换区和temp的空间都搞大些,在试试,我在linux下遇到过这样的情况,不过把其他的错误解决后,这个就消失了。
我现在是在windows下安装的,缓存已经设到4G了,现在不是前置条件不满足,而是无法检查

——————————————————————————–

遇到同样的问题,up

——————————————————————————–

我也碰到过,不过可以忽略,也可以安装成功。

——————————————————————————–

我碰到过部分检测没有通过的,但忽略就可以了,不知道你这个行不行

——————————————————————————–

我的虚拟机装oracle 11g r2 时也提示交换空间不足,安装失败
换了oracle 11g r1 安装成功了,建议楼主别装r2。
另外,交换空间大小怎么设置?产生此错误可能是因为使用虚拟光驱引起的吧?

——————————————————————————–

增大虚存。
安装桌面版。不装企业级server。

——————————————————————————–

Oracle要求内存至少为1G,但内存为1G–2G时,交换空间要求为内存的1.5倍;
磁盘空间应该是够的。。。

——————————————————————————–

帮你顶一下 希望有人看到这个 我也遇到这个问题了。现在不知道咋整啊

——————————————————————————–

oracle 11g最终还是没有装上,放弃了
下了个9g的,server端,在administrator帐户下安装成功,需注意一下几点:
1,安装前彻底删除安装失败的痕迹
2,安装文件路径,安装路径均不可出现中文
3,安装客户端,因为报错找不到java运行环境,所以放弃自带客户端,下载了plsql developer,安装后,数据库可用
谢谢各位关注

——————————————————————————–

有可能是我当前系统帐户是中文帐户的原因

——————————————————————————–

我在vista下安装的11.2的数据库,遇到跟楼主相同的问题,最后发现原因是没有以管理员方式运行安装程序setup.exe。
解决的办法是:右键setup.exe,选择"Properties",在弹出的页面中切换到"Compatiblity",然后勾上"Run this program as
an Administrator",确定。
再次运行setup.exe,就可以成功安装oracle database了。

——————————————————————————–

我也遇到和楼主一样的情况,全部检查项都失败,实际值是:N/A。我当前账号已经是administrator了,还是不行

——————————————————————————–

操作系统windows2008r2-cn 问题相同!

——————————————————————————–

问题找到了: 操作系统如果是企业版的,应当选择“服务器型”,其他,应选择“桌面型”。

——————————————————————————–

全部忽略装上了 开始和楼主一样
4g的内存的 笔记本可能检测有问题

——————————————————————————–

打开C盘的默认共享,再重新检查即可!