一、cmd操作数据库
1.创建一个库
create database 库名
create database 库名 character set 编码(create database web character set gbk)
查看编码 show create database web;
2.删除一个库
drop database 库名
3.使用库 use 库名
4.查看当前正在操作的库 select database();
二、对数据库表的操作
1.创建一张表
create table 表名(
字段名 类型(长度) [约束],
字段名 类型(长度) [约束],
字段名 类型(长度) [约束]
);
2.查看数据库表show tables;
查看表的结构desc 表名
3.删除一张表drop table 表名
4.修改表
4.1 添加一列
alter table 表名 add 字段名 类型(长度) [约束]
4.2 修改列的类型(长度、约束)
alter table 表名 modify 要修改的字段名 类型(长度) [约束
4.3 修改列的列名
alter table 表名 change 旧列名 新列名 类型(长度) [约束]
4.4 删除表的列
alter table 表名 drop 列名
4.5 修改表名
rename table 表名 to 新表名
4.6 修改表的字符集
alter table 表名 character set 编码
三、对数据库表记录进行操作(修改)
1.插入记录
insert into 表名(列名1,列名2,列名3……) values(值1,值2,值3……)
insert into 表名 values(值1,值2,值3……)
1.1 插入数据中文乱码问题解决办法
方式一:【不建议!】
直接修改数据库安装目录里面的my.ini文件的第57行
dafault-character-set=utf8
方式二:
set names gbk;
2.1 不带条件的
update 表名 set 字段名=值, 字段名=值, 字段名=值……(它会将该列的所有记录都更改)
2.2 带条件的
update 表名 set字段名=值, 字段名=值, 字段名=值…… where 条件
3.删除表记录
3.1 带条件的
delete from 表名 where 条件
注意,删除后,uid不会重置!
3.2.不带条件的
删除操作
delete from 表名;
3.3 面试题
说说delete与truncate的区别?
delete删除的时候是一条一条的删除记录,它配合事务,可以将删除的数据找回。
truncate删除,它是将整个表摧毁,然后再创建一张一模一样的表。它删除的数据无法找回。
注意:delete删除,uid不会重置!而使用truncate操作,uid会重置[因为它删除了表结构,然后再创建一张一模一样的表,所以再次插入数据的数据的时候从1开始。]
4.查询操作
语法:
select [distinct] *| 列名,列名 from 表名 [where条件]
4.1 简单查询
1.查询所有商品
select * from product;
- 查询商品名和商品价格
select pname,price from product;
3.查询所有商品信息使用表别名
select * from product as[可以省略] p;
4.查询商品名,使用列别名
select pname as[可以省略] p from product
5.去掉重复值(按照价格)
select distinct(price) from product;
6.将所有的商品的价格+10进行显示
select pname,price+10 from product;
4.2 条件查询
1.查询商品名称为"左慈"的商品信息
select * from product where pname=“左慈”;
2.查询价格>60元的所有商品信息
select * from product where price>60;
3.查询商品名称含有"士"字的商品信息
select * from product where pname like '%士%';
4.查询商品id在(3,6,9)范围内的所有商品信息
select * from product where pid in(3,6,9);
5.查询商品名称含有"士"字并且id为6的商品信息
select * from product where pname like '%士%' pid=6;
6.查询id为2或者6的商品信息
select * from product where pid=2 or pid=6;
4.3 排序
1.查询所有的商品,按价格进行排序(升序、降序)
select * from product order by price asc;(升序)
select * from product order by price desc;(降序)
2.查询名称有"士"的商品信息并且按照价格降序排序
select * from product where pname like '%士%' order by price desc;
4.4 聚合函数
1.获得所有商品的价格的总和
select sum(price) from product ;
2.获得所有商品的平均价格
select avg(price) from product ;
3.获得所有商品的个数
select count(*)from product ;
4.5 分组操作
1.添加分类id (alter table product add cid varchar(32);)
2.初始化数据
update product set cid='1';
update product set cid='2' where pid in (5,6,7);
1.根据cid字段分组,分组后统计商品的个数。
select cid ,count(*) from product group by cid;
2.根据cid分组,分组统计每组商品的平均价格,并且平均价格大于20000元。
select cid,avg(price) from product group by cid having avg(price)>20000;
4.6 查询总结
select 一般在的后面的内容都是要查询的字段
from 要查询到表
where
group by
having 分组后带有条件只能使用having
order by 它必须放到最后面
三、JDBC
- JDBC(Java DataBase Connectivity)就是Java数据库连接,是用Java语言来操作数据库。原来操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句。
2.由SUN提供一套访问数据库的规范(就是一组接口),并提供连接数据库的协议标准,然后各个数据库厂商会遵循SUN的规范提供一套访问自己公司的数据库服务器的API出现。SUN提供的规范命名为JDBC,而各个厂商提供的,遵循了JDBC规范的,可以访问自己数据库的API被称之为驱动!
JDBC是接口,而JDBC驱动才是接口的实现,没有驱动无法完成数据库连接!每个数据库厂商都有自己的驱动,用来连接自己公司的数据库。
当然还有第三方公司专门为某一数据库提供驱动,这样的驱动往往不是开源免费的!
3.JDBC中的核心类有:DriverManager、Connection、Statement,和ResultSet!
DriverManger(驱动管理器)的作用有两个:
注册驱动:这可以让JDBC知道要使用的是哪个驱动;
获取Connection:如果可以获取到Connection,那么说明已经与数据库连接上了。
Connection最为重要的一个方法就是用来获取Statement对象;
Statement是用来向数据库发送SQL语句的,这样数据库就会执行发送过来的SQL语句
void executeUpdate(String sql):执行更新操作(insert、update、delete等);
ResultSet executeQuery(String sql):执行查询操作,数据库在执行查询后会把查询结果,查询结果就是ResultSet;
ResultSet对象表示查询结果集,只有在执行查询操作后才会有结果集的产生。结果集是一个二维的表格,有行有列。操作结果集要学习移动ResultSet内部的“行光标”,以及获取当前行上的每一列上的数据:
boolean next():使“行光标”移动到下一行,并返回移动后的行是否存在;
XXX getXXX(int col):获取当前行指定列上的值,参数就是列数,列数从1开始,而不是0。
4.2 注册驱动
看清楚了,注册驱动就只有一句话:Class.forName(“com.mysql.jdbc.Driver”),下面的内容都是对这句代码的解释。今后我们的代码中,与注册驱动相关的代码只有这一句。
DriverManager类的registerDriver()方法的参数是java.sql.Driver,但java.sql.Driver是一个接口,实现类由mysql驱动来提供,mysql驱动中的java.sql.Driver接口的实现类为com.mysql.jdbc.Driver!那么注册驱动的代码如下:
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
上面代码虽然可以注册驱动,但是出现硬编码(代码依赖mysql驱动jar包),如果将来想连接Oracle数据库,那么必须要修改代码的。并且其实这种注册驱动的方式是注册了两次驱动!
JDBC中规定,驱动类在被加载时,需要自己“主动”把自己注册到DriverManger中
com.mysql.jdbc.
Driver类中的static块会创建本类对象,并注册到DriverManager中。这说明只要去加载com.mysql.jdbc.Driver类,那么就会执行这个static块,从而也就会把com.mysql.jdbc.Driver注册到DriverManager中,所以可以把注册驱动类的代码修改为加载驱动类。
Class.forName(“com.mysql.jdbc.Driver”);
4.3 获取连接
DriverManager.getConnection(url,username,password),
mysql的url:
jdbc:mysql://localhost:3306/mydb1
一.jdbc,这是固定的;
二.数据库名称,mysql数据库;
三数据库厂商规定的,我们需要了解每个数据库厂商的要求,mysql的第三部分分别由数据库服务器的IP地址(localhost)、端口号(3306),以及DATABASE名称(mydb1)组成。
还可以在url中提供参数:
jdbc:mysql://localhost:3306/web08?useUnicode=true&characterEncoding=UTF8
useUnicode参数指定这个连接数据库的过程中,使用的字节集是Unicode字节集;
characherEncoding参数指定穿上连接数据库的过程中,使用的字节集编码为UTF-8编码。请注意,mysql中指定UTF-8编码是给出的是UTF8,而不是UTF-8。
4.5 发送SQL查询语句
String sql = “select * from user”;
ResultSet rs = stmt.executeQuery(sql);
请注意,执行查询使用的不是executeUpdate()方法,而是executeQuery()方法。executeQuery()方法返回的是ResultSet,ResultSet封装了查询结果,我们称之为结果集。
4.6 读取结果集中的数据
ResultSet就是一张二维的表格,它内部有一个“行光标”,光标默认的位置在“第一行上方”,可以调用rs对象的next()方法把“行光标”向下移动一行,当第一次调用next()方法时,“行光标”就到了第一行记录的位置,这时就可以使用ResultSet提供的getXXX(int col)方法来获取指定列的数据了:
rs.next();//光标移动到第一行
rs.getInt(1);//获取第一行第一列的数据
当使用rs.getInt(1)方法时,必须可以肯定第1列的数据类型就是int类型,如果你不能肯定,那么最好使用rs.getObject(1)。在ResultSet类中提供了一系列的getXXX()方法,比较常用的方法有:
Object getObject(int col)
String getString(int col)
int getInt(int col)
double getDouble(int col)
4.7 关闭
与IO流一样,使用后的东西都需要关闭!关闭的顺序是先得到的后关闭,后得到的先关闭。
rs.close();
stmt.close();
con.close();
4.8 完成查询操作代码
public static Connection getConnection() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/web08";
return DriverManager.getConnection(url, "root", "root");
}
@Test
public void query() throws Exception {
Connection con = getConnection();
Statement stmt = con.createStatement();
String sql = "select * from user";
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()) {
String username = rs.getString(1);
String password = rs.getString(2);
System.out.println(username + ", " + password);
}
}
4.9 规范化代码
所谓规范化代码就是无论是否出现异常,都要关闭ResultSet、Statement,以及Connection
@Test
public void query() {
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try {
con = getConnection();
stmt = con.createStatement();
String sql = "select * from user";
rs = stmt.executeQuery(sql);
while(rs.next()) {
String username = rs.getString(1);
String password = rs.getString(2);
System.out.println(username + ", " + password);
}
} catch(Exception e) {
throw new RuntimeException(e);
} finally {
try {
if(rs != null) rs.close();
if(stmt != null) stmt.close();
if(con != null) con.close();
} catch(SQLException e) {}
}
可能出现的两种异常
ClassNotFoundException
没有给出mysql的jar包;
把类名称打错了,查看类名是不是com.mysql.jdbc.Driver。
4 Statement
Statement最为重要的方法是:
int executeUpdate(String sql):执行更新操作,即执行insert、update、delete语句,其实这个方法也可以执行create table、alter table,以及drop table等语句,但我们很少会使用JDBC来执行这些语句;
ResultSet executeQuery(String sql):执行查询操作,执行查询操作会返回ResultSet,即结果集。
boolean execute()
Statement还有一个boolean execute()方法,这个方法可以用来执行增、删、改、查所有SQL语句。该方法返回的是boolean类型,表示SQL语句是否执行成功。
如果使用execute()方法执行的是更新语句,那么还要调用int getUpdateCount()来获取insert、update、delete语句所影响的行数。
- PreparedStatement防止注入攻击
过滤用户输入的数据中是否包含非法字符;
分步校验!先使用用户名来查询用户,如果查找到了,再比较密码;
PreparedStatement叫预编译声明
String sql = “select * from tab_student where s_number=?”;
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, “S_1001”);
ResultSet rs = pstmt.executeQuery();
rs.close();
pstmt.clearParameters();
pstmt.setString(1, “S_1002”);
rs = pstmt.executeQuery();
PreparedStatement对象独有的executeQuery()方法是没有参数的