東川印記

一本東川,笑看爭龍斗虎;寰茫兦者,度橫佰昧人生。

通过idea 2020 gradle 搭建 Spring Boot 基础学习demo 04 简单配置log and mysql jpa

2020年10月30日星期五



出差兰州归来,继续水文

简单配置日志

涉及结构 依然简单!

SENRSL:spring_boot2 senrsl$ tree
.
├── log
│   └── spring.log  产出物
└── src
    └── main
       ├── java
       │   └── dc
       │       └── test
       │           └── spring
       │               └── boot2
       │                   └── zheng
       │                      ├── TestZhengApplication.java
       │                      └── controller
       │                          └── TestZheng01Controller.java
       │                  
       └── resources
           └── application.properties 配置log
   
75 directories, 55 files
SENRSL:spring_boot2 senrsl$

先去配置一个足够简单的log配置

SENRSL:spring_boot2 senrsl$ cat src/main/resources/application.properties
sb2.title=Sb2
dc.test.wu.title=Wu's Title
dc.test.wu.desc=Wu's Desc
# 日志配置
logging.file.path=log/
logging.level.dc.test.spring.boot2.zheng=INFO

SENRSL:spring_boot2 senrsl$

然后写一个更加简单的示例

SENRSL:spring_boot2 senrsl$ cat src/main/java/dc/test/spring/boot2/zheng/controller/TestZheng01Controller.java
package dc.test.spring.boot2.zheng.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 日志输出测试
 * 输出于/Users/senrsl/j2ee/Project/TestSpringBoot/spring_boot2/log/spring.log
 *
 * @author senrsl
 * @ClassName: TestZheng01Controller
 * @Package: dc.test.spring.boot2.zheng.controller
 * @CreateTime: 2020/10/30 11:24 上午
 */
@RestController
public class TestZheng01Controller {

    public static final Logger log = LoggerFactory.getLogger(TestZheng01Controller.class);

    @RequestMapping("zheng")
    public String zheng() {
        log.trace("这是 trace 的测试。。。。");
        log.debug("这是 debug 的测试。。。。");
        log.info("这是 info 的测试。。。。");
        log.warn("这是 warn 的测试。。。。");
        log.error("这是 error 的测试。。。。");
        return getClass().getSimpleName();
    }

}
SENRSL:spring_boot2 senrsl$

这样,就有了一个对于log的基本认识。。。。

-----------------------分割线-------------------------------------

简单配置 mysql 基本操作

先安个 mysql.....

1,下载安装mysql

dev.mysql.com/downloads

选择社区服务器 MySQL Community Server - > DMG包 macOS 10.15 (x86, 64-bit), DMG Archive

填上用途啥的,终于开始下载了。。。。

cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.22-macos10.15-x86_64.dmg

MD5: 6fa385100e474ddc2a6a4e848b3f9284
Size: 401.5M

DMG包 pkg,傻瓜式安装,Config需要手动填写 root密码。。。。

然后,系统偏好设置,底部,会出现 Mysql的配置面板,关闭自动启动。。。。

然后,可以直接执行mysql命令了

SENRSL:spring_boot2 senrsl$ /usr/local/mysql/bin/mysql -u root -p
Enter password: dA
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.22 MySQL Community Server - GPL

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> help

For information about MySQL products and services, visit:
   http://www.mysql.com/
For developer information, including the MySQL Reference Manual, visit:
   http://dev.mysql.com/
To buy MySQL Enterprise support, training, or other products, visit:
   https://shop.mysql.com/

List of all MySQL commands:
Note that all text commands must be first on line and end with ';'
?         (\?) Synonym for `help'.
clear     (\c) Clear the current input statement.
connect   (\r) Reconnect to the server. Optional arguments are db and host.
delimiter (\d) Set statement delimiter.
edit      (\e) Edit command with $EDITOR.
ego       (\G) Send command to mysql server, display result vertically.
exit      (\q) Exit mysql. Same as quit.
go        (\g) Send command to mysql server.
help      (\h) Display this help.
nopager   (\n) Disable pager, print to stdout.
notee     (\t) Don't write into outfile.
pager     (\P) Set PAGER [to_pager]. Print the query results via PAGER.
print     (\p) Print current command.
prompt    (\R) Change your mysql prompt.
quit      (\q) Quit mysql.
rehash    (\#) Rebuild completion hash.
source    (\.) Execute an SQL script file. Takes a file name as an argument.
status    (\s) Get status information from the server.
system    (\!) Execute a system shell command.
tee       (\T) Set outfile [to_outfile]. Append everything into given outfile.
use       (\u) Use another database. Takes database name as argument.
charset   (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets.
warnings  (\W) Show warnings after every statement.
nowarning (\w) Don't show warnings after every statement.
resetconnection(\x) Clean session context.

For server side help, type 'help contents'

mysql> exit
Bye
SENRSL:spring_boot2 senrsl$

2, mysql开启3306端口

安装成功貌似没有自动开启3306端口,也就没法供其他程序调用。。。。

配置连接,允许 非localhost

mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select host from user where user = 'root';
+-----------+
| host      |
+-----------+
| localhost |
+-----------+
1 row in set (0.00 sec)

mysql> update user set host = '%' where user = 'root';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select host from user where user = 'root';
+------+
| host |
+------+
| %    |
+------+
1 row in set (0.00 sec)

mysql> select host,user from user;
+-----------+------------------+
| host      | user             |
+-----------+------------------+
| %         | root             |
| localhost | mysql.infoschema |
| localhost | mysql.session    |
| localhost | mysql.sys        |
+-----------+------------------+
4 rows in set (0.00 sec)

mysql>

还没开始改,发现3306又通了。。。。

SENRSL:~ senrsl$ /usr/local/mysql/bin/mysql -h 127.0.0.1 -P 3306 -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.22 MySQL Community Server - GPL

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> exit
Bye
SENRSL:~ senrsl$ telnet 127.0.0.1 3306
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
J
8.0.22    CH67JRM?+x:5 \caching_sha2_password
Connection closed by foreign host.
SENRSL:~ senrsl$ 


2,mysql建测试库

1)建库

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql> create database test;
Query OK, 1 row affected (0.00 sec)
mysql> drop database test;
Query OK, 0 rows affected (0.00 sec)

mysql> create database sb_test;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sb_test            |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql>

2)建表

mysql> create table wang_usr (
    -> id INT NOT NULL AUTO_INCREMENT,
    -> name VARCHAR(100) NOT NULL,
    -> create_time DATE,
    -> PRIMARY KEY (id)
    -> )ENGINE=InnoDB  DEFAULT CHARSET=utf8;
Query OK, 0 rows affected, 1 warning (0.01 sec)


3) 增删改查

mysql> insert into wang_usr(name,create_time)
    -> values
    -> ("wang1","2020-10-30");
Query OK, 1 row affected (0.00 sec)

mysql> insert into wang_usr values(2,"wang2","2020-10-30");
Query OK, 1 row affected (0.00 sec)

mysql> insert into wang_usr(name,create_time) values ("wang5","2020-10-30");
Query OK, 1 row affected (0.00 sec)

mysql> select * from wang_usr;
+----+-------+-------------+
| id | name  | create_time |
+----+-------+-------------+
|  1 | wang1 | 2020-10-30  |
|  2 | wang2 | 2020-10-30  |
|  4 | wang2 | 2020-10-30  |
|  5 | wang5 | 2020-10-30  |
+----+-------+-------------+
4 rows in set (0.00 sec)

mysql> delete from wang_user where id=4;
ERROR 1146 (42S02): Table 'sb_test.wang_user' doesn't exist
mysql> delete from wang_usr where id=4;
Query OK, 1 row affected (0.01 sec)

mysql> select * from wang_usr;
+----+-------+-------------+
| id | name  | create_time |
+----+-------+-------------+
|  1 | wang1 | 2020-10-30  |
|  2 | wang2 | 2020-10-30  |
|  5 | wang5 | 2020-10-30  |
+----+-------+-------------+
3 rows in set (0.00 sec)

mysql> update wang_usr set name="wangwang" where id=5;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from wang_usr;
+----+----------+-------------+
| id | name     | create_time |
+----+----------+-------------+
|  1 | wang1    | 2020-10-30  |
|  2 | wang2    | 2020-10-30  |
|  5 | wangwang | 2020-10-30  |
+----+----------+-------------+
3 rows in set (0.00 sec)

mysql>

看起来这个自增 id,如果传的话就以传的为准,不传就根据上面那个自增。。。。


3,增加 JPA和 mysql jdbc依赖

SENRSL:spring_boot2 senrsl$ cat build.gradle
plugins {
    id 'org.springframework.boot' version '2.3.4.RELEASE'
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'
    id 'java'
}

group = 'dc.test'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'junit:junit:4.12'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }

    implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.3.4.RELEASE'
    implementation 'mysql:mysql-connector-java:8.0.22'
}

test {
    useJUnitPlatform()
}
SENRSL:spring_boot2 senrsl$


其中 spring-boot-starter-data-jpa 这个是 hibernate 的 jpa,mysql-connector-java这个与mysql通信。。。。

4,配置jdbc连接

SENRSL:spring_boot2 senrsl$ cat src/main/resources/application.properties
# 数据库JPA
spring.datasource.url=jdbc:mysql://localhost:3306/sb_test
spring.datasource.username=root
spring.datasource.password=dA
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=trueSENRSL:spring_boot2

senrsl$

启动有个警告

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

替换 com.mysql.jdbc.Driver 为 com.mysql.cj.jdbc.Driver

5,建立 domain 和 DAO 与 mysql映射

package dc.test.spring.boot2.wang.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

/**
 * @author senrsl
 * @ClassName: WangUser
 * @Package: dc.test.spring.boot2.wang.domain
 * @CreateTime: 2020/10/30 3:45 下午
 */
@Entity
public class WangUser {

    @Id
    @GeneratedValue
    private Long id;
    @Column(nullable = false, unique = true)
    private String name;
    @Column(nullable = false)
    private String passwd;
    @Column(nullable = false, unique = true)
    private String email;
    private String createTime;

    public WangUser() {
    }

    public WangUser(String name, String passwd, String email, String createTime) {
        this.name = name;
        this.passwd = passwd;
        this.email = email;
        this.createTime = createTime;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPasswd() {
        return passwd;
    }

    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "WangUser{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", passwd='" + passwd + '\'' +
                ", email='" + email + '\'' +
                ", createTime='" + createTime + '\'' +
                '}';
    }
}

DAO相比十年前真的太简单了呀。。。。

基本的增删改查都自己生成了,只需要写定制接口就行了。。。。

package dc.test.spring.boot2.wang.repo;

import org.springframework.data.jpa.repository.JpaRepository;

import dc.test.spring.boot2.wang.domain.WangUser;

/**
 * @author senrsl
 * @ClassName: IWangUserRepository
 * @Package: dc.test.spring.boot2.wang.dao
 * @CreateTime: 2020/10/30 3:49 下午
 */
public interface IWangUserRepository extends JpaRepository<WangUser, Long> {

    WangUser findByName(String name);

    WangUser findByNameOrEmail(String name, String email);
}

6,建立Controller 简单实现增删改查

package dc.test.spring.boot2.wang.controller;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import dc.test.spring.boot2.wang.domain.WangUser;
import dc.test.spring.boot2.wang.repo.IWangUserRepository;

/**
 * @author senrsl
 * @ClassName: Wang01Controller
 * @Package: dc.test.spring.boot2.wang.controller
 * @CreateTime: 2020/10/30 4:08 下午
 */
@RequestMapping("wang/user/")
@RestController
public class Wang01Controller {

    @Autowired
    private IWangUserRepository repository;

    /**
     * http://localhost:8080/wang/user/add
     *
     * @return
     */
    @RequestMapping("add")
    public String wangUser() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss");
        Date date = new Date();

        WangUser usr = repository.save(new WangUser(generateName(), "a", generateEmail(), sdf.format(date)));

        System.out.println(usr.toString());

        return usr.toString();
    }

    int i = 100;

    private String generateName() {
        return "wang" + i;
    }

    private String generateEmail() {
        return "wang" + i++ + "@a.com";
    }

    /**
     * http://localhost:8080/wang/user/list
     *
     * @return
     */
    @RequestMapping("list")
    public String list() {
        List<WangUser> list = repository.findAll();
        StringBuffer sb = new StringBuffer();
        for (WangUser usr : list) {
            sb.append(usr.toString()).append("\n<br/>");
        }
        return sb.toString();
    }

    /**
     * http://localhost:8080/wang/user/delete/11
     *
     * @param id
     */
    @RequestMapping("delete/{id}")
    public void delete(@PathVariable long id) {
        repository.deleteById(id);
    }

    /**
     * http://localhost:8080/wang/user/update?id=18&name=aaaaaa
     * http://localhost:8080/wang/user/update?name=aaaaaa&id=180
     *
     * @param id
     * @param name
     * @return
     */
    @RequestMapping("update")
    public String update(long id, String name) {
        Optional<WangUser> usr = repository.findById(id);
        if (!usr.isPresent()) return usr.toString();
        usr.get().setName(name);
        WangUser usrNew = repository.save(usr.get());
        return usrNew.toString();
    }

}

跟之前相比太简单了。。。。

泛型的 强大!!!

7,还可以使用Junit来测试

package dc.test.spring.boot2.wang;

import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import dc.test.spring.boot2.wang.domain.WangUser;
import dc.test.spring.boot2.wang.repo.IWangUserRepository;

/**
 * @author senrsl
 * @ClassName: WangUserRepositoryTests
 * @Package: dc.test.spring.boot2.wang
 * @CreateTime: 2020/10/30 3:56 下午
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class WangUserRepositoryTests {

    @Autowired
    private IWangUserRepository repository;

    @Test
    public void testCount() {
        long totalSize = repository.count();

        Assert.assertEquals(17, totalSize);
    }

    @Test
    public void testSelect() {
        WangUser usr = repository.findByNameOrEmail("wang100", "wang100@a.com");

        Assert.assertEquals("a", usr.getPasswd());
    }

}

一直报这个错误

No tests found for given includes: [dc.test.spring.boot2.wang.WangUserRepositoryTests.test](filter.includeTestsMatching)

替换Test的引入 解决。。。。

8,总体结构

涉及到的文件结构

SENRSL:spring_boot2 senrsl$ tree
.
├── build.gradle
└── src
    └── main
       └─ java
          └── dc
              └── test
                   └── spring
                            └── boot2
                                 └── wang
                                        ├── TestWangApplication.java
                                        ├── controller
                                        │   └── Wang01Controller.java
                                        ├── domain
                                        │   └── WangUser.java
                                        └── repo
                                              └── IWangUserRepository.java
    └── test
        └── java
            └── dc
                └── test
                    └── spring
                        └── boot2                         
                            └── wang
                                └── WangUserRepositoryTests.java

103 directories, 77 files
SENRSL:spring_boot2 senrsl$


pkg wang 提交记录:github.com/senRsl/TestSpringBoot/tree/9646c6d3e969509156406f6886c372850c474d74

又是一周结束。。。。

2020年10月30日17:20:30


--
senRsl
2020年10月30日11:57:30

没有评论 :

发表评论