第十三章 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{

	@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>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值