Java Config 之 SSM搭建(Mybatis-Plus)
1.JavaConfig概念
a.定义:Spring JavaConfig 是Spring社区的产品,它提供了配置Spring IOC容器的纯Java方法。因此它有助于避免使用XML配置
b.常用注解:
1)@Configuration:在类上打上这一标签,表示这个类是配置类,即表示该类为spring-*.xml
2)@ComponentScan:扫描包,相当于 <context:component-scan base-package="包路径"/>
3)@Bean:定义Bean,相当于 <bean id="类ID" class="全类名" />
4)@EnableWebMvc:开启MVC注解,相当于 <mvc:annotation-driven/>
5)@ImportResource:导入xml配置文件,相当于 <import resource="classpath:spring-mybatis.xml" />
6)@Import:导入其他 @Configuration 配置类
7)@PropertySource:读取properties文件,配合 @Value 使用
8)@EnableTransactionManagement:开启事务,相当于 <tx:annotation-driven/>
2.后端搭建
a.在数据库创建`t_user`用户表
-- 用户表 CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_name` varchar(255) NOT NULL, `user_pwd` varchar(255) NOT NULL, PRIMARY KEY (`id`) );
b.导入Maven依赖
<properties> ...... <!-- spring --> <spring.version>5.1.1.RELEASE</spring.version> <!-- jackson-json --> <jackson.version>2.9.4</jackson.version> <!-- log4j --> <slf4j.version>1.7.18</slf4j.version> <log4j.version>1.2.17</log4j.version> </properties> <dependencies> <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!-- Jackson --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- AOP --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.6</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.6</version> </dependency> <!-- 日志相关 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <!-- spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <!-- MySQL --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.13</version> </dependency> <!-- 连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency> <!-- mp 依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>3.2.0</version> </dependency> <!-- servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> <scope>provided</scope> </dependency> </dependencies>
c.创建jdbc.properties配置文件
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC jdbc.username=root jdbc.password=123456
d.创建web配置类(对应web.xml)
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected String[] getServletMappings() { return new String[] { "/" }; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { MvcConfig.class }; } @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] { RootConfig.class }; } }
e.创建Spring配置类(对应spring.xml)
@Configuration @ComponentScan("com.wode") @EnableTransactionManagement //开启事务支持 @Import(DataBaseConfig.class)//导入数据源的配置 public class RootConfig { }
f.创建DB配置类(对应spring-mybatis.xml)
@Configuration @PropertySource("classpath:jdbc.properties") public class DataBaseConfig { @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 DruidDataSource dataSource(){ DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driver); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } // 创建全局配置 @Bean public GlobalConfig globalConfig() { GlobalConfig globalConfig = new GlobalConfig(); GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig(); // 默认为自增 dbConfig.setIdType(IdType.AUTO); // 全局的表前缀策略配置 dbConfig.setTablePrefix("t_"); globalConfig.setDbConfig(dbConfig); return globalConfig; } @Bean public MybatisSqlSessionFactoryBean sqlSessionFactory(DruidDataSource dataSource, GlobalConfig globalConfig) { MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); //加载数据源 sqlSessionFactoryBean.setDataSource(dataSource); //加载 mybatis-plus 全局属性 sqlSessionFactoryBean.setGlobalConfig(globalConfig); //指定 pojo 目录 sqlSessionFactoryBean.setTypeAliasesPackage("com.wode.entity"); //mybatis-plus 插件(分页插件) Interceptor[] interceptors = {new PaginationInterceptor()}; sqlSessionFactoryBean.setPlugins(interceptors); return sqlSessionFactoryBean; } @Bean public static MapperScannerConfigurer mapperScannerConfigurer() { MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setBasePackage("com.wode.dao"); // 设置为上面的 factory name configurer.setSqlSessionFactoryBeanName("sqlSessionFactory"); return configurer; } //事务管理器 @Bean public DataSourceTransactionManager transactionManager(DruidDataSource dataSource) { return new DataSourceTransactionManager(dataSource); } }
注意:如果 mapperScannerConfigurer 不加 static,会导致整个都提前加载,这时候取不到 @Value 的值。
g.创建MVC配置类(对应spring-mvc.xml)
@Configuration @EnableWebMvc @ComponentScan("com.wode.controller") public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/home").setViewName("/home"); registry.addViewController("/detail").setViewName("/detail"); super.addViewControllers(registry); } //配置jsp视图 @Bean public ViewResolver viewResolver(){ InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/page"); resolver.setSuffix(".jsp"); resolver.setExposeContextBeansAsAttributes(true); return resolver; } //配置静态资源处理 @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable();//将静态资源的请求转发到servlet容器中默认的servlet上 } }
h.创建entity实体类
@TableName //@TableName("t_user") public class User { @TableId private Integer id; private String userName; private String userPwd; public User(){} public User(Integer id, String userName, String userPwd) { this.id = id; this.userName = userName; this.userPwd = userPwd; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPwd() { return userPwd; } public void setUserPwd(String userPwd) { this.userPwd = userPwd; } }
i.创建Dao
public interface UserMapper extends BaseMapper<User> { }
j.创建Service
@Service public class UserService { @Resource private UserMapper userMapper; public boolean addUser(User user){ if(userMapper.insert(user) > 0){ return true; } return false; } public boolean updateUser(User user){ if(userMapper.updateById(user) > 0){ return true; } return false; } public User getUser(int id){ return userMapper.selectById(id); } public IPage<User> getUserList(int currentPage, int pageSize){ Page<User> page = new Page<>(currentPage, pageSize); QueryWrapper<User> queryWrapper = new QueryWrapper<>(); return userMapper.selectPage(page, queryWrapper); } public boolean deleteUser(int id){ if(userMapper.deleteById(id) > 0){ return true; } return false; } }
k.创建Controller
@RestController @RequestMapping("/user") public class UserController { @Resource private UserService userService; @PostMapping("/add") public String addUser(User user) { if(userService.addUser(user)){ return "Success"; } return "Failure"; } @PostMapping("/update") public String updateUser(User user) { if(userService.updateUser(user)){ return "Success"; } return "Failure"; } @RequestMapping("/get/{id}") public User getUser(@PathVariable("id") int id) { return userService.getUser(id); } @RequestMapping("/list") public IPage<User> getUserList(int currentPage, int pageSize){ return userService.getUserList(currentPage, pageSize); } @RequestMapping("/delete/{id}") public String deleteUser(@PathVariable("id") int id){ if(userService.deleteUser(id)){ return "Success"; } return "Failure"; } }
3.前端测试
a.在 webapp/WEB-INF/page 目录下创建 home.jsp 和 detail.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <html lang="en"> <head> <base href="<%=basePath%>"> <meta charset="UTF-8"> <title>首页</title> <link rel="stylesheet" href="css/common.css"/> </head> <body> <div> <h1>首页</h1> <div class="row"> <table id="list-table" border="1"> <tr> <th>编号</th> <th>账号</th> <th>密码</th> <th>操作</th> </tr> </table> </div> <div class="row"> <div class="col"> <button id="list-btn">用户列表</button> </div> <div class="col"> <button id="add-btn">添加用户</button> </div> </div> </div> </body> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <script src="js/home.js"></script> </html>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <html lang="en"> <head> <base href="<%=basePath%>"> <meta charset="UTF-8"> <title>保存</title> <link rel="stylesheet" href="css/common.css"/> </head> <body> <div> <h1>保存</h1> <div class="row"> <div class="col"> <label>用户名:</label><input id="username-input" type="text"/> </div> </div> <div class="row"> <div class="col"> <label>密码:</label><input id="userpwd-input" type="text"/> </div> </div> <div class="row"> <div class="col"> <button id="save-btn">保存</button> </div> <div class="col"> <button id="close-btn">关闭</button> </div> </div> <input id="id" type="hidden" value="${param.id}" /> </div> </body> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <script src="js/detail.js"></script> </html>
b.在 webapp/css 下创建 common.css
.row{ margin:10px 0px; } .col{ display: inline-block; margin:0px 5px; }
c.在 webapp/js 下创建 home.js 和 detail.js
$(function() { //获取用户列表 $("#list-btn").on("click", getUserListFunc); //用户详情 $(document).on("click", ".detail-btn",function(){ let id = $(this).attr('data-id'); location.href = "detail?id=" + id; }); //删除用户 $(document).on("click", ".delete-btn",function(){ let id = $(this).attr('data-id'); $.ajax({ url: "user/delete/" + id, success: function(data){ alert("删除成功!"); getUserListFunc(); }, error: function(e){ alert("系统错误!"); }, }) }); //添加用户 $("#add-btn").on("click",function(){ location.href = "detail"; }); }); //函数:获取用户列表 let getUserListFunc = function() { $.ajax({ url: "user/list", data: { currentPage: 1, pageSize: 100 }, success: function (data) { if (data) { $("#list-table").empty(); $("#list-table").html("<tr><th>编号</th><th>账号</th><th>密码</th><th>操作</th></tr>"); let userArray = data.records; for (let i in userArray) { let user = userArray[i]; let id = user.id; let userName = user.userName; let userPwd = user.userPwd let trTemplate = `<tr> <th>${id}</th> <th>${userName}</th> <th>${userPwd}</th> <th> <button class="detail-btn" data-id="${id}">详情</button> <button class="delete-btn" data-id="${id}">删除</button> </th> </tr>`; $("#list-table").append(trTemplate); } } }, error: function (e) { console.log("系统错误!"); }, }) }
$(function() { //加载 let id = $("#id").val(); if(id){ $.ajax({ url: "user/get/" + id, success: function(data){ if(data){ let userName = data.userName; let userPwd = data.userPwd; $("#username-input").val(userName); $("#userpwd-input").val(userPwd); }else{ alert("系统错误!"); } }, error: function(e){ alert("系统错误!"); }, }) } //获取用户列表 $("#save-btn").on("click",function(){ let userName = $("#username-input").val(); if(! userName){ alert("用户名不能为空"); return; } let userPwd = $("#userpwd-input").val(); if(! userPwd){ alert("密码不能为空"); return; } let user; let url; //修改 if(id){ url = "user/update"; user = { userName: userName, userPwd: userPwd, id: id }; //添加 }else{ url = "user/add"; user = { userName: userName, userPwd: userPwd }; } $.ajax({ url: url, type: "POST", data: user, success: function(data){ alert("保存成功!"); }, error: function(e){ alert("系统错误!"); }, }) }); //添加用户 $("#close-btn").on("click",function(){ location.href = "home"; }); });
d.访问 http://localhost:8080/项目名/home 测试
4.参考文章
https://blog.csdn.net/albenxie/article/details/82633775
https://www.cnblogs.com/hhhshct/p/9688079.html
https://www.cnblogs.com/saber-himesama/p/7478159.html
https://www.cnblogs.com/hinsy/p/9668684.html