第十三章 SpringBoot项目(总)

news2024/9/22 23:33:48

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{

	@Override
	protected 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);
	
	@Override
	public 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;
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("a servlet get method ran...");
		doPost(req, resp);
}
	
	@Override
	protected 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 {

	@Override
	public 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 {
	
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		System.out.println("应用初始化。。。");
	}
	
	@Override
	public 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);
	}

	@Override
	public 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.Driver
    url: jdbc:mysql://localhost/mypro?&useSSL=false&serverTimezone=Asia/Chongqing&characterEncoding=utf8
    username: root
password: 123456

mybatis: # 配置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	int
	private Integer userId;
//	user_name	varchar
	private String userName;
//	user_create_time	timestamp
	private 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();
}
测试:
@Autowired
	private UserMapper userMapper;
	
	@Test
	public void userMapperInsert() {
		User user = new User(2, "张三", new Date());
		userMapper.insert(user);
	}
	
	@Test
	public void userMapperSelectById() {
		User user = userMapper.selectById(3);
		System.out.println(user);
	}
	
	@Test
	public void userMapperUpdate() {
		User user = new User(4, "老王", new Date());
		userMapper.update(user);
	}
	
	@Test
	public void userMapperDelete() {
		userMapper.deleteById(4);
	}
	
	@Test
	public 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_type
		where 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 generatorConfiguration
        PUBLIC "-//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>

使用

    @Test
	public 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 {

	@Autowired
	private 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 {
	
	@Autowired
	private 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.coloradmin.cn/o/891058.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蝉联第一 | 2022中国数据泄露防护市场份额报告发布

2022年天空卫士DLP 市场份额位列中国第一 IDC 2022中国数据泄露防护市场份额报告于8月14日发布。报告主要阐述中国数据泄露防护市场的规模、厂商份额以及技术发展变化等内容。报告数据显示&#xff0c;2022年中国中国数据泄露防护&#xff08;DLP&#xff09;市场规模为1.31亿…

智慧工地云平台源码——塔机监控系统

智慧工地概念 智慧工地是一种崭新的工程全生命周期管理理念&#xff0c;是指运用信息化手段&#xff0c;通过对工程项目进行精确设计和施工模拟&#xff0c;围绕施工过程管理&#xff0c;建立互联协同、智能生产、科学管理的施工项目信息化生态圈&#xff0c;并将此数据在虚拟…

【Python程序设计】基于Python Flask的全国气象数据采集及可视化系统-附下载方式以及项目参考论文,原创项目其他均为抄袭

基于Python Flask的全国气象数据采集及可视化系统 一、项目简介二、项目技术三、项目功能四、运行截图五、分类说明六、实现代码七、数据库结构八、源码下载地址 一、项目简介 本项目是一个基于Web技术的实时气象数据可视化系统。通过爬取中国天气网的各个城市气象数据&#x…

linkis 1.1.1 报错 No plugin found spark-2.4.8, please check your configuration

按照官方教程设置,但是仍然报错 Caused by: java.util.concurrent.ExecutionException: LinkisException{errCode70063, descNo plugin found spark-2.4.8, please check your configuration, iphadoop0004, port9103, serviceKindlinkis-cg-engineplugin} 这个时候,我们首先检…

配置pyqt5开发环境

安装库 pip install pyqt5 -i https://mirrors.aliuyun.com/pypi/simple pip install pyqt5-tools -i https://mirrors.aliuyun.com/pypi/simple pip install PyQt5designer -i https://mirrors.aliuyun.com/pypi/simple配置External Tools Name:QtDesigner Program:C:\Anaco…

第九章 动态规划part10(代码随想录)

121. 买卖股票的最佳时机 1. 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 用二维dp数组表示第i天的2种状态 dp[i][0] 表示第i天持有股票所得最多现金&#xff0c;可能i-1天就买股票了 dp[i][1] 表示第i天不持有股票所得最多现金 最后求&#xff1a;dp[len-1][0…

SQLServer数据库获取单表重复记录中日期最新的记录

SQLServer数据库获取重复记录中日期最新的记录 CREATE TABLE [dbo].[t_expense_record_info]([id] [int] IDENTITY(1,1) NOT NULL,[goods_id] [int] NULL,[amount] [decimal](18, 6) NULL,[expense_time] [datetime] NULL,[user_id] [int] NULL,[create_date] [datetime] NULL…

qt初入门0:结构体中QString用memset导致崩溃分析及QLatin1String简单查看源码

初识Qt,进行开发时遇到一个崩溃问题 简单整理 1&#xff1a;问题描述如下&#xff0c;结构体中QString成员&#xff0c;然后对结构体调用了memset导致问题&#xff1a; 2&#xff1a;问题分析&#xff0c;加断点调试的方式可以明确分析到行数 可以明确看出&#xff0c;初始化…

msvcr120.dll丢失怎么修复,介绍几种最简单的修复方法

当您在运行某个程序时遇到msvcr120.dll丢失的错误提示时&#xff0c;可能无法正常启动或执行该程序。msvcr120.dll是Microsoft Visual C Redistributable中的一个动态链接库&#xff08;DLL&#xff09;文件&#xff0c;它是一种运行时库&#xff08;Runtime Library&#xff0…

浅谈时序:set_input_delay

1、set_input_delay的本质 set_input_delay是对模块input信号在模块外部延迟的约束&#xff0c;本质上EDA工具会根据约束调整设计内部的器件类型&#xff0c;摆放的位置以及优化内部组合逻辑保证满足约束要求。 约束指导原则&#xff1a;尽量照顾设计外部逻辑延时 set_input…

机器学习编译系列---张量程序抽象

机器学习编译系列---张量程序抽象 1. 张量函数概念的引入与抽象的必要性 1. 张量函数概念的引入与抽象的必要性 在文章机器学习编译系列—概述中提到&#xff0c;机器学习编译的一个很重要操作是做等价变换来减少内存或者提高运行效率。变换是以“元张量函数”(private tensor …

第一百三十一天学习记录:数据结构与算法基础:栈和队列(下)(王卓教学视频)

队列的表示和操作的实现 循环顺序队列是一种使用数组来实现的队列结构&#xff0c;其中头指针和尾指针表示队列的头部和尾部位置。 当队列为空时&#xff0c;头指针和尾指针都指向同一个位置&#xff0c;即数组的第一个位置。这是因为在空队列中&#xff0c;没有任何元素可以作…

软件测试|Python自动化测试实现的思路

Python自动化测试常用于Web应用、移动应用、桌面应用等的测试 Python自动化实现思路通常分为以下几步&#xff1a; 1. 确定自动化测试的范围和目标&#xff1a; 首先需要明确需要进行自动化测试的范围和目标&#xff0c;包括测试场景、测试用例、测试数据等。 2. 选择自动化…

分析商务报表使用什么工具?

传统的BI分析商务报表存在的问题 随着数字化转型的深入推进&#xff0c;企业面临着海量数据的挑战和机遇。数据是企业的重要资产&#xff0c;能够帮助企业洞察市场动态、优化业务流程、提升客户满意度、创造竞争优势。然而&#xff0c;传统的BI&#xff08;商业智能&#xff0…

【IMX6ULL驱动开发学习】07.驱动程序分离的思想之平台总线设备驱动模型和设备树

一、驱动程序分离的思想 【IMX6ULL驱动开发学习】05.字符设备驱动开发模板&#xff08;包括读写函数、poll机制、异步通知、定时器、中断、自动创建设备节点和环形缓冲区&#xff09;_阿龙还在写代码的博客-CSDN博客 之前编写驱动程序的代码存在不少弊端&#xff1a;移植性差…

治疗偏头痛等亚疼痛的远程电神经调控(REN)设备

原文链接&#xff1a; NERIVIO CE标志适应症扩展到青少年和成人偏头痛的预防和急性治疗 (prnewswire.com) 公司官网&#xff1a; Homepage - Theranica APP下载链接&#xff1a; Migraine Headache Treatment - Nerivio 使用过程问题&#xff1a; 常见问题 - 无药物偏头痛两…

解决Oracle中XML插入数据时的空格问题

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

05- 定时器

定时器 定时器5.1 独立看门狗定时器独立看门狗的配置步骤&#xff1a;看门狗计时时间的计算&#xff1a; 5.2 窗口看门狗看门狗有什么作用&#xff1f;窗口看门狗超时时间计算&#xff1a;窗口看门狗的配置过程&#xff1a; 5.3 通用定时器三种定时器&#xff1a; 计数器的时钟…

使用Jmeter进行压力测试你所不知道内幕

在网络很多网友反馈Jmeter的测试结果不准确&#xff0c;下面我们主要聊一下不准确的原因。 Jmeter 是ASF的一款开源免费软件 &#xff0c;在国内被很多中小公司当作性能测试工具广泛使用。Apache软件基金会&#xff08;ASF&#xff09;是一家总部位于美国的非营利性慈善组织。…

Binder机制原理解析

前言 我们都知道Android应用程序由Activity、Service、Broadcast Receiver、Content Provider四大组件构成的,他们可能运行在不同进程中&#xff0c;还有Android系统中还有各种服务&#xff0c;例如Actiivty管理服务ActivityManagerService、电源管理服务PowerManagerService、…