系统:bash on ubuntu(16.04) on Windows
1 配置mysql
1.1 安装mysql
apt install mysql-server # 安装过程会提示设置数据库服务器访问密码,输入2次即可。数据库服务器,用于管理数据库与表,控制用户访问,以及处理 SQL 查询
apt install mysql-client # MySQL 客户端程序,实现用户与服务器的连接与交互功能
apt install libmysqlclient-dev # 编译使用 MySQL 的其他程序的过程中会用到的一些库及头文件
1.2 设置utf-8编码
修改/etc/mysql/mysql.conf.d/mysqld.cnf,即在[mysqld]选项中加入character_set_server=utf8
1.3 启动创建数据库
mysql -u root -p # 进入时输入设定的密码即可
select user(); #查看当前登录用户
show databases; #显示所有的数据库
create database JavaConnectMysql; #创建名为“JavaConnectMysql”的数据库
show databases; #可以看到新创建的数据库“JavaConnectMysql”
1.4 在数据库中创建并查看数据表
help use; #查看use命令的相关功能:
/*Name: 'USE'
Description:
Syntax:
USE db_name
The USE statement tells MySQL to use the named database as the default
(current) database for subsequent statements.
*/
use JavaConnectMysql; # 告诉MySQL使用JavaConnectMysql为默认数据库
create table students(name varchar(20), id int(5), score float); # 在默认数据库中创建students表格
describe students; #详细显示表students的信息,help describe;会显示the DESCRIBE keyword is more often used to obtain information about table structure
show create table students; # 不仅可以查看创建表时的详细语句,而且可以查看存储引擎和字符编码
1.5 删除数据表和数据库
drop table students; #删除数据表students
show tables; #显示所有数据表
drop database JavaConnectMysql; #删除数据库JavaConnectMysql
show databases; #显示所有数据库
2 java连接打印数据库中的数据表
2.1 java配置
参考网站:https://blog.csdn.net/lantuxin/article/details/104152769
按照1.1 安装jdk11的步骤完成jdk安装,并使用javac --version测试jdk是否安装成功。
2.2 安装mysql-connect-java
- 下载mysql-connect-java(专门针对java开发的,当然还有针对C++、python等语言开发的包),
- 安装:dpkg -i mysql-connector-java_*-1ubuntu19.10_all.deb
- 查看安装位置:dpkg -L mysql-connector-java #可以找到/usr/share/java/mysql-connector-java-8.0.19.jar
2.3 数据库访问代码
src/javaConnectMysql.java
package src;//包名
import java.sql.*;
//import libs.mysqlconnectorjava;
public class javaConnectMysql{
static final String JDBC_DRIVER="com.mysql.jdbc.Driver";
static final String DB_URL="jdbc:mysql://localhost:3306/zhouJavaConnectMysql?serverTimezone=GMT";
static final String USER="root";
static final String PASSWORD="********";
public static void main(String[] args)
{
Connection conn = null;
Statement stmt = null;
List<String> columnNames = new ArrayList<>();
try{
Class.forName(JDBC_DRIVER);//注册JDBC驱动
System.out.println("......连接数据库.......");
conn = DriverManager.getConnection(DB_URL,USER,PASSWORD);
System.out.println("......实例化Statement对象.......");
stmt = conn.createStatement();
String sqlcommand = "select * from students";
ResultSet rs = stmt.executeQuery(sqlcommand);
System.out.println("...........");
//结果集元数据
ResultSetMetaData rsmd = rs.getMetaData();
//表列数
int size = rsmd.getColumnCount();
for (int i = 0; i < size; i++) {
columnNames.add(rsmd.getColumnName(i + 1));
}
System.out.println("columnNames:"+columnNames);
while(rs.next())
{
String name = rs.getString("name");
System.out.println("名称:"+name);
}
rs.close();
stmt.close();
conn.close();
}
catch(SQLException se){
// 处理 JDBC 错误
se.printStackTrace();
}catch(Exception e){
// 处理 Class.forName 错误
e.printStackTrace();
}finally{
// 关闭资源
try{
if(stmt!=null) stmt.close();
}catch(SQLException se2){
}// 什么都不做
try{
if(conn!=null) conn.close();
}catch(SQLException se){
se.printStackTrace();
}
}
System.out.println("Goodbye!");
}
}
代码中不加serverTimezone=GMT可能会报错。
2.4 javac编译
项目文件结构find .可以查看
./libs
./libs/mysqlconnectorjava.jar #这是我从/usr/share/java/mysql-connector-java-8.0.19.jar移过来并改名后的文件
./src
./src/javaConnectMysql.class
./src/javaConnectMysql.java
javac -encoding utf-8 -classpath .:./libs/mysqlconnectorjava.jar -d ./ src/javaConnectMysql.java
-classpath表示加入jar包(加入多个jar情况,linux使用:分开,Windows使用;分开),-d表示类文件生成位置
2.5 java执行
java -classpath ./:./libs/mysqlconnectorjava.jar src.javaConnectMysql
如果不使用-classpath加入项目路径和程序中用到的jar包,则会报错。
- 只加入项目路径,即执行java -classpath ./ src.javaConnectMysql,报错:java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
- 项目路径和jar包都不加入,即执行java src.javaConnectMysql,报错:Error: Could not find or load main class src.javaConnectMysql Caused by: java.lang.ClassNotFoundException: src.javaConnectMysql
输出:......连接数据库.......
......实例化Statement对象.......
...........
columnNames:[name, id, scores]
Goodbye!
3.索引
参考网站1:https://www.cnblogs.com/aspwebchh/p/6652855.html
参考网站2:https://www.cnblogs.com/heibaijianpan/p/10706288.html
引言:知道“给数据库某字段建立索引,会使得查询(select * from ${table} where id=${key})速度变快”,这是最初级的。知道为什么会变快,才是硬道理!
原理:
3.1 主键索引(聚集)
为表的某字段(列,如id)添加索引之后,也就是建立了一张索引表,或者可以称为一棵平衡树(类似二叉树),即索引表是一棵平衡树。这个平衡树,将索引(就是添加索引的字段)自动(是否自动还未找到证明材料,暂时不管,设置为auto_increment就不用排序了)排序,并且所有的表数据都是存在叶子节点的。因此,查找命令(select * from ${table} where id=${key})执行时,就可以先只查索引,并且因为索引是平衡树,查找过程可以通过二分查找,快速找到。最后将找到的id对应的行的内容找出来。
具体查找原理,可去参考网站找。
3.2 非聚集
非聚集索引,其实就是建立了一张与主键(聚集索引)关联的表。如一张表有id(主键-聚集索引)、name、age等字段,现在给name字段添加了索引,则会生成一张有name(非聚集性索引)和id(聚集索引)的索引表,查找数据(select age from table where name='张三')的时候,会先去找到“张三”对应的主键id,然后通过id去查找子节点的内容。
4.elasticsearch
基本原理:倒排索引(https://www.imooc.com/article/36255,“根据词语找文档”使用倒排索引,“根据文档找词语”使用正向索引)
系统环境:windows
下载地址(国内华为云):https://mirrors.huaweicloud.com/elasticsearch/
安装:解压下载的elasticsearch-7.8.0-windows-x86_64.zip,直接运行bin/elasticsearch.bat即可完成自动部署。
验证:浏览器访问http://localhost:9200/,出现一些配置信息。
java API:https://www.elastic.co/guide/en/elasticsearch/client/java-api/7.x/index.html
测试添加与读取的RESTAPI(spring项目)
参考网站:https://www.cnblogs.com/cjsblog/p/10232581.html
- pom文件:
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.8.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.0</version>
</dependency>
- spring 工程代码:
package com.example.demo.controller;
import org.apache.http.HttpHost;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author zhou
*/
@RestController
public class HighRestAPI {
Map<String,Object> jsonMap = new HashMap<>();
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));
@PostMapping("/add")
public String connect() throws IOException {
/**
* 通过Map提供文档source
*/
jsonMap.put("user","zhangsan");
jsonMap.put("postTime",new Date());
jsonMap.put("message","this is a test");
IndexRequest indexRequest = new IndexRequest("posts","doc","1");
indexRequest.source(jsonMap);
indexRequest.opType(DocWriteRequest.OpType.CREATE);
try{
IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
}catch (ElasticsearchException e){
}
// client.close();
return "添加成功";
}
@GetMapping("/get")
public Object getRequest() throws IOException {
GetRequest getRequest = new GetRequest("posts","doc","1");
GetResponse getResponse = client.get(getRequest,RequestOptions.DEFAULT);
String index = getResponse.getIndex();
String type = getResponse.getType();
String id = getResponse.getId();
System.out.println(String.format("index:%s,type:%s,id:%s",index,type,id));
Map<String,Object> sourceAsMap = getResponse.getSourceAsMap();
return sourceAsMap;
}
}
- postman访问验证:
添加:localhost:8080/add
读取:localhost:8080/get
5.elasticsearch索引数据备份与迁移
将elasticsearch7.3.2中指定索引时间字段(long)修改为date类型
5.1. 创建一个中间索引
#创建索引,mappings数据可以在索引位置查看
PUT /query_log_backup
{
"mappings":{
"properties": {
"errorMessage": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"matchAcc": {
"type": "boolean"
},
"queryId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"queryStartTime": {
"type": "long"
},
"querySuccess": {
"type": "boolean"
}
}
}
}
5.2. 向中间索引备份源索引的数据
重建索引
POST _reindex
{
"source": {
"index": "query_log"
},
"dest": {
"index": "query_log_backup"
}
}
5.3.查询确认数据是否copy过去
GET /query_log/_search
{
"query": {
"match_all": {}
}
}
GET /query_log_backup/_search
{
"query": {
"match_all": {}
}
}
5.4.删除有问题的索引
删除有问题的索引
DELETE query_log
5.5.重新创建同名的索引(★字段类型修改正确★)
#创建索引
PUT /query_log
{
"mappings":{
"properties": {
"errorMessage": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"matchAcc": {
"type": "boolean"
},
"queryId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"queryStartTime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"querySuccess": {
"type": "boolean"
}
}
}
}
5.6. 从中间索引还原到源索引的数据
重建索引
POST _reindex
{
"source": {
"index": "query_log_backup"
},
"dest": {
"index": "query_log"
}
}
查看验证
###数据查询
GET /query_log_backup/_search
{
"query": {
"match_all": {}
}
}
GET /query_log/_search
{
"query": {
"match_all": {}
}
}
5.7. 删除中间索引
DELETE query_log_backup