SSM整合
流程:
1.创建工程
2.SSM整合
Spring:
-
SpringConfig
@Configuration @ComponentScan("com.aiit.service") @PropertySource("classpath:jdbc.properties") @Import({JdbcConfig.class,MybatisConfig.class}) public class SpringConfig { }
MyBatis:
- MyBatisConfig
public class MybatisConfig {
//设置两个bean
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setTypeAliasesPackage("com.aiit.domain");
return sqlSessionFactoryBean;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer mapperScannerConfigurer=new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.aiit.dao");
return mapperScannerConfigurer;
}
}
- 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 druidDataSource=new DruidDataSource();
druidDataSource.setDriverClassName(driver);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
return druidDataSource;
}
}
- jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm_db
jdbc.username=root
jdbc.password=20020630
SpringMVC:
- ServletConfig
public class ServletContainsConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
- SpringMvcConfig
@Configuration
@ComponentScan("com.aiit.controller")
@EnableWebMvc
public class SpringMvcConfig {
}
3.功能模块
表与实体类
dao(接口+自动代理)
public interface BookDao {
//新增
@Insert("insert into tbl_book values(null,#{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) ;
//根据id查询
@Select("select * from tbl_book where id=#{id}")
public Book selectById(Integer id);
@Select("select * from tbl_book")
//查询所有
public List<Book> selectAll();
}
service(接口+实现类)
- 业务层接口测试
public interface BookService {
//新增
public boolean save(Book book);
//修改
public boolean update(Book book);
//删除
public boolean delete(Integer id) ;
//根据id查询
public Book selectById(Integer id);
//查询所有
public List<Book> selectAll();
}
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
@Override
public boolean save(Book book) {
bookDao.save(book);
return true;
}
@Override
public boolean update(Book book) {
bookDao.update(book);
return true;
}
@Override
public boolean delete(Integer id) {
bookDao.delete(id);
return true;
}
@Override
public Book selectById(Integer id) {
return bookDao.selectById(id);
}
@Override
public List<Book> selectAll() {
return bookDao.selectAll();
}
}
controller
- 表现层接口测试
@Controller
@ResponseBody
@RequestMapping("/books")
public class BookContorller {
@Autowired
private BookService bookService;
@PostMapping
public boolean save(@RequestBody Book book) {
bookService.save(book);
return true;
}
@PutMapping
public boolean update(@RequestBody Book book) {
bookService.update(book);
return true;
}
@DeleteMapping("/{id}")
public boolean delete(@PathVariable Integer id) {
bookService.delete(id);
return true;
}
@GetMapping("/{id}")
public Book selectById(@PathVariable Integer id) {
return bookService.selectById(id);
}
@GetMapping
public List<Book> selectAll() {
return bookService.selectAll();
}
}
4.事务处理
1.配置当前接口方法具有事务
使用@Transactional注解
@Transactional
public interface BookService {
//新增
public boolean save(Book book);
//修改
public boolean update(Book book);
//删除
public boolean delete(Integer id) ;
//根据id查询
public Book selectById(Integer id);
//查询所有
public List<Book> selectAll();
}
2.配置事务管理器
使用形参注入dataSource
在jdbcConfig类中写
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
3.开启注解式事务驱动
在SpringConfig中
@EnableTransactionManagement
5.实现 表现层和前端数据传输协议
定义返回结果类
public class Result {
private Object data;
private Integer code;
private String msg;
//提供构造方法
public Result() {
}
public Result(Object data, Integer code) {
this.data = data;
this.code = code;
}
public Result(Object data, Integer code, 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;
}
}
定义Code类
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;
}
修改表现层BookController的返回值
@Controller
@ResponseBody
@RequestMapping("/books")
public class BookContorller {
@Autowired
private BookService bookService;
@PostMapping
public Result save(@RequestBody Book book) {
boolean flag = bookService.save(book);
return new Result(flag,flag?Code.SAVE_OK:Code.SAVE_ERR);
}
@PutMapping
public Result update(@RequestBody Book book) {
boolean flag = bookService.update(book);
return new Result(flag,flag?Code.UPDATE_OK:Code.UPDATE_ERR);
}
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
boolean flag = bookService.delete(id);
return new Result(flag,flag?Code.DELETE_OK:Code.DELETE_ERR);
}
@GetMapping("/{id}")
public Result selectById(@PathVariable Integer id) {
Book book = bookService.selectById(id);
return new Result(book,book==null?Code.GET_ERR:Code.GET_OK,book==null?"数据查询失败":"查询成功");
}
@GetMapping
public Result selectAll() {
List<Book> books = bookService.selectAll();
return new Result(books,books==null?Code.GET_ERR:Code.GET_OK,books==null?"数据查询失败":"查询成功");
}
}
6.异常处理
定义一个系统异常类继承RuntimeException
public class BusinessExcpetion extends RuntimeException {
private Integer code;
public BusinessExcpetion(Integer code) {
this.code = code;
}
public BusinessExcpetion(String message, Integer code) {
super(message);
this.code = code;
}
public BusinessExcpetion(String message, Throwable cause, Integer code) {
super(message, cause);
this.code = code;
}
public BusinessExcpetion(Throwable cause, Integer code) {
super(cause);
this.code = code;
}
public BusinessExcpetion(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Integer code) {
super(message, cause, enableSuppression, writableStackTrace);
this.code = code;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
定义一个业务异常类
public class BusinessExcpetion extends RuntimeException {
private Integer code;
public BusinessExcpetion(Integer code) {
this.code = code;
}
public BusinessExcpetion(String message, Integer code) {
super(message);
this.code = code;
}
public BusinessExcpetion(String message, Throwable cause, Integer code) {
super(message, cause);
this.code = code;
}
public BusinessExcpetion(Throwable cause, Integer code) {
super(cause);
this.code = code;
}
public BusinessExcpetion(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Integer code) {
super(message, cause, enableSuppression, writableStackTrace);
this.code = code;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
在表现层自定义一个异常处理类,用来捕获程序中出现的异常
我们造一个异常出来
@Override
public Book selectById(Integer id) {
//制作一个异常充当业务异常
if (id==100){
throw new BusinessExcpetion("请不要用你的技术挑战我的耐心!", Code.BUSINESS_ERR);
}
return bookDao.selectById(id);
}
当查询id是100时,返回业务异常
加载页面
1.放行
配置一个类继承WebMvcConfigurationSupport
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
}
}
对资源放行不然访问不到资源
要在SpringMvcConfig中扫描该配置类
前端的代码实现:
<!DOCTYPE html>
<html>
<head>
<!-- 页面meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>SpringMVC案例</title>
<meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
<!-- 引入样式 -->
<link rel="stylesheet" href="../plugins/elementui/index.css">
<link rel="stylesheet" href="../plugins/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../css/style.css">
</head>
<body class="hold-transition">
<div id="app">
<div class="content-header">
<h1>图书管理</h1>
</div>
<div class="app-container">
<div class="box">
<div class="filter-container">
<el-input placeholder="图书名称" v-model="pagination.queryString" style="width: 200px;" class="filter-item"></el-input>
<el-button @click="getAll()" class="dalfBut">查询</el-button>
<el-button type="primary" class="butT" @click="handleCreate()">新建</el-button>
</div>
<el-table size="small" current-row-key="id" :data="dataList" stripe highlight-current-row>
<el-table-column type="index" align="center" label="序号"></el-table-column>
<el-table-column prop="type" label="图书类别" align="center"></el-table-column>
<el-table-column prop="name" label="图书名称" align="center"></el-table-column>
<el-table-column prop="description" label="描述" align="center"></el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>
<el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 新增标签弹层 -->
<div class="add-form">
<el-dialog title="新增图书" :visible.sync="dialogFormVisible">
<el-form ref="dataAddForm" :model="formData" :rules="rules" label-position="right" label-width="100px">
<el-row>
<el-col :span="12">
<el-form-item label="图书类别" prop="type">
<el-input v-model="formData.type"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="图书名称" prop="name">
<el-input v-model="formData.name"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="描述">
<el-input v-model="formData.description" type="textarea"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="handleAdd()">确定</el-button>
</div>
</el-dialog>
</div>
<!-- 编辑标签弹层 -->
<div class="add-form">
<el-dialog title="编辑检查项" :visible.sync="dialogFormVisible4Edit">
<el-form ref="dataEditForm" :model="formData" :rules="rules" label-position="right" label-width="100px">
<el-row>
<el-col :span="12">
<el-form-item label="图书类别" prop="type">
<el-input v-model="formData.type"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="图书名称" prop="name">
<el-input v-model="formData.name"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="描述">
<el-input v-model="formData.description" type="textarea"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible4Edit = false">取消</el-button>
<el-button type="primary" @click="handleEdit()">确定</el-button>
</div>
</el-dialog>
</div>
</div>
</div>
</div>
</body>
<!-- 引入组件库 -->
<script src="../js/vue.js"></script>
<script src="../plugins/elementui/index.js"></script>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script src="../js/axios-0.18.0.js"></script>
<script>
var vue = new Vue({
el: '#app',
data:{
pagination: {},
dataList: [],//当前页要展示的列表数据
formData: {},//表单数据
dialogFormVisible: false,//控制表单是否可见
dialogFormVisible4Edit:false,//编辑表单是否可见
rules: {//校验规则
type: [{ required: true, message: '图书类别为必填项', trigger: 'blur' }],
name: [{ required: true, message: '图书名称为必填项', trigger: 'blur' }]
}
},
//钩子函数,VUE对象初始化完成后自动执行
created() {
this.getAll();
},
methods: {
//列表
getAll() {
//查询所有
axios.get("/books").then((resp)=>{
this.dataList=resp.data.data;
})
},
//弹出添加窗口
handleCreate() {
this.dialogFormVisible=true;
},
//重置表单
resetForm() {
this.formData={};
},
//添加
handleAdd () {
this.resetForm();
axios.post("/books",this.formData).then((resp)=>{
//发送好请求之后,将对话框隐藏
if (resp.data.code==20011){
this.dialogFormVisible=false;
//刷新页面
this.$message({
message: '恭喜你,添加成功',
type: 'success'
});
this.getAll();
}
else if (resp.data.code==20010){
//弹出弹出对话框提示错误'
this.$message.error('添加失败');
}
else{
//
this.$message.error(resp.data.msg);
}
})
},
//弹出编辑窗口
handleUpdate(row) {
this.dialogFormVisible4Edit=true;
axios.get("/books/"+row.id).then((resp)=>{
this.formData=resp.data.data;
})
},
//点击编辑按钮
handleEdit() {
this.formData="";
axios.put("/books", this.formData).then((res)=> {
//如果操作成功
if(res.data.code == 20031)
{
this.dialogFormVisible4Edit = false;
this.$message.success("修改成功");
}
else if (resp.data.code==20030){
//弹出弹出对话框提示错误'
this.$message.error('修改失败');
}
else{
//
this.$message.error(resp.data.msg);
}
}).finally(()=>{
this.getAll();
})
},
// 删除
handleDelete(row) {
//弹出对话框
this.$confirm('此操作将永久删除列数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.delete("/books/"+row.id).then((resp)=>{
if(resp.data.code==20021)
{
this.$message({
type: 'success',
message: '删除成功!'
});
}
else if (resp.data.code==20030){
//弹出弹出对话框提示错误'
this.$message.error('删除失败');
}
else{
//
this.$message.error(resp.data.msg);
}
}).finally(()=>{
this.getAll();
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
}
}
})
</script>
</html>