SQLServer学习笔记

SQLServer学习时期总结,如有不足,望指正

Java数据库编程

数据库对象

基础知识:数据库管理系统(DBMS  DataBase Manage System)

1、数据库是一套完整的软件。

2、分为客户端服务器端两部分。安装的时候,都同时安装了客户端和服务器。

i.          服务器就是后台程序sqlservr.exe  开机后无条件运行  没有界面。

ii.        客户端就是SQL Server Management Studio(管理控制台)

3、服务器端又分为软件和数据两部分。

i.          软件就是后台程序

ii.        数据就是后台程序管理的数据仓库,可以通过客户端查看它。

4、数据是怎么组织的?用表格的形式。

一个数据库管理系统,可以管理多个数据库(DataBase)。

每个数据库都能包含多张表(Table)。

每个表里面都可以保存很多数据。

5、数据只有表吗?

视图(View)、存储过程(Procedure)、函数(Function)、索引(Index)

以上,连同数据库、表一起,合称数据库对象

6、怎么操纵数据库对象呢?

A、使用客户端。 手工操作  命令模式(SQL  Structured Query  Language)

B、写Java程序(JDBC)

SQL发展史:

1、1992年,各厂家一起推出标准SQL92

2、SQL方言 SQL Server的方言是:T-SQL   Oracle的方言是:PL/SQL

3、SQL不区分大小写。

数据库:

1、系统库:master(主控)、model(模版)、msdb(不知道干啥的)、tempdb(临时库)

2、创建数据库:手工操作;SQL实现: create database 库名   go

3、删除数据库:手工操作;   drop database 库名    go

4、客户端有当前数据库,默认是master。当前库是不能删除的。

5、切换当前库:手工操作;   use  库名      go

数据库对象:

1、创建都用create

2、删除都用drop

3、标识符命名  字母数字下划线组合,数字不准打头,不准用关键字。

表:

1、创建表:   create table 表名 (若干列的定义)    go

2、列的定义:  列名   数据类型    [约束]     多个列用逗号隔开

3、删除表:  drop table 表名      go

数据类型:

1、整数类型:int   bigint

2、浮点数:real   float   money(SQL Server特有)

3、定点数:Numeric(n,m)  Decimal(n,m)  Number  例子:Decimal(9,3)

4、字符串:char(n)   varchar(n)   n是最大长度

5、日期:datetime(年月日时分秒)

6、二进制:BLOB  CLOB varbinary

7、逻辑:bit

约束:

1、主键约束:primary key  每张表都只能有最多一个主键。 唯一、不为空

2、非空约束:not null     不允许为空,必须有值。

3、唯一约束:unique      唯一,值不能重复

4、检查约束:check(条件)  表中写入数据必须符合条件。

5、默认约束:default(值)   列的默认值

6、自增约束:identity(1,1)  这个列的值归数据库自己控制,你不要向其中写值。这个列的数据类型必须是int,在同一张表里面,这种约束只能出现一次。

基本语法:

1、SQL语句不区分大小写,包括表名、列名

2、行末不需要分号

3、DDL类型的语句下一行必须写go

4、--开头的是单行注释

5、/*  */是多行注释

6、SQL里面字符串必须是单引号括起来的

SQL语句也是分类的:

1、创建、修改、销毁 数据库对象的语句 create dropalter replace use  DDL

2、向表中插入、修改、删除、查询数据的语句insert update delete select  DML

3、向用户授权或取消授权的语句 grantrevoke  DCL

增删改查

1、怎么往表里面加入数据?

手工操作  只准编辑两百条。

代码实现  insert into 表名(列名清单) values(值清单)  向表中加入一条新的记录

1、自动增长列不要赋值

2、列名清单有几个列,值清单就要有几个值

3、列名清单必须是这个表的列,可以缺少,不能多

4、允许缺少的列:自动增长列、默认约束列、允许为空列

2、怎么修改表里面的数据?

手工操作  编辑前200行

代码实现  update 表名 set 列名=新值 where 条件  

1、如果不写where条件?全表所有的记录的列都改成新值。

2、一次允许修改多个列,用逗号隔开,列名不能重复

3、自动增长列不允许修改

3、怎么删除表里面的数据?

手工操作 

代码实现  delete from 表名 where 条件

1、如果不写where条件?全表所有的记录都被删除了

2、删除表内所有数据 可以用delete不加条件,也可以用truncate table 表名  差别:

a)        delete比较慢  因为delete是一行一行删除的,并且每行删除都记录日志

b)       truncate快,因为它不写行日志

c)        delete操作不影响自动增长列  truncate操作会让自动增长归零

4、怎么查看表里面的数据?

手工操作  选择前1000行

代码实现  select */列名清单 from 表名

1、只想显示某几个列,就写列名清单,需要显示所有的列,就写*

2、只想显示前n行,在列名清单或*之前,写top n

3、也可以加where条件,满足条件的记录就显示出来。

4、还可以把查询结果用另一张表保存下来  select之后,from之前,插一个into 表名。  这个表可以不存在,会新建这张表。表的列名、数据类型等都和原表一样。

5、where条件怎么用?

1、update、delete、select才有where条件。也叫where子句。

2、为每行记录做一个逻辑运算,运算结果为true,那么这条记录就算符合条件。

3、单个的关系运算,叫一个条件  多个条件组合起来,叫复合条件。and与运算,表示两个条件都成立,才算成立;or或运算,表示两个条件只要满足一个,就算成立。

4、列 between Aand B,列的值在A到B之间   例子:agebetween 20 and 22

5、列 in (值清单)  表示列的值在这个值清单的范围内。 例子:age in(20,22)

6、模糊匹配  列 like ‘模式串’   %代表任意个数字符  _代表一个字符  例子:

name like ‘X%’   --所有姓X的

name like ‘X_’   --所有姓X但是单名的

name like ‘%X’   -- 名字用X结尾的

name like ‘%X%’  -- 名字中只要有X字的

7、判断为空  列 is null表示为空就是true,is not null表示不为空就是true

8、默认查询结果是自然排序,基本上以ID列值为准,用ordereby修改排序结果。

查询功能的发展

查询的所有行为,都不会对原始数据有任何影响。

1、别名

在查询语句里面,可以对表(视图)或列取一个别名,仅仅在这一个语句里面有效。

表的别名是在查询语句里面用。

列的别名是在查询结果里面用。

语法:在表或列后面写 as 别名

2、计算列

查询语句中,某个列不是表的列,而是一个计算公式,查询结果里面,这个列保存的是计算结果。

计算列本身没有名字,叫无名列。可以通过as给它一个别名。

3、排重

在查询结果里面排除掉重复记录。在select之后,列名或*之前,写distinct

4、聚合函数

计数:数一下,查询结果有多少条记录。

count(*)  只要符合where条件,每条记录都算1

count(列名)  只要符合where条件,这个列的值不是NULL的话,算1

count(distinct 列名)  第二类基础上,排除重复数据,再

求和:算一下,这个累加起来有多少   sum(数字类型的列或运算结果)

求平均值:算一下,这个平均结果是多少   avg(数字类型的列或运算结果)

最大值:找一下,这个最大的值是多少  max(列或运算结果)

最小值:找一下,这个最小的值是多少  min(列或运算结果)

5、分组统计

使用的关键字是group by。

1、group by后面必须写一个或多个列。

2、查询子句里面也必须写这些列,不能多也不能少,然后就只能写聚合函数

3、可以在group by后面写having子句,having里面可以写查询条件。

4、where的条件全部都是针对原始数据的

5、having的条件全部都是针对统计结果的。

6、SELECT的执行顺序是:from--> where --> group by --> select --> having -->order by

7、order by排序,指的是查询结果按照什么顺序摆布。如果有group by,那么order by的范围就是select子句列出来的所有内容;如果没有,order by可以使用表的任意一个列。

8、group by后面写的列不止一个,叫多维度统计。

6、子查询:查询语句中又嵌套查询语句

第一种:子查询用在外层查询的条件where部分,用在in范围条件里面。子查询的查询结果必须只有一个列。  查询的时候,层层限制它的查询范围  影响了行数

第二种:子查询用在外层查询的select部分。  1、子查询的查询结果必须只有一个列;2、子查询的查询结果必须只有一行。  缺点:主查询的查询结果有多少条记录,子查询就要执行多少遍。性能表现不佳。   都可以转化为关联查询  增加了列,行数不变

第三种:子查询用在外层查询的from部分。把查询结果当作一张表来用。   优点:提高性能表现。

7、组合查询:由多个查询组成,平等关系,把查询结果合并在一起。

关键字是 union 或 union all,不写all表示排重。

合并有严格的要求:

1、多个查询语句,每一个的列数相同。

2、对应的列数据类型兼容。

8、连接查询:一个select语句查询的数据来自多个表,from后面有多个表。

简单连接——交叉连接  直接在from后面写多个表 查询结果是多个表的笛卡尔积。

等值连接  在简单连接的基础上,增加条件判断,条件是每个表各出一个列进行等值判断  结果是对笛卡尔积进行筛选

内连接:主表 inner  join 从表 on 主表.列=从表.列   特点:查询结果必须严格遵守on后面的条件。

左外连接: 主表 left outerjoin 从表 on 主表.列=从表.列  特点:主表的所有记录都能查询出来,但是从表的记录必须符合on后面的条件。不符合的得到null

右外连接: 主表 right outerjoin 从表 on 主表.列=从表.列  特点:从表的所有记录都能查询出来,但是主表的记录必须符合on后面的条件,不符合的得到null

全外连接: 主表 full outerjoin 从表 on 主表.列=从表.列  特点:主表和从表的所有记录都能查询出来,但是主表和从表的记录都必须符合on后面的条件,不符合的得到null

内连接和左外连接效果一致。主表的做条件的列的值,在从表里面全都存在。

内连接和右外连接效果一致。从表的做条件的列的值,在主表里面全都存在。

内连接和全外连接效果一致。上述两个条件都成立。

外键约束:从表的某个列的值不是凭空乱来的,而是根据主表的ID值而来的。所以外键约束要建立在从表上。在从表的建表语法里面,加一行:

foreign key (从表某个列)references 主表(主表的ID列)。

一对多关系:主表的一条记录,可以对应从表的N条记录。从表的每条记录都只能对应主表的一条记录。

1、必须先创建主表,再创建从表。

2、必须先给主表加入数据,然后再给从表加入数据。

3、必须先删除从表的数据,然后再删除主表的数据。

4、必须先删除从表,再删除主表。

表和表之间:一对一   一对多  多对多

一对一:它是一对多关系的一个特例,做外键约束的从表的列本身是从表的主键列。

数据库设计

一、设计过程

什么是数据库设计?

设计指的是数据库的表结构的设计。

设计的目的是数据要井井有条,增删改查都比较快,尽量减少数据冗余。

为什么要做数据库设计?

一个良好的数据库设计,能够达到以上目的,并且充满美感。

如何做数据库设计?

数据库设计是整个软件设计的一部分。

软件设计步骤:  需求分析  概要设计  详细设计  编码开发  测试验证  交付验收

数据库设计步骤:需求分析  概念设计  逻辑设计  物理设计

二、概念模型  ER图

E是Entity,实体类的意思。R是Relational,关系的意思。

绘制ER图,要用到MicrosoftVisio软件。

什么是实体?客观存在并可相互区别的事物称为实体。Entity,绘制为方框。

什么是属性?实体所具有的某种特性叫属性。Attribute,绘制为椭圆形。

1、简单属性和复合属性。
         2、单值属性和多值属性。

3、保存属性和派生属性。

4、空值属性

5、复杂属性

6、键属性 实体的某个属性值是唯一的,通过这个属性可以把它和其他实体区分开。

什么是联系?将两个或多个截然不同的实体以特定的意义关联在一起。Relationship,绘制为菱形

同一个类型的实体集合在一起,叫实体集EntitySet。

一个简单属性它的值--可以取值的范围,叫值集。

实体:分为强实体和弱实体。

强实体——有键属性的实体。

弱实体——没有键属性的实体。

概念设计最终的目的是绘制出ER图。

三、逻辑数据模型设计

把ER图转化为表结构 的设计。

部门表:

ID

Name

Address

员工表:

ID

Name

PhoneNum

Work

DeptID

SexID

项目表:

ID

Name

Address

DeptID

把一对多的关系转化为表结构 的设计

表现为多的一方实体类的属性。增加一个属性保存一的一方的实体类的ID。

把多对多的关系转化为表结构 的设计

增加一个关联关系表

项目-员工关联关系表

ProjectID

EmployeeID

把多值属性转化为表结构 的设计

1、只能单选的多值属性:

做一个表,记录所有的选项:例子性别表

ID

Sex-Option

在实体类里面,增加一个列,保存选项表的ID。

2、可以多选的多值属性:

做一个表,记录所有的选项:例子  爱好表

ID

Like-Option

做一个关联关系表,记录每个人的选项表的选择

员工-爱好关联关系表

EmployeeID

LikeID

JDBC

1、JDBC是什么意思?

Java DataBaseConnectivity Java语言的数据库连接

一套数据库编程接口,Java语言可以利用这个接口,用统一的方式访问各种关系型数据库。

2、JDBC由哪些部分组成?

JDBC API(ApplicationProgramming Interface)或叫做规范    驱动程序

3、JDBC有一些什么编程对象?

Connection  Statement ResultSet  DriverManager  PreparedStatement

例子:家乐福系统

1、Customer对象:cusLoginName  cusLoginPass cusRealyName

2、Product对象:proNo  proName proNumber  proPrice

3、按照上述要求,创建表

4、驱动包  sqljdbc4.jar (jar包是Java语言特有的一种包文件。)

5、数据库驱动包的准备:把数据库驱动包sqljdbc4.jar复制到项目的lib目录,然后选择build Path-->Configure Build Path,点击“Add Jar”,把压缩包加入到项目路径中。

6、准备写访问数据库的代码

7、驱动类加载  com.microsoft.sqlserver.jdbc.SQLServerDriver

8、创建连接    url=”jdbc:sqlserver://服务器的地址:数据库端口DataBaseName=库名

服务器的地址:数据库服务器所在的电脑的IP地址,也可以是域名或机器名。localhost相当于127.0.0.1,表示是自己的电脑,回圈地址。或者机器名

数据库端口:数字编号,最小是0,最大是65535。SQL Server数据库默认是1433。

库名:就是createdatabase创建的对象。

9、获得语句对象

Statement        stmt  = conn.createStatement();

PreparedStatement  pst  = conn.prepareStatement(SQL字符串);

10、执行SQL

stmt.executeUpdate(SQL字符串); 返回int,意思是受影响的行数。

11、释放资源

ResultSet对象要close()

Statement对象要close()

Connection对象要close()

总结:JDBC操作:

1、加载驱动、创建连接和获得语句对象 几乎一模一样。

2、执行SQL:

增删改:调用executeUpdate(),返回一个int

查询:调用executeQuery(),返回一个ResultSet对象

3、查询多出一个步骤:解析查询结果

ResultSet代表一个查询结果,是有多行多列的

首先调用next()方法。第n次调用next()方法,它检查是否有第n行数据,有的话,它就把内部指针指向第n行,返回true;如果没有,返回false。

获取内部指针指向的这一行数据,要用get开头的一系列方法。getInt() getString() getDouble() getDate() getObject() 这些方法统统都是一个参数,输入列名或者下标。下标从1算起

4、释放资源 ResultSet  Statement Cpnnection  必须无条件执行finally

SQL注入攻击:

在你输入账号密码的地方,输入一个特殊的内容aa’ or 1=1 --

拼出来的SQL就会变成查询整个表

原因是:SQL是用字符串拼出来的

PreparedStatement:

1、带预处理的语句对象。优点:SQL里面可以带参数,而且性能表现好。  缺点:一个语句对象绑定了一句SQL。(和普通的Statement对比,普通的Statement是在执行execute一系列方法的时候,通过参数指定SQL的,所以可以执行各种不同的SQL。)

Statement

PreparedStatement

SQL语句

不能用?做参数,也没有参数替换

可以用?做参数,可以替换参数

使用SQL

execute系列方法中带入SQL,所以每次执行的SQL可以不同

在创建的时候就带入了SQL,所以每次只能执行同一句SQL(值可以不一样)

获得手段

conn.createStatement();

conn.prepareStatement(SQL语句);

替换参数

pst.setXXXX(index, 值);

执行SQL

executeQuery(SQL语句)

executeUpdate(SQL语句)

execute(SQL语句)

executeQuery()

executeUpdate()

execute()

2、SQL里面可以用?做替换参数。?不能用在表名、列名上面。

错误:select *from ?   select ?,?,? from Customer

3、获得语句对象的手段:

PreparedStatement pst = conn.prepareStatement(SQL语句);

4、替换参数:把对应的?替换成现成的值。

pst.setXXXX(index, 值);   setInt  setDouble setString  setDate  setObject

5、执行SQL:executeQuery  executeUpdate execute  都不带参数。

JDBC固定套路:

// 查询:

ResultSet rs =null;

PreparedStatement pst=null;

Connection conn=null;             

try{

         // 加载驱动

         String drvClass = "com.microsoft.sqlserver.jdbc.SQLServerDriver";

         Class.forName(drvClass);

         // 创建连接

         String url      = "jdbc:sqlserver://localhost:1433;DataBaseName=school";

         String user     = "sa";

         String password = "123456";

         conn = DriverManager.getConnection(url, user, password);

         // 这是带参数的SQL

         String sql = "select ……可以带?";

         // 获得语句对象

         pst  = conn.prepareStatement(sql);

         // 替换参数

         pst.setString(1, username);

         pst.setString(2, userpwd);

         // 执行SQL,得到查询结果

         rs = pst.executeQuery();

         // 解析查询结果

         ……

} catch (Exception e) {

         // TODO Auto-generated catch block

         e.printStackTrace();

} finally{

         // 释放资源

         try {

                   if ( rs != null) rs.close();

         } catch (SQLException e) {

                   e.printStackTrace();

         }

         try {

                   if (pst != null) pst.close();

         } catch (SQLException e) {

                   e.printStackTrace();

         }

         try {

                   if (conn != null) conn.close();

         } catch (SQLException e) {

                   e.printStackTrace();

         }

}

// 查询:

PreparedStatement pst=null;

Connection conn=null;             

try{

         // 加载驱动

         String drvClass = "com.microsoft.sqlserver.jdbc.SQLServerDriver";

         Class.forName(drvClass);

         // 创建连接

         String url      = "jdbc:sqlserver://localhost:1433;DataBaseName=school";

         String user     = "sa";

         String password = "123456";

         conn = DriverManager.getConnection(url, user, password);

         // 这是带参数的SQL

         String sql = "insert 或者update 或者 delete  可以带?";

         // 获得语句对象

         pst  = conn.prepareStatement(sql);

         // 替换参数

         pst.setString(1, username);

         pst.setString(2, userpwd);

         // 执行SQL,得到查询结果

         int n = pst.executeUpdate();

         // 处理执行结果

         ……

} catch (Exception e) {

         // TODO Auto-generated catch block

         e.printStackTrace();

} finally{

         // 释放资源

         try {

                   if (pst != null) pst.close();

         } catch (SQLException e) {

                   e.printStackTrace();

         }

         try {

                   if (conn != null) conn.close();

         } catch (SQLException e) {

                   e.printStackTrace();

         }

}

持久层

专职其事。  解耦合

DAO  持久层的类   Data Access Object

专门创建一个DAO类,类名:表名+Dao,里面的每个方法都是对这张表的JDBC操作。

可以有的操作是:

增:addXXXX(XXXX xx);

删:removeXXXX(XXXXxx);  // 其实只用到对象的id属性。

改:updateXXXX(XXXXxx);  // 其实是以id作为where条件,用对象的属性值覆盖掉表里面的旧值

查:有多个查询方法

只查询到一条记录(只返回一个对象) getXXXXByID(ID)

能查到多条记录(返回List)  queryXXXXByxxxx(条件值)


猜你喜欢

转载自blog.csdn.net/slowly_man/article/details/78006177