第十三章 SpringBoot项目(总)

1.创建SpringBoot项目

1.1.设置编码

 1.4.导入已有的spring boot项目

2.快速搭建Restfull风格的项目

2.1.返回字符串

@RestController
public class IndexController {@RequestMapping("/demo1")public Object demo1() {System.out.println("demo1 ran....");System.out.println("demo1 ran%^*^&*)*(_*(*&)(&&*()&()");return "hello world!";}
}

效果:

控制台:

 2.2.返回自定义对象

@RequestMapping("/demo2/{userId}/{userName}")public Object demo2(@PathVariable("userId") Integer userId, @PathVariable("userName") String userName) {System.out.println("demo2 ran...");User user = new User();user.setUserId(userId);user.setUserName(userName);user.setUserDate(new Date());return user; }

时间的配置,在属性文件中application.properties中

# 配置时间输出的pattern
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss   
# 配置时区
spring.jackson.time-zone=Asia/Chongqing

2.3.lombok.jar的引用

        在pom.xml文件中添加

<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>

去本地库,执行lombok.jar
 执行方式一:在路径哪里点一下,地址会有背景色,无需删除,直接键入cmd


在DOS命令行输入:java -jar jar 包的名字,我们可输入:java -jar lombok-1.18.12.jar
按照想到扫描到你本地的开发软件,点击“Install/Update",安装成功后,点击"Quir Installer",完成安装,重启eclipse生效
生效

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Emp {private Integer empId;private String empName;private Date hiredate;
}

返回Map

@RequestMapping("/demo3")public Object demo3(@RequestParam(value="userName", defaultValue="老王") String userName) {Map<String, Object> map = new HashMap<String, Object>();List<Emp> empList = new ArrayList<Emp>();empList.add(new Emp(1001, "张三", new Date()));empList.add(new Emp(1002, "李四", new Date()));map.put("empList", empList);User user = new User();user.setUserId(11);user.setUserName(userName);// 对日期做个处理Calendar cal = Calendar.getInstance(); // 获得日历类cal.set(Calendar.YEAR, 1984);cal.set(Calendar.MONTH, 5);cal.set(Calendar.DATE, 28);user.setUserDate(cal.getTime());map.put("user", user);map.put("money", 888888888);return map;}

2.4.打包

        有一个要求,运行环境不能只是jre,要上到jdk

打包之前需要关闭服务,打包命令:clean package,先如图方式倒灶弹窗

看到如下图表示成功了

测试

3.Properties和YML(YAML)

3.1.application属性文件优先级

        优先级高的会覆盖优先级低的,优先级高低如下
                当前目录系的一个/config子目录
                当前目录
                classpath下的/config子目录
                classpath对应的root根路径

3.2.创建的几个配置 

# 配置时间输出的pattern
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss   
# 配置时区
spring.jackson.time-zone=Asia/Chongqing# 配置服务绑定的端口
server.port=8081# 配置站点根目录
server.servlet.context-path=/sd1.1

3.3 配置随机值

# 32位的随机字符串
my.msg=${random.value}
# 随机整数(100以内的)
my.num=${random.int(100)}
# 随机整数(10到100之间)
my.num.range=${random.int[10,100]}

如何在后代代码访问属性文件中定义好的随机值

    @Value(value="${my.msg}")private String msg;@Value(value="${my.num}")private Integer num;@Value(value="${my.num.range}")private Integer range;// 读取时:使用注解 @Value(value=”${my.msg}”)
@RequestMapping("/demo4")
public Object demo4() {Map<String, Object> map = new HashMap<String, Object>();map.put("msg", msg);map.put("num", num);map.put("range", range);return map;
}

另一种读取属性文件中值的方式
 

// 先做一个配置类:说明从那个属性文件中,映射哪几个值
@Configuration
@ConfigurationProperties(prefix="my")
@PropertySource(value={"classpath:/application.properties"})
@Data
public class ConfigBean {private Integer num;private String name;private String engname;
}//要在XXXXAppliction这个入口类上写一个注解进行注册
@EnableConfigurationProperties(value={ConfigBean.class})
public class SpringbootDemo11Application {
}//在使用的某个Controller类中,先注入,在使用
@RequestMapping("/demo5")
public Object demo5() throws UnsupportedEncodingException {System.out.println("demo5 ran...");Map<String, Object> map = new HashMap<String, Object>();map.put("name", new String(configBean.getName().getBytes("ISO-8859-1"), "utf-8"));map.put("engname", configBean.getEngname());map.put("num", configBean.getNum());return map;
}@Autowired
private ConfigBean configBean;

4.环境配置

4.1.多环境配置的好处

        不同网络环境配置可以配置不同的参数,编译部署,提高效率和减少出错。

4.2.properties多环境配置

        配置激活选项
                spring.profiles.active=dev
        要分别添加不同网环境的properties文件
                application-dev.properties
                application-test.properties
                application-prod.properties

4.3.YML多环境配置

// 配置激活选项
spring: profiles: active: dev
// 在yml文件中添加三个英文状态下的短横线区分的块
---
spring: profiles: dev 

4.4.两种配置方式的比较

        properties文件配置多环境,需要添加多个文件,yml配置多环境,只需要一个文件
        书写格式上:yml相对简洁、优雅、层次清晰

4.5.打包后切换环境的命令

        java -jar springboot-demo-2-2-0.01-SNAPAHOT.jar -- spring.profiles.active=prod

5.日志配置

        springboot项目也支持日志框架:logback、Java Util Logging、log4j2,默认使用logback

5.1.引用外部配置文件

5.1.1.logback配置方式

SpringBOOT会默认加载classpath:logback-spring.xml,在配置文件中记得加上一个配置日志文件的语句:如果properties文件,写法是:logging.config=classpath:logback-my.xml,如果是yml文件写法是:
logging:
        config:classpath:logback-my.xml

5.1.2.log4j2配置

        首先移除logback的依赖,然后添加log4j2的依赖
移除

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 移除默认的logback依赖 --><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency>

添加

<!-- 添加log4j2依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

如果需要第三方依赖,参考:mvnrepository.com

5.2.比较

        性能:logback和log4j2都比log4j要好(不推荐使用log4j)
        配置方式:logback方式更加简洁
        推荐:使用logback方式,Spring Boot默认。

6.Web应用开发—模板引擎

        Spring Boot的Web应用开发,是基于Spring MVC的。

6.1.SpringBoot特性

        SpringBoot在Spring默认的基础上,自动配置添加了以下的特性:包含了ContentNegotiatingViewResolver和BeanNameViewResolver;对静态资源的支持,包括对WebJars的支持;自动注册Converter、GenericConverter、Formatter;对HttpMessageConverters的支持;自动注册MessageCodeResolver;对静态index.html的支持;对自定义的favicon的支持;对自定义的banner的支持;主动使用ConfigurableWebBindingInitializer。

6.2.模板引擎的选择

        Freemarker;Thymeleaf;Groovy;Mustache
        注意:尽量不要使用jsp
        原因:jsp只能打war报,不支持jar,需要单独部署(tomcat);内嵌的Jetty不支持jsp;Undertow不支持jsp;jsp中的自定义错误页面不能覆盖SpringBoot默认的错误页的。

7.Web应用开发—模板引擎之ThyMeleaf

7.1.引入ThyMeleaf依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

7.2.添加Thymeleaf的相关配置

spring: thymeleaf:cache: false      # 不使用缓存suffix: .html     # 静态页面的后缀encoding: utf-8   # 页面编码mvc: static-path-pattern: /static/**     # 配置静态资源路径

        在thymeleaf页面中要访问不同域的数据,写法如下:
 

// 后台代码封装数据:model.addAttribute(“name1”, “val1”);session.setAttribute(“name2”, “val2”);
application.setAttribute(“name2”, “val2”);
// 前台代码获取数据${“name1”}        	//  能够获得 val1${“name2”}			//  什么也获得不到,因为域不对${“session.name2”}	//  能够获得val2
${“application.name3”} 	// 能够获得val3

8.Web应用开发—模板引擎之FreeMarker

8.1.引入FreeMarker的依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

8.2.在配置文件中加入freemarker的相关配置

spring:freemarker:                                     # 配置freemarker的相关信息suffix: .ftl                                  # 配置模板后缀template-loader-path: classpath:/templates/   # 设置ftl文件路径cache: false                                  # 设置页面不缓存content-type: text/html                       # 设置文档类型charset: utf-8                                # 设置页面编码格式 request-context-attribute: rc                 # 设置站点根目录属性 这样设置以后,如果ftl页面要获取站点根目录,可以使用${rc.contextPaht}

9.Web应用开发—JSP

9.1.使用模板引擎jsp的依赖

<!-- Jsp模板引擎需要的两个依赖  start -->
<dependency><groupId>org.apache.tomcat.embed</groupId><artictId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId>
</dependency>
<!-- Jsp模板引擎需要的两个依赖  end -->		

9.2.添加配置参数

spring:mvc: view: prefix: /WEB-INF/templates/suffix: .jsp

9.3.入口类改写

@SpringBootApplication
public class SpringbootDemo33Application extends SpringBootServletInitializer{@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder application) {return application.sources(SpringbootDemo33Application.class);}public static void main(String[] args) {SpringApplication.run(SpringbootDemo33Application.class, args);}}

9.4.项目结构 ​​​

 9.5.jsp页面编写

<head><meta charset="UTF-8"><title>Insert title here</title><script type="text/javascript" src="${pageContext.request.contextPath }/webjars/jquery/3.2.1/dist/jquery.min.js"></script><script type="text/javascript" src="${pageContext.request.contextPath }/webjars/bootstrap/4.3.1/js/bootstrap.min.js"></script><link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath }/webjars/bootstrap/4.3.1/css/bootstrap.min.css" /><script type="text/javascript">$(function(){alert("测试!");});
</script><link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath }/static/css/common.css" />
</head>
<body class="bodybk">测试<br><c:url value="https://www.baidu.com" var="百度" /><a href="${百度}">去百度</a><spring:url value="https://www.sina.com.cn" var="新浪" /><a href="${新浪}">去新浪</a><br><spring:url value="&lt;hello&gt;" htmlEscape="true" var="测试用" /><h3>${测试用 }</h3><img src="${pageContext.request.contextPath }/static/imgs/a.png">
</body>

10.Web应用开发—错误处理

10.1.错误处理方式一

        SpringBoot会将所用的错误默认映射到/error。所以,我们可以自定义一个错误处理的Controller,让他实现ErrorController并配置他的访问路径是/error即可
 

@Controller
@RequestMapping("/error")
public class BaseErrorController implements ErrorController {private static final Logger LOG = LoggerFactory.getLogger(BaseErrorController.class);@Overridepublic String getErrorPath() {LOG.info("出错了!进入自定义错误控制器。");return "error/error";}@RequestMapping()public String error() {return getErrorPath();}}

        错误页的层级

 10.2.错误处理方式二—添加自定义的错误页面

        html静态页面:在resources/public/error/下定义一个404.html页面
        模板引擎页面:在templates/error下定义一个5xx.html页面

10.3.错误处理方式三

        定义一个处理错误的Handler类,使用注解@ControllerAdvice

@ControllerAdvice
public class MyErrorHandler {private static final Logger LOG = LoggerFactory.getLogger(MyErrorHandler.class);@ExceptionHandler({RuntimeException.class})@ResponseStatus(HttpStatus.OK)public ModelAndView processException(RuntimeException e) {LOG.info("自定义异常处理-RuntimeException!");ModelAndView mav = new ModelAndView();mav.addObject("myException", e.getMessage());mav.setViewName("error/500");return mav;}@ExceptionHandler({Exception.class})
@ResponseStatus(HttpStatus.OK)public String processException(Model model, Exception e) {LOG.info("统一异常处理-Exception!");model.addAttribute("myException", e.getMessage());return "error/500";}}

错误处理页在项目中的层级:

 错误处理页的内容(带上后台抛过来的信息)
我是错误页-错误信息是:<font size="20px" th:text="${myException}"></font>

11.Web应用开发Servlert、Filter、Listener

        Web开发中,我们使用Controller基本上可以完成大部分需求,三实我们还可能会用到Servlet、Filter、Listener

11.1SpringBoot中的三种实现方式

        方式一:通过注册。ServletRegistrationBean、FiterRegistrationBean、ServletListenerRegistrationBean来获取控制。
        Servlet的使用

public class AServlet extends HttpServlet{private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("a servlet get method ran...");doPost(req, resp);
}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("a servlet post method ran...");resp.getWriter().print("hello world, I'm servlet A.");}}// 在程序启动类中注册Aservlet
@Bean
public ServletRegistrationBean<AServlet> aServletRegistrationBean() {return new ServletRegistrationBean<AServlet>(new AServlet(), "/a");
}

         Filter的使用

public class MyFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {System.out.println("放行!"); chain.doFilter(request, response);}}// 在入口类中注册
@Bean
public FilterRegistrationBean<MyFilter> myFilterRegistrationBean() {return new FilterRegistrationBean<MyFilter>(new MyFilter(),aServletRegistrationBean());
}

Listener

public class MyListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("应用初始化。。。");}@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("应用销毁。");}}//注册:
@Bean
public ServletListenerRegistrationBean<MyListener> myServletListenerRegistrationBean(){return new ServletListenerRegistrationBean<MyListener>(new MyListener());
}

        方式二:(推荐)在入口类上添加一个注解@ServletComponentScan后,直接扫描带有@WebServlet、@WebFilter、@WebListener注解的组件镜像注册

//在入口类上添加注解
@SpringBootApplication
@ServletComponentScan
public class SpringbootDemo31Application{public static void main(String[] args) {SpringApplication.run(SpringbootDemo31Application.class, args);}}//在各个组件上添加注解等待扫描
@WebServlet(urlPatterns = "/a", name="aServlet")
public class AServlet extends HttpServlet{@WebServlet(urlPatterns = "/b", name = "bServlet")
public class BServlet extends HttpServlet{@WebFilter(urlPatterns = {"/*"})
public class MyFilter implements Filter {@WebListener
public class MyListener implements ServletContextListener {

        方式三:让入口类实现ServletContextInitializer接口的方式镜像注册

public class SpringbootDemo31Application implements ServletContextInitializer{public static void main(String[] args) {SpringApplication.run(SpringbootDemo31Application.class, args);}@Overridepublic void onStartup(ServletContext sc) throws ServletException {sc.addServlet("aServlet", new AServlet()).addMapping("/a");sc.addServlet("bServlet", new BServlet()).addMapping("/b");sc.addFilter("myFilter", new MyFilter()).addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST), true, new String[] {"aServlet", "bServlet"});sc.addListener(new MyListener());}}

12.SpringBoot中的文件上传

12.1.SpringBoot默认使用SpringMVC包装好的解析器进行上传

12.2.表单代码

<form th:action="@{/file/upload}" method="POST"enctype="multipart/form-data">文件:<input type="file" name="myFile" /><br><input type="submit" value=" 上 传 " />
</form>

12.3.Controller代码

@RestController
@RequestMapping("/file")
@RestController
@RequestMapping("/file")
public class FileController {private static final Logger LOG = LoggerFactory.getLogger(FileController.class);@RequestMapping("upload")public String upload(@RequestParam("myFile") MultipartFile file) {if(file.isEmpty()) {return "未选择文件!";}// 获取文件名String fileName = file.getOriginalFilename();LOG.info("获取到前台传来的文件名是:" + fileName);// 获取文件的后缀名String suffixName = fileName.substring(fileName.lastIndexOf("."));LOG.info("上传文件的后缀名是:" + suffixName);// 指定文件上传路径String filePath = "D://tmp/";// 使用随机字符作为文件名称String newFileName = UUID.randomUUID().toString().replace("-", "");String fullFileName = filePath + newFileName + suffixName;LOG.info("上传文件路径全名称是:" + fullFileName);File dest = new File(fullFileName);// 检测是否存在父级目录if(!dest.getParentFile().exists()) {dest.getParentFile().mkdirs();}// 文件上传try {file.transferTo(dest);return "上传成功!";} catch(Exception e) {e.printStackTrace();System.err.println(e.getMessage());return "上传失败!";}}}

13.SpringBoot整合MyBatis

13.1.依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.2</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.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></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><dependency><groupId>org.webjars.bower</groupId><artifactId>jquery</artifactId><version>3.2.1</version></dependency><dependency><groupId>org.webjars</groupId><artifactId>bootstrap</artifactId><version>4.3.1</version></dependency></dependencies>

13.2.配置

spring:datasource:   # mysql数据库的配置信息driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost/mypro?&useSSL=false&serverTimezone=Asia/Chongqing&characterEncoding=utf8username: root
password: 123456mybatis: # 配置XXXXMapper.xml文件的路径mapper-locations: classpath:mybatis/**/*.xml 
//日志文件中加上一句配置:
<logger name="org.springframework.jdbc.core.JdbcTemplate" level="debug"/>

13.3.项目结构

13. 4.数据库表设计&实体类设计

实体类代码如下:

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
//	user_id	intprivate Integer userId;
//	user_name	varcharprivate String userName;
//	user_create_time	timestampprivate Date userCreateTime;
}

13.5.Mapper接口的编写

13.5.1.注解处理方式

        这种方式就不用在写XXXMapper.xml文件

@Mapper
public interface UserMapper {/*** 新添用户* @param user */@Insert(value = "insert into user(user_name, user_create_time) "+ "values(#{userName, jdbcType=VARCHAR}, #{userCreateTime, jdbcType=TIMESTAMP})")void insert(User user);/*** 根据id删除指定用户* @param userId*/@Delete(value = "delete from user where user_id = #{userId, jdbcType=INTEGER}")void deleteById(Integer userId);/*** 修改指定用户信息* @param user*/@Update(value = "update user set user_name = #{userName, jdbcType=VARCHAR}, "+ "user_create_time = #{userCreateTime, jdbcType=TIMESTAMP} "+ "where user_id = #{userId, jdbcType=INTEGER}")void update(User user);/*** 根据用户id查找用户* @param userId* @return*/@Select(value = "select * from user where user_id = #{userId, jdbcType=INTEGER}")@Results(value = {@Result(column="user_id", property="userId", jdbcType=JdbcType.INTEGER),@Result(column="user_name", property="userName", jdbcType=JdbcType.VARCHAR),@Result(column="user_create_time", property="userCreateTime", jdbcType=JdbcType.TIMESTAMP)})User selectById(Integer userId);/*** 查全部* @return*/@Select(value = "select * from user")@Results(value = {@Result(column="user_id", property="userId", jdbcType=JdbcType.INTEGER),@Result(column="user_name", property="userName", jdbcType=JdbcType.VARCHAR),@Result(column="user_create_time", property="userCreateTime", jdbcType=JdbcType.TIMESTAMP)})List<User> selectAll();
}
测试:
@Autowiredprivate UserMapper userMapper;@Testpublic void userMapperInsert() {User user = new User(2, "张三", new Date());userMapper.insert(user);}@Testpublic void userMapperSelectById() {User user = userMapper.selectById(3);System.out.println(user);}@Testpublic void userMapperUpdate() {User user = new User(4, "老王", new Date());userMapper.update(user);}@Testpublic void userMapperDelete() {userMapper.deleteById(4);}@Testpublic void userMapperSelectAll() {List<User> userList = userMapper.selectAll();for (User user : userList) {System.out.println(user);}}

13.5.2..xml的处理方式

<?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.no1.cz.mapper.GoodsTypeMapper"><resultMap type="com.no1.cz.domain.GoodsType" id="BaseResultMap"><id column="goods_type_id" property="goodsTypeId" jdbcType="INTEGER" /><result column="goods_type_name" property="goodsTypeName" jdbcType="VARCHAR" /></resultMap><sql id="Base_Column_List01">goods_type_id, goods_type_name</sql><!-- 新添一条商品类型数据 --><insert id="insert" parameterType="com.no1.cz.domain.GoodsType">insert into goods_type(goods_type_name) values (#{goodsTypeName})</insert><!-- 查单个商品 --><select id="selectById" resultMap="BaseResultMap" parameterType="java.lang.Integer">select * from goods_typewhere goods_type_id = #{goodsTypeId}</select><!-- 改、删、查全部,自己先写写看 --></mapper>

13.6.mybatis-generator

13.6.1.在pom.xml文件中加上一段插件配置的代码

<!-- mybatis的逆向生成插件 --><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><configuration><configurationFile>src/main/resources/generator/generatorConfig.xml</configurationFile><overwrite>true</overwrite><verbose>true</verbose></configuration></plugin>

13.6.2.创建逆向生成用的配置文件generatorConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration><!-- 数据库驱动:选择你的本地硬盘上面的数据库驱动包--><classPathEntry location="D:\Maven\Repository\mysql\mysql-connector-java\8.0.15\mysql-connector-java-8.0.15.jar"/><context id="mypro"  targetRuntime="MyBatis3"><commentGenerator><property name="suppressDate" value="true"/><!-- 是否去除自动生成的注释 true:是 : false:否 --><property name="suppressAllComments" value="true"/></commentGenerator><!--数据库链接URL,用户名、密码 --><jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1/mypro" userId="root" password="123456">
<property name="nullCatalogMeansCurrent" value="true"/></jdbcConnection><javaTypeResolver><property name="forceBigDecimals" value="false"/></javaTypeResolver><!-- 生成模型的包名和位置--><javaModelGenerator targetPackage="com.no1.cz.domain" targetProject="src/main/java"><property name="enableSubPackages" value="true"/><property name="trimStrings" value="true"/></javaModelGenerator><!-- 生成映射文件的包名和位置--><sqlMapGenerator targetPackage="mybatis" targetProject="src/main/resources"><property name="enableSubPackages" value="true"/></sqlMapGenerator><!-- 生成DAO的包名和位置--><javaClientGenerator type="XMLMAPPER" targetPackage="com.no1.cz.mapper" targetProject="src/main/java"><property name="enableSubPackages" value="true"/></javaClientGenerator><!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名--><!-- <table tableName="user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table> --><table tableName="goods" domainObjectName="Goods" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table><table tableName="goods_type" domainObjectName="GoodsType" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>	</context>
</generatorConfiguration>

13.6.3.时区设置

13.6.4.你想生成用的命令mybatis-generator:generate

 

 13.7.分页插件PageHelper的使用

依赖

<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.2.10</version>
</dependency>

使用

    @Testpublic void userMapperSelcetByPage() {// 要查询第3页的2条数据PageHelper.startPage(3, 2);List<User> userList = userMapper.selectAll();PageInfo<User> pageInfo = new PageInfo<>(userList);for (User user : pageInfo.getList()) {System.out.println(user);}System.out.println(pageInfo.getSize());System.out.println(pageInfo.getPrePage());System.out.println(pageInfo.getNextPage());System.out.println(pageInfo.getPages());System.out.println(pageInfo.getTotal());}

13.8.业务层

public interface UserService {List<User> findAll();void add(User user);
}
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Override@Transactional(propagation = Propagation.REQUIRED, readOnly = true)public List<User> findAll() {try {return userMapper.selectAll();} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);}}@Override@Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})public void add(User user) {try {userMapper.insert(user);} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);}}}

13.9.Controller层

@Controller
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("showAll")public String showAll(Model model) {List<User> userList = userService.findAll();model.addAttribute("userList", userList);return "user/showAll";}}

13.10.View层

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>用户信息展示页</title><script type="text/javascript" th:src="@{/webjars/jquery/3.2.1/dist/jquery.min.js}"></script><script type="text/javascript" th:src="@{/webjars/bootstrap/4.3.1/js/bootstrap.min.js}"></script><link rel="stylesheet" type="text/css" th:href="@{/webjars/bootstrap/4.3.1/css/bootstrap.min.css}" />
</head>
<body><div class="container"><table class="table table-striped"><tr><th>序号</th><th>Id</th><th>姓名</th><th>日期</th></tr><tr th:each="user, var : ${userList}"><td th:text="${var.count}"></td><td th:text="${user.userId}"></td><td th:text="${user.userName}"></td><td th:text="${#dates.format(user.userCreateTime, 'yyyy-MM-dd')}"></td></tr></table></div>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/94283.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2022年12月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题:数组逆序重放 将一个数组中的值按逆序重新存放。例如,原来的顺序为8,6,5,4,1。要求改为1,4,5,6,8。 输入 输入为两行:第一行数组中元素的个数n(1 输出 输出为一行:输出逆序后数组的整数,每两个整数之间用空格分隔。 样例输入 5 8 6 5 4 1 样例输出 1 4 5 6 8 以下是…

网络安全--linux下Nginx安装以及docker验证标签漏洞

目录 一、Nginx安装 二、docker验证标签漏洞 一、Nginx安装 1.首先创建Nginx的目录并进入&#xff1a; mkdir /soft && mkdir /soft/nginx/cd /soft/nginx/ 2.下载Nginx的安装包&#xff0c;可以通过FTP工具上传离线环境包&#xff0c;也可通过wget命令在线获取安装包…

Linux:shell脚本:基础使用(5)《正则表达式-sed工具》

sed是一种流编辑器&#xff0c;它是文本处理中非常中的工具&#xff0c;能够完美的配合正则表达式使用&#xff0c;功能不同凡响。 处理时&#xff0c;把当前处理的行存储在临时缓冲区中&#xff0c;称为“模式空间”&#xff08;pattern space&#xff09;&#xff0c;接着用s…

深入篇【C++】手搓模拟实现二叉搜索树(递归/非递归版本)常见应用场景(K模型与KV模型)

深入篇【C】手搓模拟实现二叉搜索树(递归/非递归版本&#xff09;&&常见应用场景 Ⅰ.二叉搜索树概念Ⅱ.二叉搜索树模拟实现(递归与非递归)①.定义结点②.构造二叉树③.插入结点④.删除结点(重要)⑤.查找结点⑥.析构二叉树⑦.拷贝二叉树⑧.二叉树赋值 Ⅲ.二叉搜索树应用…

SpringBoot复习:(48)RedisAutoConfiguration自动配置类

RedisAutoConfiguration类代码如下&#xff1a; 可以看到在这个类中配置了2个bean: redisTemplate和stringRedisTemplate. 而它通过EnableConfigurationProperties(RedisProperties.class)注解&#xff0c;把配置文件中配置的Redis相关的信息引入进来了&#xff0c;RedisPrope…

元素在div中水平居中

先看一下行级元素在div中水平居中&#xff1b; <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>div demo </title> <style> body {background-color:#d0e4fe; }</style> </head><body>&…

使用css实现时间线布局(TimeLine)

前言 在使用uni-app开发微信小程序过程中&#xff0c;遇到了时间轴布局&#xff0c;由于每项的内容高度不一致&#xff0c;使用uniapp自带的扩展组件uni-steps&#xff0c;样式布局无法对齐竖线&#xff0c;于是自己造轮子&#xff0c;完成特殊的布局。显示效果如下&#xff1…

71 # 协商缓存的配置:通过内容

对比&#xff08;协商&#xff09;缓存 比较一下再去决定是用缓存还是重新获取数据&#xff0c;这样会减少网络请求&#xff0c;提高性能。 对比缓存的工作原理 客户端第一次请求服务器的时候&#xff0c;服务器会把数据进行缓存&#xff0c;同时会生成一个缓存标识符&#…

day12 13-牛客67道剑指offer-JZ83、70、63、47、48、46、21、81

1. JZ83 剪绳子&#xff08;进阶版&#xff09; class Solution { public:int jumpFloorII(int number) {if(number < 1) return number;int temp 1;int res 0;/*2级台阶 23级台阶 44级台阶 65级台阶 16*/for(int i2; i<number; i){res 2 * temp;temp res;}return re…

docker 安装elasticsearch、kibana

下载es镜像 docker pull elasticsearch 启动es容器 docker run --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.typesingle-node" -e ES_JAVA_OPTS"-Xms512m -Xmx512m" -d elasticsearch 验证es界面访问 ​​​​​http://节点ip:9200/ ​…

应用在汽车前照灯系统中的环境光传感芯片

为了保证行车照明的安全性和方便性&#xff0c;减轻驾驶员的劳动强度。近年来&#xff0c;出现了许多新的照明控制系统&#xff0c;例如用于日间驾驶的自动照明系统、光束调节系统、延迟控制等。尤其是汽车自适应前照灯系统&#xff0c;它是一种能够自动改变两种以上的光型以适…

零售行业供应链管理核心KPI指标(一) – 能力、速度、效率和成本

有关零售行业供应链管理KPI指标的综合性分享&#xff0c;涉及到供应链能力、速度、效率和成本总共九大指标&#xff0c;是一个大框架&#xff0c;比较核心也比较综合。 衡量消费品零售企业供应链管理效率和水平的核心KPI通常有哪些&#xff1f; 图片来源-派可数据&#xff08;…

SpringBoot 操作Redis、创建Redis文件夹、遍历Redis文件夹

文章目录 前言依赖连接 RedisRedis 配置文件Redis 工具类操作 Redis创建 Redis 文件夹查询数据遍历 Redis 文件夹 前言 Redis 是一种高性能的键值存储数据库&#xff0c;支持网络、可基于内存亦可持久化的日志型&#xff0c;而 Spring Boot 是一个简化了开发过程的 Java 框架。…

【ES6】—解构赋值

一、定义 解构赋值&#xff1a;解构赋值就是一种模式的匹配&#xff0c;只要等号两边的模式完全相同的&#xff0c;那么左边的变量就会被赋值对应右边的值 二、数组的解构赋值 PS&#xff1a;数组解构赋值时&#xff0c;是通过索引的唯一性赋值的 1. 一维数组解构赋值 (1)…

《Go 语言第一课》课程学习笔记(六)

变量声明&#xff1a;静态语言有别于动态语言的重要特征 变量所绑定的内存区域是要有一个明确的边界的。也就是说&#xff0c;通过这样一个变量&#xff0c;我们究竟可以操作 4 个字节内存还是 8 个字节内存&#xff0c;又或是 256 个字节内存&#xff0c;编程语言的编译器或解…

nginx部署时http接口正常,ws接口404

可以这么配置 map $http_upgrade $connection_upgrade {default upgrade; close; }upstream wsbackend{server ip1:port1;server ip2:port2;keepalive 1000; }server {listen 20038;location /{ proxy_http_version 1.1;proxy_pass http://wsbackend;proxy_redirect off;proxy…

FreeRTOS源码分析-12 低功耗管理

目录 1 STM32低功耗管理概念及应用 1.1睡眠模式 1.2 停止模式 1.3 待机模式 2 Tickless低功耗管理 2.1 Tickless低功耗模式介绍 2.2 FreeRTOS低功耗模式配置 2.3 FreeRTOS低功耗模式应用 3 低功耗管理实际项目开发 3.1 低功耗设计必须要掌握的硬件知识 …

LangChain-ChatGLM在WIndows10下的部署

LangChain-ChatGLM在WIndows10下的部署 参考资料 1、LangChain ChatGLM2-6B 搭建个人专属知识库中的LangChain ChatGLM2-6B 构建知识库这一节&#xff1a;基本的逻辑和步骤是对的&#xff0c;但要根据Windows和现状做很多调整。 2、没有动过model_config.py中的“LORA_MOD…

【Docker】 使用Docker-Compose 搭建基于 WordPress 的博客网站

引 本文将使用流行的博客搭建工具 WordPress 搭建一个私人博客站点。部署过程中使用到了 Docker 、MySQL 。站点搭建完成后经行了发布文章的体验。 WordPress WordPress 是一个广泛使用的开源内容管理系统&#xff08;CMS&#xff09;&#xff0c;用于构建和管理网站、博客和…

LeetCode235. 二叉搜索树的最近公共祖先

235. 二叉搜索树的最近公共祖先 文章目录 [235. 二叉搜索树的最近公共祖先](https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/)一、题目二、题解方法一&#xff1a;递归方法二&#xff1a;迭代 一、题目 给定一个二叉搜索树, 找到该树中两个指定…