创建项目:创建一个crm项目
添加依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
<relativePath/>
</parent>
<groupId>com.bdqn</groupId>
<artifactId>CT-CRM</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>CT-CRM</name>
<description>CT-CRM</description>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<!-- 引入Spring Boot Starter Web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- 引入Spring Boot Thymeleaf依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 引入Spring Boot Web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入Spring Boot DevTools依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- 引入MySQL驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 引入Spring Boot Configuration Processor依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- 引入Lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 引入Spring Boot Test依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 引入MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
<!-- 引入Thymeleaf布局方言 -->
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
<!-- 引入Thymeleaf模板引擎 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<!-- 引入MyBatis-Plus支持(不需要再引入MyBatis包) -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.8</version>
</dependency>
<!-- 引入Druid数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.20</version>
</dependency>
<!-- 使用SLF4J API来记录日志信息 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置文件:
spring:
#配置数据源
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql:///crm?useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
type: com.alibaba.druid.pool.DruidDataSource #使用阿里巴巴Druid数据源
druid:
############ 连接池基础配置 ############
initial-size: 1 #初始化大小
max-active: 20 #最大连接数
min-idle: 1 #最小连接数
max-wait: 60000 #获取连接等待超时的时间(单位:毫秒)
time-between-eviction-runs-millis: 60000 #间隔多久检测一次需要关闭的空闲连接(单位:毫秒)
time-between-log-stats-millis: 60000 #日志统计信息之间的时间(单位:毫秒)
min-evictable-idle-time-millis: 300000 #一个连接在池中最小生存的时间(单位:毫秒)
max-evictable-idle-time-millis: 600000 #一个连接在池中最大生存的时间(单位:毫秒)
test-while-idle: true #应用向连接池申请连接,值为false时,连接池将会判断连接是否处于空闲状态,如果是则验证这条连接是否可用
test-on-borrow: false #默认值为false,如果为true,应用向连接池申请连接时连接池会判断这条连接是否是可用的
test-on-return: false #默认值为false,如果为true,当应用使用完连接,连接池回收连接的时候会判断该连接是否还可用
validation-query: select 1 #用来测试连接是否可用的SQL语句
validation-query-timeout: 60000 #连接是否可用测试超时时间(单位:毫秒)
# use-global-datasource-stat: true #使用全局数据源统计
keep-alive: true #连接池中的min-idle数量以内的连接,空闲时间超过max-evictable-idle-time-millis,则会执行KeepAlive操作
pool-prepared-statements: true #是否缓存PreparedStatement,也就是PSCache,对支持游标的数据库性能提升巨大,比如Oracle
max-open-prepared-statements: 20 #要启用PSCache,必须配置大于0(当大于0时,pool-prepared-statements自动触发修改为true)在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如100
remove-abandoned: true #开启连接池回收(针对不活跃的连接)
remove-abandoned-timeout: 1800 #超时连接回收时间(单位:毫秒)
log-abandoned: true #回收连接时打印日志
############ 数据库连接监控 ############
aop-patterns: "com.bdqn.*.mapper.*" #Spring监控,利用AOP对指定接口的执行时间,JDBC数进行记录
# filters: stat,wall,log4j2 #启用内置过滤器(第一个 stat必须,否则监控不到SQL)
filter: #监控统计拦截器
stat: #开启DruidDataSource的状态监控
enabled: true #启用DruidDataSource状态监控
db-type: mysql #数据库类型
log-slow-sql: true #开启慢SQL监控
slow-sql-millis: 2000 #超过2s就认为是慢SQL,记录到日志中
slf4j: #日志监控,使用slf4j进行日志输出
enabled: true #启用日志监控
statement-log-error-enabled: true
statement-create-after-log-enabled: false
statement-close-after-log-enabled: false
result-set-open-after-log-enabled: false
result-set-close-after-log-enabled: false
web-stat-filter: #配置WebStatFilter,用于采集Web关联监控的数据
enabled: true #启用WebStatFilter
url-pattern: /* #过滤所有URL
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" #排除一些不必要的URL
session-stat-enable: true #开启Session统计功能
session-stat-max-count: 100 #Session的最大个数(默认100)
stat-view-servlet: #配置StatViewServlet(监控页面),用于展示Druid的统计信息
enabled: true #启用StatViewServlet(监控页面)
url-pattern: /druid/* #访问内置监控页面的路径,内置监控页面的首页是/druid/index.html
reset-enable: false #不允许清空统计数据,重新计算
login-username: admin #监控页面访问账号
login-password: lilibo #监控页面访问密码
allow: 127.0.0.1 #允许访问的地址,如果allow没有配置或者为空,则允许所有访问
deny: #拒绝访问的地址,deny优先于allow,如果在deny列表中,就算在allow列表中,也会被拒绝
thymeleaf:
cache: true
# 检查模板是否存在,然后再呈现
check-template: true
# 检查模板位置是否正确(默认值:true)
check-template-location: true
# Context-Type的值(默认值:text/html)
servlet:
content-type: text/html
# 开启MVC Thymeleaf视图解析(默认值:true)
enabled: true
# 模板编码
encoding: UTF-8
# 要被排除再解析之外的视图名称列表,用逗号分隔
excluded-view-names:
# 要运用于模板之上的模板模式。呈现StandardTemplate—ModeHandlers(默认值:HTML5)
mode: HTML5
# 在构建URL时添加导视图名称前的前缀(默认值:classpath:/templates/)
prefix: classpath:/templates/
# 在构建URL时添加导视图名称后的前缀(默认值:.html)
suffix: .html
# Thymeleaf模板解析器在解析器链中的顺序,默认情况下,它排第一位,顺序从1开始,只有在定义了额外的TemplateResolver Bean时才需要设置这个属性。
template-resolver-order:
# 可解析的视图名称列表,用逗号分隔
# view-names:
#MyBatis-Plus配置
mybatis-plus:
#Mapper映射文件所在目录
mapper-locations: classpath:mapper/*Mapper.xml
#数据实体类别名,实体包配置
type-aliases-package: com.bdqn.pojo
#全局配置
global-config:
#配置数据库逻辑删除特征
db-config:
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
#直接配置MyBatis全局参数
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印详细SQL日志
auto-mapping-behavior: full #字段和属性全自动映射
lazy-loading-enabled: true #懒加载开关
cache-enabled: true #二级缓存
server:
servlet:
context-path: /crm
logging:
level:
com.baomidou: debug #设置MyBatis-Plus日志级别为debug
org.springframework.jdbc.datasource.init: debug #设置DataSource初始化日志级别为debug
实体类包括User,Roel,使用注解配置映射,且配置好关联关系:
package com.bdqn.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import jakarta.persistence.CascadeType;
import jakarta.persistence.FetchType;
import jakarta.persistence.OneToMany;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
@Data
@TableName("sys_role")
public class Role implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@TableId(type = IdType.AUTO)
@TableField("role_id")
private long roleId;
@TableField("role_name")
private String roleName;
@TableField("role_desc")
private String roleDesc;
@TableField("role_flag")
private long roleFlag;
@OneToMany(targetEntity = User.class,fetch = FetchType.LAZY,cascade = CascadeType.REMOVE,mappedBy = "role")
private Set<User> users=new HashSet<User>();
}
package com.bdqn.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
@TableName("sys_user")
public class User implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@TableId(type = IdType.AUTO)
@TableField("usr_id")
private long usrId;
@TableField("usr_name")
private String usrName;
@TableField("usr_password")
private String usrPassword;
@TableField("usr_role_id")
private long usrRoleId;
@TableField("usr_flag")
private Integer usrFlag;
private Role role;
}
Service:
package com.bdqn.service;
import com.bdqn.pojo.User;
import java.util.List;
public interface UserService {
User login(String usrName,String usrPassword);
int addUser(User user);
int deleteUser(Long usrId);
int updateUser(User user);
User getUser(Long usrId);
List<User> findAllUsers();
List<User> selectUsersWithRoles();
}
实现类
package com.bdqn.service.impl;
import com.bdqn.mapper.UserMapper;
import com.bdqn.pojo.User;
import com.bdqn.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
@Override
public User login(String usrName, String usrPassword) {
return userMapper.login(usrName,usrPassword);
}
@Override
public int addUser(User user) {
return userMapper.insert(user);
}
@Override
public int deleteUser(Long usrId) {
return userMapper.deleteById(usrId);
}
@Override
public int updateUser(User user) {
return userMapper.updateById(user);
}
@Override
public User getUser(Long usrId) {
return userMapper.selectById(usrId);
}
@Override
public List<User> findAllUsers() {
return userMapper.selectList(null);
}
@Override
public List<User> selectUsersWithRoles() {
return userMapper.selectUsersWithRoles();
}
}
Controller:
package com.bdqn.controller;
import com.bdqn.pojo.User;
import com.bdqn.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class indexController {
@Resource
private UserService userService;
@RequestMapping("/login")
public String login(){
return "login";
}
@RequestMapping("/main")
public String toMain(){
return "main";
}
@RequestMapping("/logout")
public String logout(HttpSession session){
session.removeAttribute("loginUser");
session.invalidate();
return "redirect:/login";
}
@RequestMapping("/doLogin")
public String doLogin(String usrName, String usrPassword, HttpServletRequest request){
User user=userService.login(usrName, usrPassword);
if (user!=null){
request.getSession().setAttribute("loginUser", user);
return "main";
}else{
request.setAttribute("message","登录失败,用户名或密码错误!");
return "/login";
}
}
}
总结:
JPA + Thymeleaf 的结合使用
-
数据展示
- 使用 JPA 从数据库中查询数据,并将结果存储在 Java 对象中。
- 在 Thymeleaf 模板中,使用表达式和标签来展示这些数据,例如使用
th:each
遍历集合数据,使用th:text
显示单个数据项的值。- 在 Thymeleaf 模板中创建表单,使用
th:value
等标签将 Java 对象中的数据绑定到表单元素上。 - 提交表单时,控制器接收表单数据,使用 JPA 将数据保存到数据库中。
- 通过 Thymeleaf 的链接和表单提交,可以实现页面之间的导航。
- 结合 JPA 的数据查询,可以根据不同的条件展示不同的页面内容。
- 在 Thymeleaf 模板中创建表单,使用
Thymeleaf
-
简介
- Thymeleaf 是一个现代的服务器端 Java 模板引擎,用于 Web 应用程序的视图层开发。
- 它能够在 HTML 页面中直接使用 Thymeleaf 表达式和标签,实现动态数据的渲染和页面逻辑的处理。
-
主要特点
- 自然模板:Thymeleaf 的模板语法接近 HTML,使得前端开发人员易于理解和使用。
- 动态数据渲染:可以在模板中使用表达式来显示动态数据,如从数据库中获取的数据。
- 条件判断和循环:支持条件判断和循环结构,方便生成动态的 HTML 内容。
- 布局和片段:可以使用布局模板和片段来实现页面的复用和模块化开发。
- 安全性:对用户输入进行自动转义和过滤,防止 XSS(跨站脚本攻击)等安全问题。