一、框架
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221217164951560-2122684063.png)
二、整合流程:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221217165034388-740229262.png)
三、创建一个Maven的Web的项目:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224142309183-455125475.jpg)
3.1-包目录的创建:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224152027909-1659785006.png)
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224151039504-1961910732.png)
3.2-对各各包的解析:
config目录存放的是相关的配置类
controller编写的是Controller类
dao存放的是Dao接口,因为使用的是Mapper接口代理方式,所以没有实现类包
service存的是Service接口,impl存放的是Service实现类
resources:存入的是配置文件,如Jdbc.properties
webapp:目录可以存放静态资源
test/java:存放的是测试类
四、环境准备ssm的整合 --->(Config包下):
4.1-pox.xml(这个"非常重要",关系重大!!!)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>springMvc_ssm</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
//--------------------------------------
//你们复制下面的部分就可以了
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
4.2-创建SpringConfig配置类
@Configuration
@ComponentScan("com.itheima.service")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MyBatisConfig.class})
public class SpringConfig {
}
4.3-创建JdbcConfig配置类
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
//平台事务管理器
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager ds = new DataSourceTransactionManager();
ds.setDataSource(dataSource);
return ds;
}
}
4.4-创建MybatisConfig配置类
public class MyBatisConfig {
//MyBatisConfig 配置类需要两个bean被IOC容器管理,SqlSessionFactoryBean可以自动获得SqlSessionFactory,MapperScannerConfigurer扫描mapper所在的包
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setTypeAliasesPackage("com.itheima.domain");
return factoryBean;
}
//Mapper扫描配置器MapperScannerConfigurer
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.itheima.dao");
return msc;
}
}
4.5-创建SpringMvcConfig配置类
@Configuration
@ComponentScan("com.itheima.controller")
@EnableWebMvc
public class SpringMvcConfig {
}
4.6-创建ServletConfig配置类
//web--springMVC的配置
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
//加载Spring配置类
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//加载SpringMVC配置类
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
//设置SpringMVC请求地址拦截规则
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
4.7-创建jdbc.properties
在resources下提供jdbc.properties,设置数据库连接四要素
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224162416831-1541836652.png)
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm_db
jdbc.username=root
jdbc.password=root
五、代码实现:
需求:对表tbl_book进行新增、修改、删除、根据ID查询和查询所有
5.1-创建数据库及表
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224163853230-2085670372.png)
5.1.....1-表的"tbl_book字段信息"(Design Table)
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224164045014-312594403.png)
5.1......2-表信息(自己看心情写)
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224164207267-749862939.png)
5.2-编写Book模型类(和"表"的字段对应)(domain包下)
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224164430701-1623926382.png)
public class Book {
private Integer id;
private String type;
private String name;
private String description;
@Override
public String toString() {
return "Book{" +
"id=" + id +
", type='" + type + '\'' +
", name='" + name + '\'' +
", description='" + description + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
5.3-编写Dao接口(是一个:接口)
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224164907143-504830334.png)
public interface BookDao {
// @Insert("insert into tbl_book values(null,#{type},#{name},#{description})")
@Insert("insert into tbl_book (type,name,description) values(#{type},#{name},#{description})")
public void save(Book book);
@Update("update tbl_book set type = #{type}, name = #{name}, description = #{description} where id = #{id}")
public void update(Book book);
@Delete("delete from tbl_book where id = #{id}")
public void delete(Integer id);
@Select("select * from tbl_book where id = #{id}")
public Book getById(Integer id);
@Select("select * from tbl_book")
public List<Book> getAll();
}
5.4-编写Service接口和实现类
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224165226995-606564689.png)
5.4.....1-Service接口:(BookService的内容)
//业务注解,搭配SpringConfig的@EnableTransactionManagement和JdbcConfig里的PlatformTransactionManager的bean对象
@Transactional
public interface BookService {
/**
* 保存
* @param book
* @return
*/
public boolean save(Book book);
/**
* 修改
* @param book
* @return
*/
public boolean update(Book book);
/**
* 按id删除
* @param id
* @return
*/
public boolean delete(Integer id);
/**
* 按id查询
* @param id
* @return
*/
public Book getById(Integer id);
/**
* 查询全部
* @return
*/
public List<Book> getAll();
}
5.4.....2-Service实现类:(BookServiceImpl的内容):#(和Dao层联系)
//BookService是接口,BookServiceImpl是实现类
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
public boolean save(Book book) {
bookDao.save(book);
return true;
}
public boolean update(Book book) {
bookDao.update(book);
return true;
}
public boolean delete(Integer id) {
bookDao.delete(id);
return true;
}
public Book getById(Integer id) {
return bookDao.getById(id);
}
public List<Book> getAll() {
return bookDao.getAll();
}
}
5.4......3-自动注入bookDao黄线提示问题:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224165912808-1463262747.png)
5.5-编写Contorller类
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224170346946-1362023915.png)
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@PostMapping
public boolean save(@RequestBody Book book) {
return bookService.save(book);
}
@PutMapping
public boolean update(@RequestBody Book book) {
return bookService.update(book);
}
@DeleteMapping("/{id}")
public boolean delete(@PathVariable Integer id) {
return bookService.delete(id);
}
@GetMapping("/{id}")
public Book getById(@PathVariable Integer id) {
return bookService.getById(id);
}
@GetMapping
public List<Book> getAll() {
return bookService.getAll();
}
}
六、Test单元测试:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224170629960-1644095623.png)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class TestService {
@Autowired
private BookService bookService;
@Test
public void testGetById(){
Book book = bookService.getById(1);
System.out.println(book);
}
@Test
public void testGetAll(){
List<Book> all = bookService.getAll();
System.out.println(all);
}
}
七、如何让一个Maven项目"跑"起来:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224171112931-1941389926.png)
八、一些Maven的配置(要注意,不然会报错!!!)
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224171255157-645045342.png)
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224171347491-394910194.png)
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224171414784-52128488.png)
八:PostMan测试:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224171532162-1604759124.png)
8.1-添加数据POST:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224171704592-645742463.png)
{
"type": "111",
"name": "11111111f",
"description": "1111111"
}
8.2-修改数据PUT:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224171810223-1054093787.png)
{
"id": 3,
"type": "000000",
"name": "0000000",
"description": "0000000000"
}
8.3-删除数据DELETE:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224171940325-526064388.png)
8.4-按Id查询GET:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224172041990-225883415.png)
8.5:全部查询GET:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221224172123514-352895727.png)
九、总结:
9.1-整合MyBatis
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221227124033551-410071695.png)
9.2-整合srpingMvc
9.2.....1:web配置
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221227125130938-1454427471.png)
9.2....2:springMvc配置类
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221227125245191-1373828813.png)
9.2.....3:controller配置
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221227125419771-702447507.png)
十、小结:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221227125500099-375115464.png)
---------------------------------------------
十一、统一结果封装,前后端数据传输协议:
11.1-希望的效果:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221227154659096-350846096.png)
11.2-包的位置
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221227154549592-1657449503.png)
11.3:代码块:
public class Result {
//描述统一格式中的数据
private Object data;
//描述统一格式中的编码,用于区分操作,可以简化配置0或1表示成功失败
private Integer code;
//描述统一格式中的消息,可选属性
private String msg;
public Result() {
}
//构造方法是方便对象的创建
public Result(Integer code, Object data) {
this.data = data;
this.code = code;
}
//构造方法是方便对象的创建
public Result(Integer code, Object data, String msg) {
this.data = data;
this.code = code;
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
//返回状态码,1结尾是成功,0结尾是失败
public class Code {
public static final Integer SAVE_OK = 20011;
public static final Integer DELETE_OK = 20021;
public static final Integer UPDATE_OK = 20031;
public static final Integer GET_OK = 20041;
public static final Integer SAVE_ERR = 20010;
public static final Integer DELETE_ERR = 20020;
public static final Integer UPDATE_ERR = 20030;
public static final Integer GET_ERR = 20040;
}
//统一每一个控制器方法返回值
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@PostMapping
public Result save(@RequestBody Book book) {
boolean flag = bookService.save(book);
return new Result(flag ? Code.SAVE_OK : Code.SAVE_ERR, flag);
}
@PutMapping
public Result update(@RequestBody Book book) {
boolean flag = bookService.update(book);
return new Result(flag ? Code.UPDATE_OK : Code.UPDATE_ERR, flag);
}
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
boolean flag = bookService.delete(id);
return new Result(flag ? Code.DELETE_OK : Code.DELETE_ERR, flag);
}
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id) {
Book book = bookService.getById(id);
Integer code = book != null ? Code.GET_OK : Code.GET_ERR;
String msg = book != null ? "" : "数据查询失败,请重试!";
return new Result(code, book, msg);
}
@GetMapping
public Result getAll() {
List<Book> bookList = bookService.getAll();
Integer code = bookList != null ? Code.GET_OK : Code.GET_ERR;
String msg = bookList != null ? "" : "数据查询失败,请重试!";
return new Result(code, bookList, msg);
}
}
----------------------------------------------------
十二、异常处理:
12.1-包路径:
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221227163947557-849506475.png)
12.2-异常处理的代码块:
//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器,Advise译为通知,建议
@RestControllerAdvice
public class ProjectExceptionAdvice {
//除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
//@ExceptionHandler异常处理器
@ExceptionHandler(Exception.class)
public Result doException(Exception ex){
System.out.println("嘿嘿,异常你哪里跑!");
return new Result(666,null,"嘿嘿,异常你哪里跑!");
}
}
------------------------------------------------
十三、项目异常处理(对上面"十二"异常处理的升级)
上面"十二"的是对"异常"统一回复,现在是分"运行时异常","输出时异常"等来做多方面处理。
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221228082852530-1286787200.png)
-
ProjectExceptionAdvice的代码块
//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
//@ExceptionHandler用于设置当前处理器类对应的异常类型
@ExceptionHandler(SystemException.class)
public Result doSystemException(SystemException ex){
//记录日志
//发送消息给运维
//发送邮件给开发人员,ex对象发送给开发人员
return new Result(ex.getCode(),null,ex.getMessage());
}
@ExceptionHandler(BusinessException.class)
public Result doBusinessException(BusinessException ex){
return new Result(ex.getCode(),null,ex.getMessage());
}
//除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
@ExceptionHandler(Exception.class)
public Result doOtherException(Exception ex){
//记录日志
//发送消息给运维
//发送邮件给开发人员,ex对象发送给开发人员
return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
}
}
//自定义业务异常处理器,用于封装异常信息,对异常进行分类
public class BusinessException extends RuntimeException {
private Integer code;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
public BusinessException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
}
//自定义系统异常处理器,继承运行时异常RuntimeException,用于封装异常信息,对异常进行分类
public class SystemException extends RuntimeException{
private Integer code;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public SystemException(Integer code, String message) {
super(message);
this.code = code;
}
public SystemException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
}
问:怎么使用"项目异常处理"???
答:在自己决定可能会出现错误的地方"抛出"异常处理器
具体操作:(根据实际案例,进行抛出异常)
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221228083752597-1196107285.png)
![](https://img2023.cnblogs.com/blog/2871529/202212/2871529-20221228084020338-1417223825.png)