springboot
Banner
// 在springboot项目 resources 目录下新建 banner.txt 文件
// 将结果拷贝
# # # # # # # # #
## ### ## ######## ## ## ## ########### ##
## ## ## ## ## ## ## ## ## ## ####
## ## # ## ## ## ## ## ########## ####
# ######## ## # # ## ## ## # ## ## ## ####
### ## # ## ####### ## ############### ########## ####
### # ## # ## ## ## # ## ## ## # ## # ####
# ## # ## ## ########## ## ## ## ## ## ##
## ##### ## ## ## ## ## ## ## ## ### ##
## ##### # ## ## ## #### ## ## ## #### # #### ##
## ## ## ## ### ## #### ## ###### ## ## ## ##
## ## ## ## ### ## ## ## # # ## ## ##
### ## # ## ## ## # ## ## ## ####
## ## ## ## # ## # ## # ## ## ##
## #### # # ### # ############# # ##
# # # # # # #
运行后
// 修改启动类可操作显示/关闭banner
SpringApplicationBuilder builder = new SpringApplicationBuilder(D1Application.class);
builder.bannerMode(Banner.Mode.LOG).run(args); // 关闭/显示 banner
编码
<!--pom.xml-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
# yaml 配置
#解决返回乱码问题
server:
servlet:
encoding:
charset: UTF-8
force: true
enabled: true
配置https
// jdk 安装目录 /bin 打开cmd
-alias 别名
-keypass 指定生成密钥的密码
-keyalg 指定密钥使用的加密算法(如 RSA)
-keysize 密钥大小
-validity 过期时间,单位天
-keystore 指定存储密钥的密钥库的生成路径、名称
-storepass 指定访问密钥库的密码
keytool -genkeypair -alias tomcat_https -keypass 123456 -keyalg RSA -keysize 1024 -validity 365 -keystore d:/tomcat_https.keystore -storepass 123456
// 生成的文件放在 resources 目录下
# 配置
#https默认端口:443,http默认端口:80
server:
port: 4439
http-port: 8082
#开启https,配置跟证书一一对应
ssl:
enabled: true
#指定证书
key-store: classpath:tomcat_https.keystore
key-store-type: JKS
#密码
key-store-password: 123456
可能有报错,maven执行clear再运行
// 配置http重指向https
@Configuration
public class SSLUtils {
@Bean
TomcatServletWebServerFactory tomcatServletWebServerFactory(){
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(){
@Override
protected void postProcessContext(Context context){
SecurityConstraint constraint = new SecurityConstraint();
constraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
constraint.addCollection(collection);
context.addConstraint(constraint);
}
};
factory.addAdditionalTomcatConnectors(createTomcatConnertor());
return factory;
}
private Connector createTomcatConnertor(){
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http0");
connector.setPort(8082);
connector.setSecure(false);
connector.setRedirectPort(4439);
return connector;
}
}
区分开发/生产环境
# application.yaml
spring:
profiles:
# 区分开发 / 生产
active: dev # prod
application:
# 应用名称
name: d1
#https默认端口:443,http默认端口:80
server:
# http/https 端口
port: 4439
http-port: 8082
#开启https,配置跟证书一一对应
ssl:
enabled: true
#指定证书
key-store: classpath:tomcat_https.keystore.old
key-store-type: JKS
#密码
key-store-password: 123456
servlet:
# utf-8 配置
encoding:
charset: UTF-8
force: true
enabled: true
book: # 自定义配置
name: 测试
author: 999
# application-dev.yaml
server:
servlet:
# 请求前缀
context-path: /dev-api
# application-prod.yaml
server:
servlet:
# 请求前缀
context-path: /prod-api
自定义配置读取
@Component
@ConfigurationProperties(prefix = "book")
public class BookConfig {
private String name;
private String author;
// get,set,tostring
}
// 使用
@Autowired
BookConfig bookConfig;
整合 Thymeleaf
<!--pom.xml中-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
spring:
# thymeleaf 配置
thymeleaf:
# 是否开启缓存,开发时可设置为false,默认true
cache: true
# 检查模板是否存在,默认true
check-template: true
# 检查模板位置是否存在,默认true
check-template-location: true
# 模板文件编码
encoding: UTF-8
# 模板位置
prefix: classpath:/templates/
# Content-Type 配置
servlet:
content-type: text/html
# 模板文件后缀
suffix: .html
// 新建 User
public class User {
private Integer id;
private String username;
private String password;
// get,set
}
// Controller
@GetMapping("/users")
public ModelAndView users(){
List<User> users = new ArrayList<>();
User u = new User(1,"搜索","123455");
User u1 = new User(2,"刚刚","321123");
User u2 = new User(3,"哈哈","555551");
users.add(u);
users.add(u1);
users.add(u2);
ModelAndView mv = new ModelAndView();
mv.addObject("users",users);
mv.setViewName("users");
return mv;
}
<!--resources/templates/users.html 新建文件-->
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<div th:each="user:${users}">
<span th:text="${user.id}"></span>
<span th:text="${user.username}"></span>
<span th:text="${user.password}"></span>
</div>
</div>
</body>
</html>
整合 FreeMarker
<!--pom.xml中-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
spring:
freemarker:
# HttpServletRequest 的属性是否可以覆盖 controller 中的 model 的同明项
allow-request-override: false
# HttpSession 的属性是否可以覆盖 controller 中的 model 的同明项
allow-session-override: false
# 是否开启缓存,开发时可设置为false,默认true
cache: false
# 模板文件编码
charset: UTF-8
# 检查模板位置是否存在,默认true
check-template-location: true
# Content-Type 配置
content-type: text/html
# HttpServletRequest 的属性是否添加到 model
expose-request-attributes: false
# HttpSession 的属性是否添加到 model
expose-session-attributes: false
# 模板文件后缀
suffix: .ftl
# 模板位置
template-loader-path: classpath:/templates/
// Controller 同上
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<#if users ??&& (users?size>0)>
<#list users as user>
<span>${user.id}</span>
<span>${user.username}</span>
<span>${user.password}</span>
</#list>
</#if>
</div>
</body>
</html>
整合 Web 开发
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
返回JSON
1.这个依赖默认加入了 json 处理器
在方法上加注解 @ResponseBody 或 在类上使用 @ResponseController
@ResponseController 等同于 @ResponseBody @Controller
2. 自定义json处理器
Gson
fastjson
静态访问
- 在 resources/static 新建文件夹下面放静态文件
- 自定义静态文件策略
spring:
mvc:
static-path-pattern: /static/**
resources:
static-locations: classpath:/static/
单文件上传
# yaml 配置
spring:
servlet:
multipart:
# 单文件上传最大
max-file-size: 10MB
# 多文件上传最大
max-request-size: 100MB
<!--upload.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单文件上传</title>
</head>
<body>
<form action="/dev-api/upload" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile" value="选择文件" />
<input type="submit" value="上传" />
</form>
</body>
</html>
@RestController
public class FileUploadController {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
private String uploadPath = "/target/classes/static/uploadFile/";
@PostMapping("/upload")
public String upload(MultipartFile uploadFile, HttpServletRequest req) {
String realPath = System.getProperty("user.dir")+uploadPath;
String format = sdf.format(new Date());
File folder = new File(realPath + format);
System.out.println(folder.isDirectory());
if (!folder.isDirectory()) {
folder.mkdirs();
}
String oldName = uploadFile.getOriginalFilename();
String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."), oldName.length());
try {
uploadFile.transferTo(new File(folder, newName));
String filePath = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/dev-api/static/uploadFile/" + format + newName;
return filePath;
} catch (IOException e) {
e.printStackTrace();
}
return "失败";
}
}
多文件上传
<!--uploads.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>多文件上传</title>
</head>
<body>
<form action="/dev-api/uploads" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFiles" value="选择文件" multiple/>
<input type="submit" value="上传" />
</form>
</body>
</html>
@PostMapping("/uploads")
public List<String> uploads(MultipartFile[] uploadFiles, HttpServletRequest req) {
List<String> strings = new ArrayList<>();
for (MultipartFile uploadFile : uploadFiles) {
strings.add(this.upload(uploadFile, req)); // 调用单文件上传
}
return strings;
}
全局异常处理
@ControllerAdvice
public class CustomExceptionHandler {
@ExceptionHandler(MaxUploadSizeExceededException.class)
public void upload(MaxUploadSizeExceededException e, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("上传文件大小限制");
out.flush();
out.close();
}
}
全局数据
@ControllerAdvice
public class GlobalConfig {
@ModelAttribute(value = "info")
public Map<String,String> userInfo(){
HashMap<String,String> map = new HashMap<>();
map.put("id","0");
map.put("ids","01");
return map;
}
}
@GetMapping("/hello")
public String hello(Model model){
Map<String,Object> map = model.asMap();
Map<String,Object> maps = model.asMap();
Set<String> ket = map.keySet();
Iterator<String> its = ket.iterator();
Map s = null;
while (its.hasNext()){
String k = its.next();
Object v = map.get(k);
if (k.equals("info")){
s = (Map) v;
}
}
return (String) s.get("id");
}
请求参数预处理
/ccc?u.id=1&b.id=9
@GetMapping("/ccc")
public String ccc(@ModelAttribute("u") User user,@ModelAttribute("b") Bian bian){
return user.toString()+">>"+bian.toString();
}
@ControllerAdvice
public class GlobalConfig {
@InitBinder("u")
public void init(WebDataBinder webDataBinder){
webDataBinder.setFieldDefaultPrefix("u.");
}
@InitBinder("b")
public void init2(WebDataBinder webDataBinder){
webDataBinder.setFieldDefaultPrefix("b.");
}
}
错误页
1.在 resources/static 下新建error
2. 自定义 error数据
@Component
public class MyErrorAttribute extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
Map<String,Object> errorAttr = super.getErrorAttributes(webRequest,options);
errorAttr.put("zdy","错误了");
errorAttr.remove("error");
return errorAttr;
}
}
- 自定义视图
@Component
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
ModelAndView mv = new ModelAndView("errorPage");
mv.addObject("zdy","错误了");
mv.addAllObjects(model);
return mv;
}
}
<!--resources/templates/errorPage.html-->
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>error</title>
</head>
<body>
<div>
自定义视图
<div>timestamp: <span th:text="${timestamp}"></span></div>
<div>status: <span th:text="${status}"></span></div>
<div>error: <span th:text="${error}"></span></div>
<div>messages: <span th:text="${#messages}"></span></div>
<div>path: <span th:text="${path}"></span></div>
<div>zdy: <span th:text="${zdy}"></span></div>
</div>
</body>
</html>
- 完全自定义 (包含2,3)
@Controller
public class MyErrorController extends BasicErrorController {
@Autowired
public MyErrorController(ErrorAttributes errorAttributes, ServerProperties serverProperties,List<ErrorViewResolver> errorViewResolvers) {
super(errorAttributes, serverProperties.getError(),errorViewResolvers);
}
@Override
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
HttpStatus status = getStatus(request);
Map<String,Object> model = getErrorAttributes(request,isIncludeStackTrace(request, MediaType.TEXT_HTML));
model.put("zdy","错误了???????");
ModelAndView modelAndView = new ModelAndView("errorPage",model,status);
return modelAndView;
}
@Override
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map<String,Object> body = getErrorAttributes(request,isIncludeStackTrace(request,MediaType.ALL));
body.put("zdy","错误了?????123123??");
HttpStatus status = getStatus(request);
return new ResponseEntity<>(body,status);
}
}
CORS 支持
Controller 类加注解 @CrossOrigin
xml 配置
public class Hello {
public String sayHellos(String name){
return "hellos "+name;
}
}
<!--resources/beans.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.Hello" id="hello"></bean>
</beans>
@Autowired
Hello hello;
@GetMapping("/beans")
public String beans(){
return hello.sayHellos("啊啊啊啊啊");
}
拦截器
public class MyInterceptor1 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor1---preHandle");
return true; // true 才会往下执行
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor1---postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor1---afterCompletion");
}
}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor1())
.addPathPatterns("/**") // 拦截的路径
.excludePathPatterns("/hello"); // 排除路径
}
}
启动系统任务
- CommandLineRunner
启动任务是加入
123 3565 999
@Component
@Order(1) // 执行顺序
public class MyCommandLineRunner2 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("MyCommandLineRunner2---"+ Arrays.toString(args));
}
}
@Component
@Order(2) // 执行顺序
public class MyCommandLineRunner1 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("MyCommandLineRunner1---"+ Arrays.toString(args));
}
}
- ApplicationRunner
启动任务是加入
–a=a --b=b 123 3565 999
@Component
@Order(1)
public class MyApplicationRunner2 implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
List<String> nonOptionArgs = args.getNonOptionArgs();
System.out.println("2-nonOptionArgs"+nonOptionArgs);
Set<String> optionsNames = args.getOptionNames();
for (String optionsName : optionsNames){
System.out.println("2-key:"+optionsName+";value:"+args.getOptionValues(optionsName));
}
}
}
@Component
@Order(2)
public class MyApplicationRunner1 implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
List<String> nonOptionArgs = args.getNonOptionArgs();
System.out.println("1-nonOptionArgs"+nonOptionArgs);
Set<String> optionsNames = args.getOptionNames();
for (String optionsName : optionsNames){
System.out.println("1-key:"+optionsName+";value:"+args.getOptionValues(optionsName));
}
}
}
整合 Servlet Filter Listener
// 启动类上加注解
@ServletComponentScan
@WebServlet("/my")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("name>>>>>"+req.getParameter("name"));
}
}
@WebFilter("/*")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("MyFilter>>init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("MyFilter>>doFilter");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
System.out.println("MyFilter>>destroy");
}
}
@WebListener
public class MyListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("MyListener>>>>>requestDestroyed");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("MyListener>>>>>requestInitialized");
}
}
路径映射
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/sun").setViewName("999"); // 第一个:路径 第二个:模板
}
}
<!--resources/templates/999.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
999999
</body>
</html>
配置 AOP
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
// service
@Service
public class UserService {
public List<User> users(User user){
List<User> users = new ArrayList<>();
users.add(user);
return users;
}
}
@Component
@Aspect
public class LogAspect {
@Pointcut("execution(* com.example.d1.service.*.*(..))")
public void pcl(){
}
@Before(value = "pcl()")
public void before(JoinPoint jp){
String name = jp.getSignature().getName();
System.out.println(name+"方法执行开始");
}
@After(value = "pcl()")
public void after(JoinPoint jp){
String name = jp.getSignature().getName();
System.out.println(name+"方法执行结束");
}
@AfterReturning(value = "pcl()",returning = "result")
public void afterReturning(JoinPoint jp,Object result){
String name = jp.getSignature().getName();
System.out.println(name+"方法返回值为:"+result);
}
@AfterThrowing(value = "pcl()",throwing = "e")
public void afterThrowing(JoinPoint jp,Exception e){
String name = jp.getSignature().getName();
System.out.println(name+"方法抛异常为:"+e.getMessage());
}
@Around("pcl()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return pjp.proceed();
}
}
@CrossOrigin
@RestController
public class UserController {
@Autowired
UserService userService;
@GetMapping("/ceshilog")
public List<User> getUserService() {
return userService.users(new User(1,"ceshi","9999"));
}
}
ico
在 resources/static/ 添加 favicon.ico
去除某个自动配置
启动类上添加注解 @EnableAutoConfiguration(exclude = {某个类.class})
持久层技术
JdbcTemplate
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency> <!--数据库驱动-->
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency><!-- 数据库连接池-->
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
# 数据库配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql:///ssm
username: root
password: 521314
public class Ccc {
private int id;
private String name;
private String author;
// get,set...
}
@Repository
public class CccDao {
@Autowired
JdbcTemplate jdbcTemplate;
public int addCcc(Ccc ccc){
return jdbcTemplate.update("INSERT INTO ccc(name,author) VALUES (?,?)",ccc.getName(),ccc.getAuthor());
}
public int updateCcc(Ccc ccc){
return jdbcTemplate.update("UPDATE ccc SET name =?,author=? WHERE id=?",ccc.getName(),ccc.getAuthor(),ccc.getId());
}
public int delCcc(int id){
return jdbcTemplate.update("DELETE FROM ccc WHERE id=?",id);
}
public Ccc getIdCcc(int id){
return jdbcTemplate.queryForObject("select * from ccc book where id=?",new BeanPropertyRowMapper<>(Ccc.class),id);
}
public List<Ccc> getCcc(int id){
return jdbcTemplate.query("select * from ccc",new BeanPropertyRowMapper<>(Ccc.class));
}
}
@Service
public class CccService {
@Autowired
CccDao cccDao;
public int addCcc(Ccc ccc){
return cccDao.addCcc(ccc);
}
public int updateCcc(Ccc ccc){
return cccDao.updateCcc(ccc);
}
public int delCcc(int id){
return cccDao.delCcc(id);
}
public Ccc getIdCcc(int id){
return cccDao.getIdCcc(id);
}
public List<Ccc> getCcc(){
return cccDao.getCcc();
}
}
@Autowired
CccService cccService;
@GetMapping("/ceshi")
public String indexs(){
System.out.println("添加:::"+cccService.addCcc(new Ccc("哈哈哈","发发撒顶起")));
System.out.println("修改:::"+cccService.updateCcc(new Ccc(1,"11111","gasfasfafa")));
System.out.println("删除:::"+cccService.delCcc(1));
System.out.println("id:::"+cccService.getIdCcc(2));
System.out.println("List:::"+cccService.getCcc());
return "999";
}
多数据源配置
spring:
datasource:
one:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql:///ssm
username: root
password: 521314
two:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql:///bk
username: root
password: 521314
// 根据配置生成两个数据源
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.one")
DataSource dsOne(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.two")
DataSource dsTwo(){
return DruidDataSourceBuilder.create().build();
}
}
// 配置jdbcTemplate
@Configuration
public class JdbcTemplateConfig {
@Bean
JdbcTemplate jdbcTemplateOne(@Qualifier("dsOne")DataSource dataSource){
return new JdbcTemplate(dataSource);
}
@Bean
JdbcTemplate jdbcTemplateTwo(@Qualifier("dsTwo")DataSource dataSource){
return new JdbcTemplate(dataSource);
}
}
// Dao 注入JdbcTemplate 时切换
@Resource(name = "jdbcTemplateTwo")
JdbcTemplate jdbcTemplate;
MyBatis
类/表与上面一样
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency> <!--mybatis-->
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency> <!--数据库驱动-->
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency><!-- 数据库连接池-->
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql:///ssm
username: root
password: 521314
mybatis:
mapper-locations: classpath:mapper/*.xml
@Mapper
public interface CccMapper {
int addCcc (Ccc ccc);
int updateCcc (Ccc ccc);
int delCcc (int id);
Ccc getIdCcc (int id);
List<Ccc> ListCcc ();
}
@Service
public class CccService {
@Autowired
CccMapper cccMapper;
public int addCcc(Ccc ccc){
return cccMapper.addCcc(ccc);
}
public int updateCcc(Ccc ccc){
return cccMapper.updateCcc(ccc);
}
public int delCcc(int id){
return cccMapper.delCcc(id);
}
public Ccc getIdCcc(int id){
return cccMapper.getIdCcc(id);
}
public List<Ccc> getCcc(){
return cccMapper.ListCcc();
}
}
@CrossOrigin
@RestController
public class CccController {
@Autowired
CccService cccService;
@GetMapping("/ceshilog")
public String cehsi() {
System.out.println("添加:::"+cccService.addCcc(new Ccc("哈哈哈","发发撒顶起")));
System.out.println("修改:::"+cccService.updateCcc(new Ccc(6,"11111","gasfasfafa")));
System.out.println("删除:::"+cccService.delCcc(2));
System.out.println("id:::"+cccService.getIdCcc(6));
System.out.println("List:::"+cccService.getCcc());
return "999";
}
}
<?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.example.d2.mapper.CccMapper">
<insert id="addCcc" parameterType="com.example.d2.Ccc">
insert into ccc(name,author) values (#{name},#{author})
</insert>
<update id="updateCcc" parameterType="com.example.d2.Ccc">
UPDATE ccc SET name =#{name},author=#{author} WHERE id=#{id}
</update>
<delete id="delCcc" parameterType="int">
DELETE FROM ccc WHERE id=#{id}
</delete>
<select id="getIdCcc" parameterType="int" resultType="com.example.d2.Ccc">
select * from ccc where id=#{id}
</select>
<select id="ListCcc" resultType="com.example.d2.Ccc">
select * from ccc
</select>
</mapper>
多数据源配置
spring:
datasource:
one:
type: com.alibaba.druid.pool.DruidDataSource
jdbc-url: jdbc:mysql:///ssm
username: root
password: 521314
two:
type: com.alibaba.druid.pool.DruidDataSource
jdbc-url: jdbc:mysql:///bk
username: root
password: 521314
@Configuration
@MapperScan(basePackages = "com.example.d2.mapper", sqlSessionFactoryRef = "OneSqlSessionFactory")//basePackages:接口文件的包路径
public class OneDataSourceConfig {
@Bean(name = "OneDataSource")
// 表示这个数据源是默认数据源
@Primary//这个一定要加,如果两个数据源都没有@Primary会报错
@ConfigurationProperties(prefix = "spring.datasource.one")//我们配置文件中的前缀
public DataSource getOneDateSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "OneSqlSessionFactory")
@Primary
public SqlSessionFactory OneSqlSessionFactory(@Qualifier("OneDataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath*:xml/mapper/CccMapper.xml"));
return bean.getObject();// 设置mybatis的xml所在位置
}
@Bean("OneSqlSessionTemplate")
// 表示这个数据源是默认数据源
@Primary
public SqlSessionTemplate OneSqlSessionTemplate(
@Qualifier("OneSqlSessionFactory") SqlSessionFactory sessionfactory) {
return new SqlSessionTemplate(sessionfactory);
}
}
@Configuration
@MapperScan(basePackages = "com.example.d2.mapperTwo", sqlSessionFactoryRef = "TwoSqlSessionFactory")
public class TwoDataSourceConfig {
@Bean(name = "TwoDataSource")
@ConfigurationProperties(prefix = "spring.datasource.two")
public DataSource getTwoDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "TwoSqlSessionFactory")
public SqlSessionFactory TwoSqlSessionFactory(@Qualifier("TwoDataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath*:xml/mapper/CccMapper2.xml"));
return bean.getObject();// 设置mybatis的xml所在位置
}
@Bean("TwoSqlSessionTemplate")
public SqlSessionTemplate TwoSqlSessionTemplate(
@Qualifier("TwoSqlSessionFactory") SqlSessionFactory sessionfactory) {
return new SqlSessionTemplate(sessionfactory);
}
}
@Mapper
public interface CccMapper {
int addCcc (Ccc ccc);
int updateCcc (Ccc ccc);
int delCcc (int id);
Ccc getIdCcc (int id);
List<Ccc> ListCcc ();
}
<?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.example.d2.mapper.CccMapper">
<insert id="addCcc" parameterType="com.example.d2.Ccc">
insert into ccc(name,author) values (#{
name},#{
author})
</insert>
<update id="updateCcc" parameterType="com.example.d2.Ccc">
UPDATE ccc SET name =#{
name},author=#{
author} WHERE id=#{
id}
</update>
<delete id="delCcc" parameterType="int">
DELETE FROM ccc WHERE id=#{
id}
</delete>
<select id="getIdCcc" parameterType="int" resultType="com.example.d2.Ccc">
select * from ccc where id=#{
id}
</select>
<select id="ListCcc" resultType="com.example.d2.Ccc">
select * from ccc
</select>
</mapper>
@Mapper
public interface CccMapper2 {
int addCcc (Ccc ccc);
int updateCcc (Ccc ccc);
int delCcc (int id);
Ccc getIdCcc (int id);
List<Ccc> ListCcc ();
}
<?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.example.d2.mapperTwo.CccMapper2">
<insert id="addCcc" parameterType="com.example.d2.Ccc">
insert into ccc(name,author) values (#{
name},#{
author})
</insert>
<update id="updateCcc" parameterType="com.example.d2.Ccc">
UPDATE ccc SET name =#{
name},author=#{
author} WHERE id=#{
id}
</update>
<delete id="delCcc" parameterType="int">
DELETE FROM ccc WHERE id=#{
id}
</delete>
<select id="getIdCcc" parameterType="int" resultType="com.example.d2.Ccc">
select * from ccc where id=#{
id}
</select>
<select id="ListCcc" resultType="com.example.d2.Ccc">
select * from ccc
</select>
</mapper>
@Service
public class CccService {
// @Autowired
// CccMapper cccMapper; // one 这个位置的切换
@Autowired
CccMapper2 cccMapper; // two 这个位置的切换
public int addCcc(Ccc ccc){
return cccMapper.addCcc(ccc);
}
public int updateCcc(Ccc ccc){
return cccMapper.updateCcc(ccc);
}
public int delCcc(int id){
return cccMapper.delCcc(id);
}
public Ccc getIdCcc(int id){
return cccMapper.getIdCcc(id);
}
public List<Ccc> getCcc(){
return cccMapper.ListCcc();
}
}
@CrossOrigin
@RestController
public class CccController {
@Autowired
CccService cccService;
@GetMapping("/ceshilog")
public String cehsi() {
System.out.println("添加:::"+cccService.addCcc(new Ccc("哈哈哈","发发撒顶起")));
System.out.println("List:::"+cccService.getCcc());
return "999";
}
}
Spring Data JPA
新建数据库 demo
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<!--排除springboot2默认的数据源HikariCP,使用druid连接池-->
<exclusions>
<exclusion>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</exclusion>
</exclusions>
</dependency>
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
username: root
password: 521314
type: com.alibaba.druid.pool.DruidDataSource
jpa:
show-sql: true
database: mysql
hibernate:
ddl-auto: update
server:
port: 9090
//Book
@Entity(name = "s_book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "book_name",nullable = false)
private String name;
@Transient // 生成数据库表时,不生成该字段
private String ooo;
// ...set,get
}
//BookDao
public interface BookDao extends JpaRepository<Book,Integer> {
List<Book> getBooksByNameContaining(String name);
@Query(value = "select * from s_book where id=(select max(id) from s_book)",nativeQuery = true)
Book getMaxIdBook();
@Query(value = "select * from s_book where id>:id",nativeQuery = true)
List<Book> getBookById(@Param("id") Integer id);
}
//BookService
@Service
public class BookService {
@Autowired
BookDao bookDao;
public Book getMaxIdBook(){
return bookDao.getMaxIdBook();
}
public List<Book> getBookById(Integer id){
return bookDao.getBookById(id);
}
}
//BookController
@CrossOrigin
@RestController
public class BookController {
@Autowired
BookService bookService;
@GetMapping("/")
public String index(){
System.out.println("getMaxIdBook:::"+bookService.getMaxIdBook());
System.out.println("getBookById:::"+bookService.getBookById(1));
return "99";
}
}
多数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
primary:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
username: root
password: 521314
secondary:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/bk?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
username: root
password: 521314
jpa:
show-sql: true
database: mysql
hibernate:
ddl-auto: update
server:
port: 9090
//DataSourceConfig
/**
* 数据库配置
*/
@Configuration
public class DataSourceConfig {
@Primary
@Bean(value = "primaryDataSource")
@ConfigurationProperties("spring.datasource.primary") //标红为yml文件中数据源路径:primary
public DataSource dataSourceOne(){
return DruidDataSourceBuilder.create().build();
}
@Bean(value = "secondDataSource")
@ConfigurationProperties("spring.datasource.secondary")//标红为yml文件中数据源路径:secondary
public DataSource dataSourceTwo(){
return DruidDataSourceBuilder.create().build();
}
}
//PrimaryJpaConfig
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryPrimary",
transactionManagerRef = "transactionManagerPrimary",
basePackages = {
"com.example.d3.one"}) //设置Repository所在位置
public class PrimaryJpaConfig {
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@Primary
@Bean(name = "entityManagerPrimary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
@Primary
@Bean(name = "entityManagerFactoryPrimary")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(primaryDataSource)// 设置数据源
.properties(jpaProperties.getProperties())// 设置jpa配置
.properties(getVendorProperties())// 设置hibernate配置
.packages("com.example.d3.etwo") //设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")// 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
.build();
}
private Map getVendorProperties() {
return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
}
@Primary
@Bean(name = "transactionManagerPrimary")
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
//SecondJpaConfig
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactorySecond",
transactionManagerRef = "transactionManagerSecond",
basePackages = {
"com.example.d3.two"}) //设置Repository所在位置
public class SecondJpaConfig {
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
@Autowired
@Qualifier("secondDataSource")
private DataSource secondDataSource;
@Bean(name = "secondEntityManager")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySecond(builder).getObject().createEntityManager();
}
@Bean(name = "entityManagerFactorySecond")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecond(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(secondDataSource)
.properties(jpaProperties.getProperties())// 设置jpa配置
.properties(getVendorProperties())
.packages("com.example.d3.etwo") //设置实体类所在位置
.persistenceUnit("secondPersistenceUnit")
.build();
}
private Map getVendorProperties() {
return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
}
@Bean(name = "transactionManagerSecond")
public PlatformTransactionManager transactionManagerSecond(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecond(builder).getObject());
}
}
//BookService
@Service
public class BookService {
@Autowired
BookDao bookDao; // 这个位置切换数据源
public Book getMaxIdBook(){
return bookDao.getMaxIdBook();
}
public List<Book> getBookById(Integer id){
return bookDao.getBookById(id);
}
}
整合 redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
spring:
redis:
# redis 库编号 0-15
database: 0
# ip
host: 192.168.75.129
# 端口号
port: 6379
# 密码
password: 123456
jedis:
pool:
# 最大连接数
max-active: 8
# 最大空闲连接数
max-idle: 8
# 最大阻塞等待时间 -1 表示没有限制
max-wait: -1ms
# 最小空闲连接数
min-idle: 0
public class Book implements Serializable {
private Integer id;
private String name;
private String ooo;
// get / set
}
@Autowired
RedisTemplate redisTemplate;
@Autowired
StringRedisTemplate stringRedisTemplate;
@GetMapping("/redis")
public String Redis(){
ValueOperations<String,String> opsl = stringRedisTemplate.opsForValue();
opsl.set("id","1");
System.out.println(opsl.get("id"));
ValueOperations ops2 = redisTemplate.opsForValue();
Book b = new Book();
b.setId(1);
b.setName("测名称");
b.setOoo("sadasdasd");
ops2.set("book",b);
Book bd = (Book) ops2.get("book");
System.out.println(bd);
return "99";
}
整合 MongoDB
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
spring:
data:
mongodb:
authentication-database: admin
database: admin
host: 192.168.75.129
port: 27017
username: guoguo
password: 123456
public class Book implements Serializable {
private Integer id;
private String name;
private String ooo;
// get / set
}
public interface BookMongoDB extends MongoRepository<Book,Integer> {
List<Book> findByNameContains(String name);
Book findByNameEquals(String name);
}
@Autowired
BookMongoDB mongoDB;
@GetMapping("/mongodb")
public String mongodb(){
List<Book> books = new ArrayList<>();
Book b1 = new Book();
b1.setOoo("000");
b1.setName("名称1");
b1.setId(1);
Book b2 = new Book();
b2.setOoo("22222");
b2.setName("名称2");
b2.setId(2);
books.add(b1);
books.add(b2);
mongoDB.insert(books);
System.out.println(mongoDB.findByNameContains("1"));
System.out.println(mongoDB.findByNameEquals("名称2"));
return "99";
}
Session 共享
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
spring:
redis:
# redis 库编号 0-15
database: 0
# ip
host: 192.168.75.129
# 端口号
port: 6379
# 密码
password: 123456
jedis:
pool:
# 最大连接数
max-active: 8
# 最大空闲连接数
max-idle: 8
# 最大阻塞等待时间 -1 表示没有限制
max-wait: -1ms
# 最小空闲连接数
min-idle: 0
server:
port: 9091
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400 * 30)
public class SessionConfig {
}
/**
* session共享测试controller
* 启动两个服务,端口为9090的服务设置session,端口为9091的服务来获取session,测试是否能够获取,实现session共享
*/
@RestController
@RequestMapping("/session")
public class SessionController {
@Value("${server.port}")
private Integer port;
@GetMapping("/set")
public String set(HttpSession session) {
session.setAttribute("username", "test");
return String.valueOf(port);
}
@GetMapping("/get")
public String get(HttpSession session) {
String username = (String) session.getAttribute("username");
return username + ":" + port;
}
}
JPA REST
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--jpa依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--rest依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
spring:
data:
rest:
# 每页查询记录数
default-page-size: 20
# 分页查询页码参数名
page-param-name: page
# 分页查询记录数参数名
limit-param-name: size
# 分页查询排序参数名
sort-param-name: sort
# 所有请求加上前缀
base-path: /api
# 添加成功是否返回添加内容
return-body-on-create: true
# 修改成功是否返回修改内容
return-body-on-update: true
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/bk?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
username: root
password: 521314
jpa:
show-sql: true
database: mysql
hibernate:
ddl-auto: update
server:
port: 9090
@Entity(name = "s_book")
public class Book implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "book_name",nullable = false)
private String name;
@Transient // 生成数据库表时,不生成该字段
private String ooo;
// get set
}
public interface BookRepository extends JpaRepository<Book,Integer> {
}
get http://localhost:9090/books 查询全部
page=1 size=3 sort=id,desc 第二页 三条记录 id倒叙
get http://localhost:9090/books/1 根据id查询
post http://localhost:9090/books 新增
put http://localhost:9090/books 修改
delete http://localhost:9090/books/1 根据id删除
@CrossOrigin // cors
// 自定义路径
@RepositoryRestResource(path = "bs",collectionResourceRel = "bs",itemResourceRel = "b")//exported = true 暴露出来,false不暴露
public interface BookRepository extends JpaRepository<Book,Integer> {
//自定义查询方法
// http://localhost:9090/bs/search/name?name=a
@RestResource(path = "name",rel = "name",exported = true) //exported = true 暴露出来,false不暴露
List<Book> findByNameContaining(@Param("name")String name);
}
devtools
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
# Idea 需要配置
# devtools 默认不会监听静态文件
# 按 ctrl + shift + alt + /
spring:
devtools:
restart:
# 是否关闭自动重启
enabled: false
缓存
Ehcache 2.x 缓存
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
// Book
public class Book implements Serializable {
private Integer id;
private String name;
private String ooo;
private String uuu;
// get/set/tostring
}
// BookDao
@Repository
@CacheConfig(cacheNames = "book_cache") // 缓存名称
public class BookDao {
@Cacheable
public Book getBookById(Integer id){
System.out.println("getBookById");
Book b = new Book();
b.setId(id);
b.setName("999as十大");
b.setOoo("1232");
return b;
}
@CachePut(key = "#book.id")
public Book updateBookById(Book book){
System.out.println("updateBookById");
book.setOoo("oooooooooo");
return book;
}
@CacheEvict(key = "#id")
public void delBookById(Integer id){
System.out.println("delBookById");
}
}
// 启动类上添加
@EnableCaching // 开启缓存
spring:
cache:
ehcache:
config: classpath:ehcache.xml # 重命名缓存配置文件位置
<!--ehcache.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<!--
diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
user.home – 用户主目录
user.dir – 用户当前工作目录
java.io.tmpdir – 默认临时文件路径
-->
<diskStore path="java.io.tmpdir/cache"/>
<!--
defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
-->
<!--
name:缓存名称。
maxElementsInMemory:缓存最大数目
maxElementsOnDisk:硬盘最大缓存个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
overflowToDisk:是否保存到磁盘,当系统当机时
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
FIFO,first in first out,这个是大家最熟的,先进先出。
LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
-->
<defaultCache
eternal="false"
maxElementsInMemory="10000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"/>
<cache
name="book_cache"
eternal="true"
maxElementsInMemory="10000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="600"/>
</ehcache>
@Autowired
BookDao bookDao;
@Test
void contextLoads() {
bookDao.getBookById(1);
bookDao.getBookById(1);
bookDao.delBookById(1);
Book b3 = bookDao.getBookById(1);
System.out.println("b3:"+b3);
Book b = new Book();
b.setOoo("妗?);
b.setName("鍐滄潙");
b.setId(1);
bookDao.updateBookById(b);
Book b4 = bookDao.getBookById(1);
System.out.println("b4--"+b4);
}