java对接腾讯云短信发送

java对接腾讯云短信发送

  1. 创建签名
    1621329289395

  2. 创建正文模板
    1621329334136

  3. 找相关信息 SDK AppIDApp Key

    1621329513034

  4. 找到API密钥 记录SecretIdSecretKey

    1621329692019

  5. 创项目导依赖

    1
    2
    3
    4
    5
    6
    <!--腾讯短信依赖-->
    <dependency>
    <groupId>com.tencentcloudapi</groupId>
    <artifactId>tencentcloud-sdk-java</artifactId>
    <version>4.0.11</version>
    </dependency>
  6. 创建java类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    package com.suyi.springcloud.test;

    import com.tencentcloudapi.common.Credential;
    import com.tencentcloudapi.common.exception.TencentCloudSDKException;
    import com.tencentcloudapi.common.profile.ClientProfile;
    import com.tencentcloudapi.sms.v20190711.SmsClient;
    import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
    import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;

    public class SendCode {
    public static void main(String[] args) {
    // secretId,secretKey
    Credential cred = new Credential("secretId",
    "secretKey");

    // 实例化要请求产品(以cvm为例)的client对象
    ClientProfile clientProfile = new ClientProfile();
    clientProfile.setSignMethod(ClientProfile.SIGN_TC3_256);
    SmsClient smsClient = new SmsClient(cred, "ap-chongqing");//第二个ap-chongqing 填产品所在的区
    SendSmsRequest sendSmsRequest = new SendSmsRequest();
    sendSmsRequest.setSmsSdkAppid("SDK AppID");//SDK AppID
    String[] phones={"+86手机号"}; //发送短信的目标手机号,可填多个。
    sendSmsRequest.setPhoneNumberSet(phones);
    sendSmsRequest.setTemplateID("模版id"); //模版id
    String [] templateParam={"452256"};//模版参数,从前往后对应的是模版的{1}、{2}等
    sendSmsRequest.setTemplateParamSet(templateParam);
    sendSmsRequest.setSign("飞驰的苏弋"); //签名内容,不是填签名id节
    try {
    SendSmsResponse sendSmsResponse= smsClient.SendSms(sendSmsRequest); //发送短信
    System.out.println(sendSmsResponse.toString());
    } catch (TencentCloudSDKException e) {
    e.printStackTrace();
    }
    }
    }

    515646846

方法二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.suyi.springcloud.test;

import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20190711.SmsClient;
import com.tencentcloudapi.sms.v20190711.models.*;

import java.util.Random;

public class SendCode2 {
public static void main(String[] args) {
try {
/* 必要步骤:
* 实例化一个认证对象,入参需要传入腾讯云账户密钥对 secretId 和 secretKey
* CAM 密钥查询:https://console.cloud.tencent.com/cam/capi
*/
Credential cred = new Credential("AKIDKPHsKXECcnKApGaUMxNO9dMs88rZZcsG", "NWjHbkeP3SkqARdbJn1zkZEdmUyB7ost");
SmsClient client = new SmsClient(cred, "");
/* 实例化一个请求对象,根据调用的接口和实际情况,可以进一步设置请求参数*/
SendSmsRequest req = new SendSmsRequest();
/* SDKAppID*/
String appid = "1400510188";
req.setSmsSdkAppid(appid);
/* 短信签名内容*/
String sign = "飞驰的苏弋";
req.setSign(sign);
/*模板ID*/
String templateID = "931520";
req.setTemplateID(templateID);

/* 86为国家码,最多不要超过200个手机号*/
String[] phoneNumbers = {"+8617691324608","+8617392119275"};
req.setPhoneNumberSet(phoneNumbers);

/* 模板参数: 若无模板参数,则设置为空*/
Random random = new Random();
int code = random.nextInt(9000)+1000;//1000-9999
String[] params = {String.valueOf(code)};
req.setTemplateParamSet(params);

/* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
* 返回的 res 是一个 SendSmsResponse 类的实例,与请求对象对应 */
SendSmsResponse res = client.SendSms(req);
System.out.println(res);
// 输出 JSON 格式的字符串回包
System.out.println("字符串回包"+SendSmsResponse.toJsonString(res));

} catch (TencentCloudSDKException e) {
e.printStackTrace();
}
}
}

mybatis一对多和多对一处理

多对一的处理

多对一的理解:

  • 多个学生对应一个老师
  • 如果对于学生这边,就是一个多对一的现象,即从学生这边关联一个老师!

数据库设计

多个学生对一个老师

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老师');

CREATE TABLE `student` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8


INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');

搭建测试环境

1、IDEA安装Lombok插件

2、引入Maven依赖

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>

3、在代码中增加注解

1
2
3
4
5
@Data //GET,SET,ToString,有参,无参构造
public class Teacher {
private int id;
private String name;
}
1
2
3
4
5
6
7
@Data
public class Student {
private int id;
private String name;
//多个学生可以是同一个老师,即多对一
private Teacher teacher;
}

4、编写实体类对应的Mapper接口 【两个】

  • 无论有没有需求,都应该写上,以备后来之需!
1
2
public interface StudentMapper {
}
1
2
public interface TeacherMapper {
}

5、编写Mapper接口对应的 mapper.xml配置文件 【两个】

  • 无论有没有需求,都应该写上,以备后来之需!
1
2
3
4
5
6
7
<?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">
<mapper namespace="com.kuang.mapper.StudentMapper">

</mapper>
1
2
3
4
5
6
7
<?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">
<mapper namespace="com.kuang.mapper.TeacherMapper">

</mapper>

按查询嵌套处理

1、给StudentMapper接口增加方法

1
2
//获取所有学生及对应老师的信息
public List<Student> getStudents();

2、编写对应的Mapper文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?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">
<mapper namespace="com.kuang.mapper.StudentMapper">

<!--
需求:获取所有学生及对应老师的信息
思路:
1. 获取所有学生的信息
2. 根据获取的学生信息的老师ID->获取该老师的信息
3. 思考问题,这样学生的结果集中应该包含老师,该如何处理呢,数据库中我们一般使用关联查询?
1. 做一个结果集映射:StudentTeacher
2. StudentTeacher结果集的类型为 Student
3. 学生中老师的属性为teacher,对应数据库中为tid。
多个 [1,...)学生关联一个老师=> 一对一,一对多
4. 查看官网找到:association – 一个复杂类型的关联;使用它来处理关联查询
-->
<select id="getStudents" resultMap="StudentTeacher">
select * from student
</select>
<resultMap id="StudentTeacher" type="Student">
<!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<!--
这里传递过来的id,只有一个属性的时候,下面可以写任何值
association中column多参数配置:
column="{key=value,key=value}"
其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
-->
<select id="getTeacher" resultType="teacher">
select * from teacher where id = #{id}
</select>

</mapper>

3、编写完毕去Mybatis配置文件中,注册Mapper!

4、注意点说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
<resultMap id="StudentTeacher" type="Student">
<!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名-->
<association property="teacher" column="{id=tid,name=tid}" javaType="Teacher" select="getTeacher"/>
</resultMap>
<!--
这里传递过来的id,只有一个属性的时候,下面可以写任何值
association中column多参数配置:
column="{key=value,key=value}"
其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
-->
<select id="getTeacher" resultType="teacher">
select * from teacher where id = #{id} and name = #{name}
</select>

5、测试

1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
public void testGetStudents(){
SqlSession session = MybatisUtils.getSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);

List<Student> students = mapper.getStudents();

for (Student student : students){
System.out.println(
"学生名:"+ student.getName()
+"\t老师:"+student.getTeacher().getName());
}
}

按结果嵌套处理

除了上面这种方式,还有其他思路吗?

我们还可以按照结果进行嵌套处理;

1、接口方法编写

1
public List<Student> getStudents2();

2、编写对应的mapper文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!--
按查询结果嵌套处理
思路:
1. 直接查询出结果,进行结果集的映射
-->
<select id="getStudents2" resultMap="StudentTeacher2" >
select s.id sid, s.name sname , t.name tname
from student s,teacher t
where s.tid = t.id
</select>

<resultMap id="StudentTeacher2" type="Student">
<id property="id" column="sid"/>
<result property="name" column="sname"/>
<!--关联对象property 关联对象在Student实体类中的属性-->
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>

3、去mybatis-config文件中注入【此处应该处理过了】

4、测试

1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
public void testGetStudents2(){
SqlSession session = MybatisUtils.getSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);

List<Student> students = mapper.getStudents2();

for (Student student : students){
System.out.println(
"学生名:"+ student.getName()
+"\t老师:"+student.getTeacher().getName());
}
}

小结

按照查询进行嵌套处理就像SQL中的子查询

按照结果进行嵌套处理就像SQL中的联表查询

一对多处理

一对多的处理

一对多的理解:

  • 一个老师拥有多个学生
  • 如果对于老师这边,就是一个一对多的现象,即从一个老师下面拥有一群学生(集合)!

实体类编写

1
2
3
4
5
6
@Data
public class Student {
private int id;
private String name;
private int tid;
}
1
2
3
4
5
6
7
@Data
public class Teacher {
private int id;
private String name;
//一个老师多个学生
private List<Student> students;
}

….. 和之前一样,搭建测试的环境!

按结果嵌套处理

1、TeacherMapper接口编写方法

1
2
//获取指定老师,及老师下的所有学生
public Teacher getTeacher(int id);

2、编写接口对应的Mapper配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<mapper namespace="com.kuang.mapper.TeacherMapper">

<!--
思路:
1. 从学生表和老师表中查出学生id,学生姓名,老师姓名
2. 对查询出来的操作做结果集映射
1. 集合的话,使用collection!
JavaType和ofType都是用来指定对象类型的
JavaType是用来指定pojo中属性的类型
ofType指定的是映射到list集合属性中pojo的类型。
-->
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname , t.name tname, t.id tid
from student s,teacher t
where s.tid = t.id and t.id=#{id}
</select>

<resultMap id="TeacherStudent" type="Teacher">
<result property="name" column="tname"/>
<collection property="students" ofType="Student">
<result property="id" column="sid" />
<result property="name" column="sname" />
<result property="tid" column="tid" />
</collection>
</resultMap>
</mapper>

3、将Mapper文件注册到MyBatis-config文件中

1
2
3
<mappers>
<mapper resource="mapper/TeacherMapper.xml"/>
</mappers>

4、测试

1
2
3
4
5
6
7
8
@Test
public void testGetTeacher(){
SqlSession session = MybatisUtils.getSession();
TeacherMapper mapper = session.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher(1);
System.out.println(teacher.getName());
System.out.println(teacher.getStudents());
}

按查询嵌套处理

1、TeacherMapper接口编写方法

1
public Teacher getTeacher2(int id);

2、编写接口对应的Mapper配置文件

1
2
3
4
5
6
7
8
9
10
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from teacher where id = #{id}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<!--column是一对多的外键 , 写的是一的主键的列名-->
<collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudentByTeacherId"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select * from student where tid = #{id}
</select>

3、将Mapper文件注册到MyBatis-config文件中

4、测试

1
2
3
4
5
6
7
8
@Test
public void testGetTeacher2(){
SqlSession session = MybatisUtils.getSession();
TeacherMapper mapper = session.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher2(1);
System.out.println(teacher.getName());
System.out.println(teacher.getStudents());
}

小结

1、关联-association

2、集合-collection

3、所以association是用于一对一和多对一,而collection是用于一对多的关系

4、JavaType和ofType都是用来指定对象类型的

  • JavaType是用来指定pojo中属性的类型
  • ofType指定的是映射到list集合属性中pojo的类型。

注意说明:

1、保证SQL的可读性,尽量通俗易懂

2、根据实际要求,尽量编写性能更高的SQL语句

3、注意属性名和字段不一致的问题

4、注意一对多和多对一 中:字段和属性对应的问题

5、尽量使用Log4j,通过日志来查看自己的错误

一对多和多对一对于很多人来说是难点,一定要大量的做练习理解!

mybatis动态SQL

介绍

什么是动态SQL:动态SQL指的是根据不同的查询条件 , 生成不同的Sql语句.

1
2
3
4
5
6
7
8
9
10
11
官网描述:
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。
动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。

-------------------------------
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
-------------------------------

我们之前写的 SQL 语句都比较简单,如果有比较复杂的业务,我们需要写复杂的 SQL 语句,往往需要拼接,而拼接 SQL ,稍微不注意,由于引号,空格等缺失可能都会导致错误。

那么怎么去解决这个问题呢?这就要使用 mybatis 动态SQL,通过 if, choose, when, otherwise, trim, where, set, foreach等标签,可组合成非常灵活的SQL语句,从而在提高 SQL 语句的准确性的同时,也大大提高了开发人员的效率。

搭建环境

新建一个数据库表:blog

字段:id,title,author,create_time,views

1
2
3
4
5
6
7
CREATE TABLE `blog` (
`id` varchar(50) NOT NULL COMMENT '博客id',
`title` varchar(100) NOT NULL COMMENT '博客标题',
`author` varchar(30) NOT NULL COMMENT '博客作者',
`create_time` datetime NOT NULL COMMENT '创建时间',
`views` int(30) NOT NULL COMMENT '浏览量'
) ENGINE=InnoDB DEFAULT CHARSET=utf8

1、创建Mybatis基础工程

创建Mybatis基础工程

2、IDutil工具类

1
2
3
4
5
6
7
public class IDUtil {

public static String genId(){
return UUID.randomUUID().toString().replaceAll("-","");
}

}

3、实体类编写 【注意set方法作用】

1
2
3
4
5
6
7
8
9
10
11
import java.util.Date;

public class Blog {

private String id;
private String title;
private String author;
private Date createTime;
private int views;
//set,get....
}

4、编写Mapper接口及xml文件

1
2
public interface BlogMapper {
}
1
2
3
4
5
6
7
<?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">
<mapper namespace="com.kuang.mapper.BlogMapper">

</mapper>

5、mybatis核心配置文件,下划线驼峰自动转换

1
2
3
4
5
6
7
8
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--注册Mapper.xml-->
<mappers>
<mapper resource="mapper/BlogMapper.xml"/>
</mappers>

6、插入初始数据

编写接口

1
2
//新增一个博客
int addBlog(Blog blog);

sql配置文件

1
2
3
4
<insert id="addBlog" parameterType="blog">
insert into blog (id, title, author, create_time, views)
values (#{id},#{title},#{author},#{createTime},#{views});
</insert>

初始化博客方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Test
public void addInitBlog(){
SqlSession session = MybatisUtils.getSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);

Blog blog = new Blog();
blog.setId(IDUtil.genId());
blog.setTitle("Mybatis如此简单");
blog.setAuthor("狂神说");
blog.setCreateTime(new Date());
blog.setViews(9999);

mapper.addBlog(blog);

blog.setId(IDUtil.genId());
blog.setTitle("Java如此简单");
mapper.addBlog(blog);

blog.setId(IDUtil.genId());
blog.setTitle("Spring如此简单");
mapper.addBlog(blog);

blog.setId(IDUtil.genId());
blog.setTitle("微服务如此简单");
mapper.addBlog(blog);

session.close();
}

初始化数据完毕!

if 语句

需求:根据作者名字和博客名字来查询博客!如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询

1、编写接口类

1
2
//需求1
List<Blog> queryBlogIf(Map map);

2、编写SQL语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!--需求1:
根据作者名字和博客名字来查询博客!
如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询
select * from blog where title = #{title} and author = #{author}
-->
<select id="queryBlogIf" parameterType="map" resultType="blog">
select * from blog where
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</select>

3、测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void testQueryBlogIf(){
SqlSession session = MybatisUtils.getSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);

HashMap<String, String> map = new HashMap<String, String>();
map.put("title","Mybatis如此简单");
map.put("author","狂神说");
List<Blog> blogs = mapper.queryBlogIf(map);

System.out.println(blogs);

session.close();
}

这样写我们可以看到,如果 author 等于 null,那么查询语句为 select * from user where title=#{title},但是如果title为空呢?那么查询语句为 select * from user where and author=#{author},这是错误的 SQL 语句,如何解决呢?请看下面的 where 语句!

Where

修改上面的SQL语句;

1
2
3
4
5
6
7
8
9
10
11
<select id="queryBlogIf" parameterType="map" resultType="blog">
select * from blog
<where>
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>

这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。

Set

同理,上面的对于查询 SQL 语句包含 where 关键字,如果在进行更新操作的时候,含有 set 关键词,我们怎么处理呢?

1、编写接口方法

1
int updateBlog(Map map);

2、sql配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--注意set是用的逗号隔开-->
<update id="updateBlog" parameterType="map">
update blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author}
</if>
</set>
where id = #{id};
</update>

3、测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
public void testUpdateBlog(){
SqlSession session = MybatisUtils.getSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);

HashMap<String, String> map = new HashMap<String, String>();
map.put("title","动态SQL");
map.put("author","秦疆");
map.put("id","9d6a763f5e1347cebda43e2a32687a77");

mapper.updateBlog(map);


session.close();
}

choose语句

有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose 标签可以解决此类问题,类似于 Java 的 switch 语句

1、编写接口方法

1
List<Blog> queryBlogChoose(Map map);

2、sql配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<select id="queryBlogChoose" parameterType="map" resultType="blog">
select * from blog
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
and author = #{author}
</when>
<otherwise>
and views = #{views}
</otherwise>
</choose>
</where>
</select>

3、测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
public void testQueryBlogChoose(){
SqlSession session = MybatisUtils.getSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);

HashMap<String, Object> map = new HashMap<String, Object>();
map.put("title","Java如此简单");
map.put("author","狂神说");
map.put("views",9999);
List<Blog> blogs = mapper.queryBlogChoose(map);

System.out.println(blogs);

session.close();
}

SQL片段

有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用。

提取SQL片段:

1
2
3
4
5
6
7
8
<sql id="if-title-author">
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>

引用SQL片段:

1
2
3
4
5
6
7
8
<select id="queryBlogIf" parameterType="map" resultType="blog">
select * from blog
<where>
<!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace -->
<include refid="if-title-author"></include>
<!-- 在这里还可以引用其他的 sql 片段 -->
</where>
</select>

注意:

①、最好基于 单表来定义 sql 片段,提高片段的可重用性

②、在 sql 片段中不要包括 where

Foreach

将数据库中前三个数据的id修改为1,2,3;

需求:我们需要查询 blog 表中 id 分别为1,2,3的博客信息

1、编写接口

1
List<Blog> queryBlogForeach(Map map);

2、编写SQL语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<select id="queryBlogForeach" parameterType="map" resultType="blog">
select * from blog
<where>
<!--
collection:指定输入对象中的集合属性
item:每次遍历生成的对象
open:开始遍历时的拼接字符串
close:结束时拼接的字符串
separator:遍历对象之间需要拼接的字符串
select * from blog where 1=1 and (id=1 or id=2 or id=3)
-->
<foreach collection="ids" item="id" open="and (" close=")" separator="or">
id=#{id}
</foreach>
</where>
</select>

3、测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Test
public void testQueryBlogForeach(){
SqlSession session = MybatisUtils.getSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);

HashMap map = new HashMap();
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(3);
map.put("ids",ids);

List<Blog> blogs = mapper.queryBlogForeach(map);

System.out.println(blogs);

session.close();
}

小结:其实动态 sql 语句的编写往往就是一个拼接的问题,为了保证拼接准确,我们最好首先要写原生的 sql 语句出来,然后在通过 mybatis 动态sql 对照着改,防止出错。多在实践中使用才是熟练掌握它的技巧。

​ 动态SQL在开发中大量的使用,一定要熟练掌握!

mybatis逆向工程(maven版)

通过 Maven 完成 Mybatis 逆向工程

1. 新建一个 Maven Project 项目

新建一个 Maven 项目,然后新建文件夹 /mybatis-maven/src/main/resources,在文件夹下新建文件 generatorConfig.xml。

Maven 项目结构

2. 配置 pom.xml 文件

配置 pom.xml 文件,在 pom.xml 文件的 project 标签里加入代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
</dependencies>
<configuration>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
</build>

配置插件 generator 版本是 1.3.2 并配置 Mysql 驱动是 5.1.38。

3. 配置文件 generatorConfig.xml

generatorConfig.xml 是在目录 src 下的 main 下的 resources 下。注意这里的targetProject="./src" 生成的文件也会在这个下面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
<context id="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="false" />
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root"
password="123456">
</jdbcConnection>
<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
connectionURL="jdbc:oracle:thin:@localhost:1521:mybatis"
userId=""
password="">
</jdbcConnection> -->

<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>

<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="com.ssm.po"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.ssm.mapper"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.ssm.mapper"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<!--
tableName:要生成的表名
domainObjectName:生成后的实例名
enableCountByExample:Count语句中加入where条件查询,默认true开启
enableUpdateByExample:Update语句中加入where条件查询,默认true开启
enableDeleteByExample:Delete语句中加入where条件查询,默认true开启
enableSelectByExample:Select多条语句中加入where条件查询,默认true开启
selectByExampleQueryId:Select单个对象语句中加入where条件查询,默认true开启
-->
<table tableName="items">
<!--
常用:
property:将所有字段逆向生成为类属性,默认全部
ignoreColumn:生成时忽略列字段
-->
</table>
<table tableName="orders"></table>
<table tableName="orderdetail"></table>
<table tableName="user"></table>


</context>
</generatorConfiguration>

4. 运行 Maven

运行命令mybatis-generator:generate。   操作步骤:选中项目右击 => Run As => Maven build… =>在 Goals 中输入mybatis-generator:generate => Run =>刷新工程。

生成的代码结构

spring-mybatis整合方式一

一、mybatis整合方式一

1.封装一个user实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.sec.pojo;

public class User {
private int id;
private String name;
private String pwd;

public User() {
}

public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}

public int getId() {
return id;
}

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

public String getName() {
return name;
}

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

public String getPwd() {
return pwd;
}

public void setPwd(String pwd) {
this.pwd = pwd;
}

@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}

2.导入pom.xml的依赖以及maven的资源顾虑问题的build

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources/</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>

注意事项:版本要对应,否则无法会报错!

3.编写一个接口UserMapper

1
2
3
4
5
6
7
8
9
10
package com.sec.mapper;

import com.sec.pojo.User;

import java.util.List;

public interface UserMapper {
public List<User> select();
}

4.完成UserMapper.xml的配置

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sec.mapper.UserMapper">
<select id="select" resultType="user" >
select * from user
</select>

</mapper>

5.完成mybatis-config.xml的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.sec.pojo"/>
</typeAliases>
<!--<settings>
<setting name="" value=""/>
</settings>-->
<!--<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/hjcdb" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>

<mappers>
<mapper resource="com/com.sec/mapper/UserMapper.xml" />
</mappers>-->

</configuration>

6.完成Spring核心配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<!--DataSource -->
<bean id="DataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/hjcdb" />
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--SqlSessionFactory-->
<bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="DataSource"/>
<!--绑定mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/sec/mapper/UserMapper.xml"/>
</bean>
<!--就是我们使用的SqlSession-->
<bean id="SqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--只能使用构造器注入SqlSessionFactory 。 因为它没有set方法-->
<constructor-arg index="0" ref="SqlSessionFactory"/>
</bean>


</beans>

7.完成applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">

<import resource="beans-dao.xml" />
<bean id="userMapper" class="com.sec.mapper.UserMapperImpl">
<property name="sqlSession" ref="SqlSession"/>
</bean>
</beans>

8.编写接口UserMapper的实现类UserMapperImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.sec.mapper;

import com.sec.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;

import java.util.List;

public class UserMapperImpl implements UserMapper {

private SqlSessionTemplate sqlSession;

public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}

@Override
public List<User> select() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.select();
}
}

9.测试类中进行测试

1
2
3
4
5
6
ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
UserMapper userMapper = (UserMapper) context.getBean("userMapper");
List<User> select = userMapper.select();
for (User user : select) {
System.out.println(user);
}

二、mybatis整合方式二

1.编写接口的实现类

  • 在方式一的基础上可以再编写一个接口的实现类,要继承SqlSessionDaoSupport
  • 使用getSqlSession();方法获取SqlSession
  • 使用SqlSession获取接口
  • 调用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.sec.mapper;

import com.sec.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.List;

public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
@Override
public List<User> select() {
SqlSession session = getSqlSession();
UserMapper mapper = session.getMapper(UserMapper.class);
return mapper.select();
}
}

2.在applicationContext.xml中注册UserMapperImpl2的bean

1
2
3
<bean id="userMapper2" class="com.sec.mapper.UserMapperImpl2">
<property name="sqlSessionFactory" ref="SqlSessionFactory"/>
</bean>

注意

  • 在继承了 SqlSessionDaoSupport类后可以不用SqlSessionTemplate了

  • 直接在applicationContext.xml文件中的userMapper2中注入SqlSessionFactory就可以了

3.测试

1
2
3
4
5
6
ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
UserMapper userMapper = (UserMapper) context.getBean("userMapper2");
List<User> select = userMapper.select();
for (User user : select) {
System.out.println(user);
}

springboot整合jpa

SpringBoot-data-JPA

JpaRepository接口

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

  1. 导入依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.9</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
    </dependency>
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
    </dependency>
    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>
    </dependencies>
  2. 配置application.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    spring:
    datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/hjcDB?serverTimezone=UTC&&characterEncoding=utf8&useUnicode=true

    jpa:
    show-sql: true
    database: mysql
    database-platform: mysql
    hibernate:
    ddl-auto: update
    properties:
    hibernate:
    dialect: org.hibernate.dialect.MySQL57Dialect
  3. 写实体类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    package com.sec.pojo;

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;

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

    @Entity(name = "userInfo")//表名
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class user {
    //主键
    @Id
    //自动增长
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private String pwd;

    }

  4. 写接口,继承JpaRepository<user,Integer>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package com.sec.dao;

    import com.sec.pojo.user;
    import org.springframework.data.jpa.repository.JpaRepository;

    public interface userDao extends JpaRepository<user,Integer> {
    //传统样式查询参数(`?`)不再支持;使用JPA样式的序号参数(例如,`?1’)
    /*@Query("from user_info where name = ?")
    List<user> queryByNameUseHQL(String name);*/

    @Query(value = "select * from user_info where name=?",nativeQuery = true)
    List<user> queryByNameUseSQL(String name);

    @Query(value = "update user_info set name=? where id=?",nativeQuery = true)
    @Modifying//需要执行一个更新操作
    void updateUsersNameById(String name,Integer id);
    }

  5. 测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    @Test
    void contextLoads() {
    /*//相当于insert语句
    userDao.save(new user(null,"zhangsan","123456"));
    userDao.save(new user(null,"lisi","123456"));
    userDao.save(new user(null,"wangwu","123456"));
    userDao.save(new user(null,"laksjkda","123456"));

    //相当于select语句
    List<user> all = userDao.findAll();
    for (user u: all
    ) {
    System.out.println(u);
    }*/



    //HQL 已不支持
    /*List<user> wangwu = userDao.queryByNameUseHQL("wangwu");
    for (user user : wangwu) {
    System.out.println(user);
    }*/

    //自定义查询方法测试
    /*List<user> lisi = userDao.queryByNameUseSQL("lisi");
    for (user user : lisi) {
    System.out.println(user);
    }*/

    //根据id删除
    //userDao.deleteById(6);

    //修改
    Optional<user> userDaoById = userDao.findById(2);
    user user = userDaoById.get();
    user.setName("猪八戒");
    user.setPwd("zhubajie");
    userDao.save(user);
    }
  6. 自定义方法测试 修改

    1
    2
    3
    4
    5
    6
    @Test
    @Transactional //@Transactional与@Test 一起使用时 事务是自动回滚的。
    @Rollback(false) //取消自动回滚
    public void upd(){
    userDao.updateUsersNameById("haojiacheng",1);
    }

Repository接口

  1. 编写接口继承Repository

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    package com.sec.dao;

    import com.sec.pojo.user;
    import org.springframework.data.repository.Repository;

    import java.util.List;

    public interface userDaoByName extends Repository<user,Integer> {
    /**
    * 根据名字查信息
    * @param name
    * @return
    */
    List<user> findByName(String name);

    /**
    * 根据名字和密码查信息
    * @param name
    * @param pwd
    * @return
    */
    List<user> findByNameAndPwd(String name,String pwd);

    /**
    * 根据id删除信息
    * @param id
    */
    void deleteById(Integer id);

    @Query(value = "update user_info set name=? where id=?",nativeQuery = true)
    @Modifying
    void updateUserName(String name,Integer id);
    }

  2. 测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    @Test
    public void hjc(){
    //根据名字查询信息
    /*List<user> res = userDaoByName.findByName("zhangsan");
    for (user u:
    res) {
    System.out.println(u);
    }*/

    //根据名字和密码查询信息
    /*List<user> zhangsan = userDaoByName.findByNameAndPwd("adf", "123456");
    System.out.println(zhangsan);
    System.out.println(zhangsan==null);
    System.out.println(zhangsan.equals(""));
    for (user u :
    zhangsan) {
    System.out.println(u);
    }*/

    //根据id删除
    //userDaoByName.deleteById(7);

    //修改
    @Test
    @Transactional
    @Rollback(false) //取消自动回滚
    void test1(){
    userDaoByName.updateUserName("郝嘉诚",1);
    }
    }

CrudRepository 接口

​ 如果持久层接口较多,且每一个接口都需要声明相似的增删改查方法,直接继承 Repository 就显得有些啰嗦,这时可以继承 CrudRepository,它会自动为域对象创建增删改查方法,供业务层直接使用。开发者只是多写了 “Crud” 四个字母,即刻便为域对象提供了开箱即用的十个增删改查方法。

​ 但是,使用 CrudRepository 也有副作用,它可能暴露了你不希望暴露给业务层的方法。比如某些接口你只希望提供增加的操作而不希望提供删除的方法。针对这种情况,开发者只能退回到 Repository 接口,然后到 CrudRepository 中把希望保留的方法声明复制到自定义的接口中即可。

​ 分页查询和排序是持久层常用的功能,Spring Data 为此提供了 PagingAndSortingRepository 接口,它继承自 CrudRepository 接口,在 CrudRepository 基础上新增了两个与分页有关的方法。但是,我们很少会将自定义的持久层接口直接继承自 PagingAndSortingRepository,而是在继承 Repository 或 CrudRepository 的基础上,在自己声明的方法参数列表最后增加一个 Pageable 或 Sort 类型的参数,用于指定分页或排序信息即可,这比直接使用 PagingAndSortingRepository 提供了更大的灵活性。

​ JpaRepository 是继承自 PagingAndSortingRepository 的针对 JPA 技术提供的接口,它在父接口的基础上,提供了其他一些方法,比如 flush(),saveAndFlush(),deleteInBatch() 等。如果有这样的需求,则可以继承该接口。

Repository用于查询,CrudRepository用于增删改

上代码:

  1. 创建一个interface 接口 继承 CrudRepository

    1
    2
    3
    4
    5
    6
    7
    8
    9
    package com.sec.dao;

    import com.sec.pojo.user;
    import org.springframework.data.repository.CrudRepository;

    public interface userCrud extends CrudRepository<user,Integer> {

    }

  2. 测试:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    @Test
    void CrudRepositoryTest(){
    /*//增
    user user = new user();
    user.setName("苏弋");
    user.setPwd("452256");
    userCrud.save(user);*/

    //删
    //userCrud.deleteById(10);

    //改


    //查全部
    /*Iterable<user> all = userCrud.findAll();
    for (user user : all) {
    System.out.println(user);
    }*/

    //根据id查
    /*Optional<user> userCrudById = userCrud.findById(1);
    System.out.println(userCrudById.get());*/

    //查总记录数
    /*long count = userCrud.count();
    System.out.println("共:"+count+"行");*/

    //根据id查询是否存在
    /*boolean flag = userCrud.existsById(1);
    if(flag=true){
    System.out.println("存在");
    }else{
    System.out.println("不存在");
    }*/

    //修改
    Optional<user> byId = userCrud.findById(2);
    user user = byId.get();
    user.setName("孙悟空");
    user.setPwd("sunwukong");
    userCrud.save(user);

    }

vue-Router

vue+ElementUI

创建工程

  1. 创建一个名为hello-vue的工程 vue init webpack hello-vue

  2. 安装依赖,我们需要安装vue-router、element-ui、sass-loader和node-sass四个插件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #进入工程目录
    cd hello-vue
    #安装 vue-router
    cnpm install vue-router --save-dev
    #安装 element-ui
    cnpm i element-ui -S
    #安装依赖
    cnpm install
    #安装 sass 加载器
    cnpm install sass-loader node-sass --save-dev
    #启动测试
    cnpm run dev

    安装报错,检查版本是否兼容,支持?

  3. Npm命令解释:

    • npm install moduleName: 安装模块到项目目录下
    • npm install -g moduleName: -g的意思是将模块安装到全局,具体安装到磁盘哪个位置,要看npm config prefix的位置
    • npm install –save moduleName: –save的意思是将模块安装到项目目录下,并在package文件的dependencies节点写入依赖,-S为该命令的缩写
    • npm install –save-dev moduleName: –save-dev的意思是将模块安装到项目目录下,并在package文件的devDependencies节点写入依赖,-D为该命令的缩写

创建登陆页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<template>
<div>
<el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
<h3 class="login-title">欢迎登录</h3>
<el-form-item label="账号" prop="username">
<el-input type="text" placeholder="请输入账号" v-model="form.username"/>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" placeholder="请输入密码" v-model="form.password"/>
</el-form-item>
<el-form-item>
<el-button type="primary" v-on:click="onSubmit(loginForm)">登录</el-button>
</el-form-item>
</el-form>

<el-dialog
title="温馨提示"
:visible.sync="dialogVisible"
width="30%"
:before-close="handleClose">
<span>请输入账号和密码</span>
<span slot="footer" class="dialog-footer">
<el-button type=primary @click="dialogVisible = false">确 定</el-button>
</span>
</el-dialog>
</div>
</template>

<script>
export default {
name: "login",
data() {
return {
form: {
username:'',
password:''
},
rules:{
username: [
{required:true,message:'账号不可为空',trigger:'blur'}
],
password: [
{required:true,message:'密码不可为空',trigger:'blur'}
]
},
//对话框显示隐藏
dialogVisible:false
}
},
methods: {
onSubmit(formName) {
this.$refs[formName].validate((valid)=>{
if(valid){
this.$router.push('/hjc');
}else{
this.dialogVisible=true;
return false;
}
});
}
}
}
</script>
<style lang="css" scoped>
.login-box{
border: 1px solid #DCDFE6;
width: 350px;
margin: 180px auto;
padding: 35px 35px 15px 35px;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
box-shadow: 0 0 25px #909399;
}
.login-title{
text-align: center;
margin: 0 auto 40px auto;
color: #303133;
}
</style>

首页:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div>
<h1>首页</h1>
<h2>{{message}}</h2>
</div>
</template>

<script>
export default {
name: "hjc",
data(){
return{
message:"hello vue-router"
}
}
}
</script>

<style scoped>

</style>

路由:

router==》index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import Vue from 'vue'
import Router from 'vue-router'
import hjc from "../components/hjc";
import login from "../components/login";

Vue.use(Router)

export default new Router({
routes: [
{
path: '/',
name: 'hjc',
component: hjc
},
{
path:'/hjc',
name:'haojiacheng',
component:hjc
},
{
path:'/login',
name:'login',
component:login
}
]
})

组件:

App.vue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
<div id="app">
<router-view></router-view>
</div>
</template>

<script>
export default {
name: 'App'
}
</script>

<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

js文件:

main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import Vue from 'vue'
import App from './App'

import router from './router'

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.config.productionTip = false

Vue.use(router);
Vue.use(ElementUI);


new Vue({
el: '#app',
router,
render:h=>h(App)
})

运行:

npm run dev

1620581011763

传递参数和重定向

两种方法皆可传递对象或数组等参数

一、方法一

  1. 页面传递参数

    1
    2
    3
    <el-menu-item index="1-1">
    <router-link class="txt-under" :to="{name:'profile',params:{id:'1'}}">个人信息</router-link>
    </el-menu-item>
  2. 配置路由参数接收

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {
    path:'/hjc',
    name:'haojiacheng',
    component:hjc,
    children:[
    {path:'/user/profile/:id',name: 'profile',component:profile},
    {path:'/user/list',component:list},
    {path:'/main',component:main},
    ]
    },
  3. 页面获取参数 注意:==$route==

    1
    2
    3
    4
    5
    6
    <template>
    <div>
    <h1>个人信息</h1>
    <p>{{$route.params.id}}</p>
    </div>
    </template>

二、方法二

  1. 开启props

    1
    {path:'/user/profile/:id',name: 'profile',component:profile,props:true},
  2. 传递参数(对象 student)

    1
    <router-link class="txt-under" :to="{name:'profile',params:{id:'1',student:student}}">个人信息</router-link>
  3. 接收参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <template>
    <div>
    <h1>个人信息</h1>
    <p>{{$route.params.id}}</p>
    <ul>
    <li v-for="item of student">{{item}}</li>
    </ul>
    </div>
    </template>

    <script>
    export default {
    name: "profile",
    props:{
    student:{
    name:'',
    age:'',
    phone:''
    }
    }
    }
    </script>

路由模式

路由模式有两种

修改路由配置,代码如下:

1
2
3
export default new Router({
mode:'history',
})

404

处理404创建一个名为NotFound.vue 的视图组件,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div>
<h1>您访问的页面不存在!</h1>
</div>
</template>

<script>
export default {
name: "NotFound"
}
</script>

<style scoped>

</style>

配置路由 index.js:

1
2
3
4
{
path:'*',
component:NotFound
}

路由钩子与异步请求

beforeRouterEnter: 在进入路由前执行

beforeRouterLeave: 在离开路由前执行

上代码:

1
2
3
4
5
6
7
8
9
10
11
beforeRouteEnter:(to, from, next)=>{
console.log("进入路由之前");
next(vm => {
vm.getData()
});

},
beforeRouteLeave:(to, from, next)=>{
console.log("进入路由之后");
next();
},

参数说明:

  • to:路由将要跳转的路径信息
  • from:路径跳转前的路径信息
  • next:路由的控制参数
    • next()跳入下一个页面
    • next(’/path’)改变路由的跳转方向
    • next(false)返回原来的页面
    • next(vm=>{})仅在beforeRouteEnter中可用,vm是组件实例

在钩子函数中使用异步请求

  1. 安装axios vue-axios cnpm install --save axios vue-axios

  2. main.js 引用Axios

    1
    2
    3
    import axios from 'axios';
    import VueAxios from 'vue-axios';
    Vue.use(VueAxios,axios);
  3. 在beforeRouteEnter中进行异步请求

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    methods:{
    getData:function () {
    this.axios({
    method:'get',
    url:'http://localhost:8080/static/mock/data.json'
    }).then(function (response) {
    console.log(response)
    })
    }
    }
  4. 导入json文件,放入static下的mock中 data.json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    {
    "name":"狂神说java",
    "url": "http://baidu.com",
    "page": 1,
    "isNonProfit":true,
    "address": {
    "street": "含光门",
    "city":"陕西西安",
    "country": "中国"
    },
    "links": [
    {
    "name": "B站",
    "url": "https://www.bilibili.com/"
    },
    {
    "name": "4399",
    "url": "https://www.4399.com/"
    },
    {
    "name": "百度",
    "url": "https://www.baidu.com/"
    }
    ]
    }

  5. npm run dev 运行访问结果如下:
    1620619140254

vue-axios

vue-axios

支持多种请求方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
axios(config)

axios.request(config)

axios.get(url,config)

axios.delete(url,config)

axios.head(url,config)

axios.post(url,data,config)

axios.put(url,data,config)

axios.patch(url,data,config)

axios并发请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
axios.all([
axios({
url:"http://123.207.32.32:8000/home/multidata",
}),
axios({
url:"http://123.207.32.32:8000/home/data",
params:{
page:1,
type:'sell'
}

})]).then(res=>{
console.log(res);
console.log(res[0]);
console.log(res[1]);
})

win10专业版激活后编程教育版

win10专业版激活后编程教育版

方法一:

  1. 按win键,搜索cmd,以管理员身份运行

  2. 输入命令 ikp后是激活密钥

    1
    slmgr.vbs -ipk W269N-WFGWX-YVC9B-4J6C9-T83GX

方法二:

  1. 打开电脑设置,点击更新和安全,点击激活

  2. 更改产品密钥

  3. 输入密钥:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Windows 10 Pro(win10专业版激活密钥)
    TPYNC-4J6KF-4B4GP-2HD89-7XMP6
    2BXNW-6CGWX-9BXPV-YJ996-GMT6T
    NRTT2-86GJM-T969G-8BCBH-BDWXG
    XC88X-9N9QX-CDRVP-4XV22-RVV26
    TNM78-FJKXR-P26YV-GP8MB-JK8XG
    TR8NX-K7KPD-YTRW3-XTHKX-KQBP6

    VK7JG-NPHTM-C97JM-9MPGT-3V66T
    NPPR9-FWDCX-D2C8J-H872K-2YT43
    W269N-WFGWX-YVC9B-4J6C9-T83GX
    NYW94-47Q7H-7X9TT-W7TXD-JTYPM
    NJ4MX-VQQ7Q-FP3DB-VDGHX-7XM87
    MH37W-N47XK-V7XM9-C7227-GCQG9

宝塔面板配置文件记录

宝塔面板配置文件记录

MySQL配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
[client]
#password = your_password
port = 3306
socket = /tmp/mysql.sock

[mysqld]
lower_case_table_names=1
port = 3306
socket = /tmp/mysql.sock
datadir = /www/server/data
default_storage_engine = InnoDB
performance_schema_max_table_instances = 400
table_definition_cache = 400
skip-external-locking
key_buffer_size = 32M
max_allowed_packet = 100G
table_open_cache = 128
sort_buffer_size = 768K
net_buffer_length = 4K
read_buffer_size = 768K
read_rnd_buffer_size = 256K
myisam_sort_buffer_size = 8M
thread_cache_size = 16
query_cache_size = 16M
tmp_table_size = 32M
sql-mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

explicit_defaults_for_timestamp = true
#skip-name-resolve
max_connections = 500
max_connect_errors = 100
open_files_limit = 65535

log-bin=mysql-bin
binlog_format=mixed
server-id = 1
expire_logs_days = 10
slow_query_log=1
slow-query-log-file=/www/server/data/mysql-slow.log
long_query_time=3
#log_queries_not_using_indexes=on
early-plugin-load = ""


innodb_data_home_dir = /www/server/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /www/server/data
innodb_buffer_pool_size = 128M
innodb_log_file_size = 64M
innodb_log_buffer_size = 16M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50
innodb_max_dirty_pages_pct = 90
innodb_read_io_threads = 1
innodb_write_io_threads = 1

[mysqldump]
quick
max_allowed_packet = 500M

[mysql]
no-auto-rehash

[myisamchk]
key_buffer_size = 32M
sort_buffer_size = 768K
read_buffer = 2M
write_buffer = 2M

[mysqlhotcopy]
interactive-timeout

Tomcat配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine defaultHost="localhost" name="Catalina">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" />
</Realm>
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log" suffix=".txt" />
</Host>
<Host autoDeploy="true" name="haojiacheng.cn" unpackWARs="true" xmlNamespaceAware="false" xmlValidation="false">
<Context crossContext="true" docBase="/www/server/tomcat/webapps/zhjc" path="" reloadable="true" />
<Context docBase="/temp/images" path="/pic" />
</Host>
</Engine>
</Service>
</Server>

网站站点配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
server
{
listen 80;
server_name haojiacheng.cn www.haojiacheng.cn;
index index.php index.html index.htm default.php default.htm default.html;
root /www/server/tomcat/webapps/zhjc;

#SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
#error_page 404/404.html;
#SSL-END

#ERROR-PAGE-START 错误页配置,可以注释、删除或修改
#error_page 404 /404.html;
#error_page 502 /502.html;
#ERROR-PAGE-END

#PHP-INFO-START PHP引用配置,可以注释或修改
#TOMCAT-START
location /
{
proxy_pass "http://haojiacheng.cn:8080";
proxy_set_header Host haojiacheng.cn;
proxy_set_header X-Forwarded-For $remote_addr;
}
location ~ .*\.(gif|jpg|jpeg|bmp|png|ico|txt|js|css)$
{
#expires 12h;
proxy_pass http://haojiacheng.cn:8080;
}
location ~ .*\.(js|css)?$
{
proxy_pass http://haojiacheng.cn:8080;
}

location ~ .*\.war$
{
return 404;
}
#TOMCAT-END
include enable-php-00.conf;
#PHP-INFO-END

#REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
include /www/server/panel/vhost/rewrite/haojiacheng.cn.conf;
#REWRITE-END

#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}

#一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log /dev/null;
access_log /dev/null;
}

location ~ .*\.(js|css)?$
{
expires 12h;
error_log /dev/null;
access_log /dev/null;
}
location /temp/images/ {
alias /pic/;
}
access_log /www/wwwlogs/haojiacheng.cn.log;
error_log /www/wwwlogs/haojiacheng.cn.error.log;
}

Tomcat 零配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?xml version="1.0" encoding="UTF-8"?>

<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />

<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />


<GlobalNamingResources>

<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>
</Engine>
</Service>
</Server>

宝塔面板端口开放记录

1620901159933

腾讯云服务器配置记录

端口开放记录

1620901074511

域名解析记录

1620901102961