关系型数据库
,所谓关系型数据库就是建立在关系模型
上的数据库。
有以下几种
show database;//show出当前数据库的信息
create databasse douyin1 if not exit;//保护性创建
drop databas if exists user;//保护性删除数据库
user douyin;//选择数据库
select databse();//查看当前的数据库
创建(Create)
create table 表名(
字段名1 数据类型1
...
);
查询(Retrieve)
show tables;//查询库中的表
desc comments;//查询表的具体结构
修改(Update)
修改表名:rename to(alter table table_name rename to newname)
添加一列数据:ADD:(alter table table_name rename add newcol datatype)
修改数据类型modify:(alter table table_name modify colname new database)
修改列名和数据类型:(alter table table_name change colname newcolname newdatatype)
删除列:drop:(alter table drop colname)
删除(Delete)
drop tables if exists comments;//语法与库的是一致的
insert into table_name(col_1,col_2,...,col_n) values(value1,value2,value3,...,valuen)
select * from table_name
update table_name set 列名1=值1,.. [where]
delete from table_name where
select 字段列表
from 表名列表
where 条件列表
group by 分组字段
having 分组后条件
order by 排序字段
limit:分页限定
select 字段列表 from table_name;
select * from table; --查询所有的字段
select distinct 字段列表 from 表名;
as:as可以省略
主要是运用where
关键字来对sql的查询结果进行限制
主要是运用order by
关键字来进行查询
select from table_name order by asc(desc) 排序字段名 [排序方式],排序字段名 [排序方式]
--多字段排序
聚合函数:将一列数据作为一个整体,进行纵向计算
聚合函数的分类
函数名 | 功能 |
---|---|
count(列名) | 统计数量(一般选用不为null的列) |
max(列名) | 最大值 |
min(列名) | 最小值 |
sum(列名) | 求和 |
avg(列名) | 平均值 |
聚合函数语法
select 聚合函数名(列名) from 表;
select avg(score) from table_name group by sex having count(*)>2;
注意:分组之后查询的字段为聚合函数和分组字段,查询其他字段没有任何意义
其中having和where应该如何区分呢?
其实就是用limit
对查询量级进行限制
表中列上
的规则,用于限制加入表的数据约束名称 | 描述 | 关键字 |
---|---|---|
非空约束 | 保证列中所有数据不能有null值 | NOT NULL |
唯一约束 | 保证列中所有数据各不相同 | UNIQUE |
主键约束 | 主键是一行数据的唯一标识 ,要求非空而且唯一 | PRIMARY KEY |
检查约束 | 保证列中的值满足某一条件 | CHECK |
默认约束 | 保存数据时未指定值则采用默认值 | DEFAULT |
外键约束 | 外键用来让两个表的数据之间建立连接,保证数据的一致性和完整性 | FOREIGN KEY |
外键:用来让两个表的数据之间建立联系,保证数据的一致性和完整性
添加约束
create table table_name{
列名 数据类型,
...
列名 数据类型
[constraint] [外键名称] foreign key(外键列名) (外键字段名称) references 主表(主表列名);
};
外键约束下的主表与从表
删除外键约束
alter table table_name drop foreign key fk_key_table_table;
增加外键约束
alter table sontable add constraint fk_key foreign key(colname) references maintable(colname);
表结构
、表与表之间的关联关系
的过程中间表
,中间表至少包含两个键
,分别关联两方的主键-- 隐式内连接
select name,sex,brief from table_name,table2_name where id1 = id2;
-- 显式内连接
select name,sex,brief from table_name [inner] join table2_name on table_name.id = table2_name.id;
-- 左外连接
select name,sex,brief from table1 [outer] left join table2 on table1.id = table2.id;
-- 右外连接
select name,sex,brief from table2 [outer] right join table2 on table1.id = table2.id;
子查询的概念:查询中嵌套查询,称嵌套查询为子查询
单行单列的查询结果:作为条件值,使用=!><
等进行判断
select 字段列表 from 表 where 字段名 = (子查询)
select name from table where score = (select score from table where name = "张三" )
多行单列的查询结果:作为条件值,用in
等关键字进行条件判断
select name from table where id in (select id from table2 where tname = "t1" or tname = "t2")
多行多列的查询结果:作为虚拟表
-- 当查询结果是表结构的时候,可以将其作为表结构,接在from后面进行查询
select name from (select * from table where name = "张三") where id > 35 ;
事务
:是一种机制,一个操作序列,包含了一组数据库操作命令
事务把所有的命令作为一个整体一起向系统提交或者撤销操作请求,即这一组数据库命令要么同时成功,要么同时失败
事务是一个不可分割的工作逻辑单元(原子操作)
开启事务:给当前的指令序列打上标记,试执行指令序列,而不对数据库内部数据作持久化的修改
-- 开启事务
start transaction;
begin;
提交事务:指令序列没有出现异常,可正常执行,对数据库内部数据作持久化的修改
-- 提交事务
commit;
回滚事务:当事务操作出现异常时,事务操作回滚到开启事务之前的状态。
-- 回滚事务
rollback;
-- 示例代码
-- 转账操作,开启事务
begin;
-- 查询李四的金额
select money from account where id = 2;
-- 李四的金额 -50
update account set money = money - 50 where id = 2;
-- 张三的金额 +50
update account set money = money + 50 where id = 1;
-- 无异常,提交事务
commit;
-- 回显金额
select * from account;
原子性(Atomicity)
:事务是不可分割的最小操作单位,要么同时成功,要么同时失败
一致性(Consisitency)
:事务完成之时,必须使得所有的数据都保持一致的状态
隔离性(Isolation)
:多个事务之间,操作的可见性
持久性(Durability)
:事务一旦提交或者回滚,它对数据库中的数据的改变就是永久的
驱动
:就是提供的jdbc中,对于不同数据库接口操作的实现类,这些实现类实现了接口import java.sql.*;
public class Main {
public static void main(String[] args) {
try{
// 1.注册当前驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 获取连接
String url = "jdbc:mysql://127.0.0.1:3306/douyin?serverTimezone=GMT&useSSL=false";
String user = "root";
String pwd = "123456";
Connection conn = DriverManager.getConnection(url,user,pwd);
//3.定义sql语句,定义任意一句sql语句
String sql = "update account set money = money +50 where id = 2";
//4.获取sql的对象
Statement stmt = conn.createStatement();
//5.执行语句
int num = stmt.executeUpdate(sql);
System.out.println("受影响的行数"+num);
//6.释放资源
stmt.close();
conn.close();
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (SQLException e){
e.printStackTrace();
}
}
}
普通执行SQL对象:statement createStatement()
预编译SQL的执行对象:PreparedStatement preparedStatement(sql)
,一定程度上可以防止sql的注入
执行存储过程的对象:callableStatement prepareCall(sql)
事务管理
要点:通过try-catch来限制commit和rollback的作用范围
// 1.注册当前驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 获取连接
String url = "jdbc:mysql://127.0.0.1:3306/douyin?serverTimezone=GMT&useSSL=false";
String user = "root";
String pwd = "123456";
Connection conn = DriverManager.getConnection(url,user,pwd);
//3.定义sql语句,定义任意一句sql语句
String sql_1 = "update account set money = money +50 where id = 2";
String sql_2 = "update account set money = money +50 where id = 1";
//4.获取sql的对象
Statement stmt = conn.createStatement();
try{
//5.执行语句
conn.setAutoCommit(false);//开启事务
stmt.execute(sql_1);
stmt.execute(sql_2);
//否则全部执行成功,提交该事务
conn.commit();
}catch (SQLException e){
conn.rollback();
e.printStackTrace();
}
//6.释放资源
stmt.close();
conn.close();
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (SQLException e){
e.printStackTrace();
}
DML语句影响的行数、DDL语句执行后也可能将会返回0
将当前指针从当前位置向后移动一行
,判断当前行是否是有效行
try{
// 1.注册当前驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 获取连接
String url = "jdbc:mysql://127.0.0.1:3306/douyin?serverTimezone=GMT&useSSL=false";
String user = "root";
String pwd = "123456";
Connection conn = DriverManager.getConnection(url,user,pwd);
// 3. 定义sql语句
String sql="select * from account";
//4. 创建执行sql的对象
Statement stmt = conn.createStatement();
//5. 执行sql
ResultSet res = stmt.executeQuery(sql);
while(res.next()){
System.out.println(res.getString(1));
System.out.println(res.getString(2));
System.out.println(res.getDouble(3));
}
//6.释放资源
stmt.close();
conn.close();
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (SQLException e){
e.printStackTrace();
}
// 1.注册当前驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 获取连接
String url = "jdbc:mysql://127.0.0.1:3306/douyin?serverTimezone=GMT&useSSL=false";
String user = "root";
String pwd = "123456";
Connection conn = DriverManager.getConnection(url,user,pwd);
// 3. 定义sql语句,用pre的写法的话,动态的数据应该要用?来替代
String sql="select * from users where id = ? and password = ?";
//4. 创建执行sql的对象
//Statement stmt = conn.createStatement();
PreparedStatement stmt = conn.prepareStatement(sql);
//5. 执行sql
stmt.setString(1,"1");
stmt.setString(2,"2");
ResultSet res = stmt.executeQuery();
while(res.next()){
System.out.println(res.getString(1));
System.out.println(res.getString(2));
System.out.println(res.getDouble(3));
}
//6.释放资源
stmt.close();
conn.close();
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (SQLException e){
e.printStackTrace();
}
preparedStatement可以有效地防止sql注入
useServerPrepStmts = true
数据库连接池
是一个容器,负责分配,管理数据库连接(Connection)
它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个
释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库而引起的数据库连接遗落
好处
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/douyin?serverTimezone=GMT&useSSL=false&allowPublicKeyRetrieval=true
username=root
password=123456
# 初始化连接池数量
initialSize = 5
# 最大连接数
maxActive = 10
# 最大等待时间
maxWait = 3000
@Test
public void test(){
try {
// 1.加载配置文件
Properties prop = new Properties();
prop.load(new FileInputStream("src/connection.properties"));
// 2.获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
// 3.获取数据库连接
Connection connection = dataSource.getConnection();
System.out.println(connection.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
package testdemo;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.junit.Test;
import javax.sql.DataSource;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import java.util.Vector;
public class test {
/*要点:1.连接池的使用*/
/*sql的编写(pre)*/
@Test
public void testSelectAll(){//测试查询
try{
//1.获取connection,利用德鲁伊连接池
Properties properties = new Properties();
properties.load(new FileReader("src/connection.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
Connection connection = dataSource.getConnection();
//2.编写sql
String sql="select * from tb_brand";
//3.执行sql
PreparedStatement stmts = connection.prepareStatement(sql);
ResultSet resultSet = stmts.executeQuery();
//4.定义数据结构,将其存储起来
Vector<Brand> brands = new Vector<>();
while(resultSet.next()){
Brand brand = new Brand();
brand.setId(resultSet.getInt(1));
brand.setBrand_name(resultSet.getString(2));
brand.setCompany_name(resultSet.getString(3));
brand.setOrdered(resultSet.getInt(4));
brand.setDescription(resultSet.getString(5));
brand.setStatus(resultSet.getBoolean(6));
brands.add(brand);
}
//5.输出结果
for (Brand brand : brands) {
System.out.println(brand.toString());
}
stmts.close();
connection.close();
} catch (Exception e){
e.printStackTrace();
}
}//PASS
@Test
public void testDeleteData(){
try{
//1.获取connection,利用德鲁伊连接池
Properties properties = new Properties();
properties.load(new FileReader("src/connection.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
Connection connection = dataSource.getConnection();
//2.编写sql
String sql="delete from tb_brand where id = ?";
//3.执行sql
PreparedStatement stmts = connection.prepareStatement(sql);
int deleteNum = 3;//删除id为2的,并且回显
stmts.setInt(1,deleteNum);
int count = stmts.executeUpdate();
if(count>0){
System.out.println("删除成功");
}else{
System.out.println("删除失败");
}
stmts.close();
connection.close();
testSelectAll();
} catch (Exception e){
e.printStackTrace();
}
}
@Test
public void testUpdateData(){
try{
//1.获取connection,利用德鲁伊连接池
Properties properties = new Properties();
properties.load(new FileReader("src/connection.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
Connection connection = dataSource.getConnection();
//2.编写sql
String sql="update tb_brand set brand_name = ? where id = 1";
//3.执行sql
PreparedStatement stmts = connection.prepareStatement(sql);
String newBrandName = "newName";
stmts.setString(1,newBrandName);
int count = stmts.executeUpdate();
if(count>0){
System.out.println("更新成功");
}else{
System.out.println("更新失败");
}
stmts.close();
connection.close();
testSelectAll();
} catch (Exception e){
e.printStackTrace();
}
}
@Test
public void testAddData(){
try{
//1.获取connection,利用德鲁伊连接池
Properties properties = new Properties();
properties.load(new FileReader("src/connection.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
Connection connection = dataSource.getConnection();
//2.编写sql
String sql="insert into tb_brand values (?,?,?,?,?,?)";
//3.执行sql
PreparedStatement stmts = connection.prepareStatement(sql);
stmts.setInt(1,4);
stmts.setString(2,"5");
stmts.setString(3,"6");
stmts.setInt(4,2);
stmts.setString(5,"8");
stmts.setBoolean(6,true);
int count = stmts.executeUpdate();
if(count>0){
System.out.println("增加成功");
}else{
System.out.println("增加失败");
}
stmts.close();
connection.close();
testSelectAll();
} catch (Exception e){
e.printStackTrace();
}
}
@Test
public void testPath(){//不需要模块名
System.out.println(System.getProperty("user.dir"));
}
}
sql代码
use douyin;
-- 删除库中已经存在的重名表
drop table if exists tb_brand;
-- 创建表
create table tb_brand(
-- id 主键
id int primary key auto_increment,
-- 品牌名称
brand_name varchar(10) not null ,
-- 企业名称
company_name varchar(10) not null,
-- 排序字段
ordered int,
-- 描述信息
description varchar(100),
-- 状态: false:禁用 true:可用
status bool
);
-- 添加一条初始数据
insert into tb_brand (brand_name, company_name, ordered, description, status)
values ("1","1",1,"1",true),
("2","2",2,"2",true),
("3","3",3,"3",true);
-- 校验数据
select * from tb_brand;
提供了一套标准化的项目结构
提供了一套标准化的构建流程
提供了一套管理依赖工具
本质上管理和构建JAVA项目的工具
Apache Maven 是一个项目管理和构建工具,它基于项目对象模型(Project Obiject Model)的概念,通过一小段描述性信息来管理项目的构建,报告和文档
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EYCNWsCB-1656738342573)(H:\JAVA\JAVA-webv\note\image\maven.png)]
mvn compile
mvn clean
mvn package
mvn test
mvn install
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DlXOJbwa-1656738342574)(H:\JAVA\JAVA-webv\note\image\maven生命周期.png)]
资源的唯一标识符
groupid
:定义当前Maven项目属于的组织名称(比如com.alibaba)artifactId
:定义当前Maven项目名称(通常是模块名称)version
:定义当前项目版本号scope
),可以设置对应jar包的作用范围,编译环境,测试环境,运行环境依赖范围 | 编译classpath | 测试classpath | 运行classpath | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | logback |
test | - | Y | - | Junit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | jdbc驱动 |
system | Y | Y | - | 存储在本地的jar包 |
import | 引入Dependenc | yManagement |
<dependencies>
<!-- 导入mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- 导入mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<!-- 导入junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- 导入slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.2</version>
</dependency>
<!-- 导入logback-core-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.7</version>
</dependency>
<!-- 导入logback-classic-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
</dependencies>
数据库连接信息
<!-- 数据库连接设置 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/douyin?serverTimezone=GMT&useSSL=false&allowPublicKeyRetrieval=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
namespace:命名空间
resultType:将来将要返回的数据类型(已经封装)
select id:表示该sql是用来干啥的,标识符
-->
<mapper namespace="test">
<select id="selectAll" resultType="pojo.Brand">
select * from tb_brand;
</select>
</mapper>
<mappers>
<!--加载sql的映射文件,注意路径,这里是平级的-->
<mapper resource="UserMapper.xml"/>
</mappers>
@Test
public void mybatisTest(){
String resource = "mybatis-config.xml";//此处修改为刚才写的mybatis配置文件路径
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);//解析文本文件,并以字节输入流的形式传入
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//以刚才得到的字节流信息为基础,建立SQLSessionFactory对象
//2.获取sql执行对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//3.执行sql
List<Brand> users = sqlSession.selectList("test.selectAll");//填入sql映射的唯一标识
//4.释放资源
sqlSession.close();
//5.校验数据结构
System.out.println(users);
}
<mapper namespace="com.lumxi.mapper.UserMapper">
<select id="selectAll" resultType="com.lumxi.pojo.Brand">
select * from tb_brand;
</select>
</mapper>
修改namespace即可
public interface UserMapper {
List<Brand> selectAll();
}
@Test
public void mapperTest(){
String resource = "mybatis-config.xml";//此处修改为刚才写的mybatis配置文件路径
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);//解析文本文件,并以字节输入流的形式传入
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//以刚才得到的字节流信息为基础,建立SQLSessionFactory对象
//2.获取sql执行对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//3.执行sql
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<Brand> brands = userMapper.selectAll();
//4.释放资源
sqlSession.close();
//5.校验数据结构
System.out.println(brands);
}
<mappers>
<!--加载sql的映射文件,注意路径,这里是平级的-->
<!--<mapper resource="com/lumxi/mapper/UserMapper.xml"/>-->
<!-- 当遵守了以上开发规范后,可以使用下列的方式,直接扫描包内所有资源文件-->
<package name="com.lumxi.mapper"/>
</mappers>
environments
<!--
environments:配置数据库的连接环境信息,可以配置多个环境信息,通过切换default来切换environment,这里指代的是适用在哪个场景下的配置,假如说我想要一套在测试环境下的环境,那么这里就要改成test
transactionManager:管理事务的方式(JDBC),但我们一般不用mybatis来管理数据库的事务
-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 数据库连接设置 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/douyin?serverTimezone=GMT&useSSL=false&allowPublicKeyRetrieval=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<environments default="test">
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 数据库连接设置 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/douyin?serverTimezone=GMT&useSSL=false&allowPublicKeyRetrieval=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>