转载

基于MyBatis的动态SQL实现简单的案例

要求:数据库,SpringToolSuite4,VsCode以及Postman测试工具和MySQLWorkbeach

数据库


 SpringToolSuite4

控制器也可以写一个代替两个

@controller + @ResponseBody(在返回数据的方法上加上) = @RestController

工程目录:


Staff.java

package com.newer.dsql.pojo;

public class Staff {

	int id;
	
	String name;
	
	String job;
	
	String phone;
	
//	避免数据填充时,该数据为空
	Dept dept =new Dept();

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getJob() {
		return job;
	}

	public void setJob(String job) {
		this.job = job;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public Dept getDept() {
		return dept;
	}

	public void setDept(Dept dept) {
		this.dept = dept;
	}

	@Override
	public String toString() {
		return "Staff [id=" + id + ", name=" + name + ", job=" + job + ", phone=" + phone + ", dept=" + dept + "]";
	}

	
	
}

Dept.java

package com.newer.dsql.pojo;

public class Dept {

	public int id;
	
	String title;
	
	String loc;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getLoc() {
		return loc;
	}

	public void setLoc(String loc) {
		this.loc = loc;
	}

	@Override
	public String toString() {
		return "Dept [id=" + id + ", title=" + title + ", loc=" + loc + "]";
	}
	
	
}

StaffMapper.java

package com.newer.dsql.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.jdbc.SQL;

import com.newer.dsql.pojo.Dept;
import com.newer.dsql.pojo.Staff;
/**
 * SQL映射
 * @author Admin
 *
 */
@Mapper
public interface StaffMapper {
	
	/**
	 * 插入一条新纪录
	 * @param staff
	 * @return
	 */
	@Insert("insert into staff(name,job,phone,dept_id) values (#{name},#{job},#{phone},#{dept.id})")
	@Options(useGeneratedKeys = true,keyProperty = "id")
	boolean save(Staff staff);
	
	
	
	

//	@Select("select * from staff")
//	动态SQL
	@SelectProvider(type = SqlProvider.class,method="findStaff")
	@Results(
			id = "staffResultMap",
			value = {
					@Result(column = "id", property = "id"),
					@Result(column = "name", property = "name"),
					@Result(column = "job", property = "job"),
					@Result(column = "phone", property = "phone"),
					@Result(
							column = "dept_id",
							property = "dept",
							javaType = Dept.class,
							one=@One(select ="com.newer.dsql.mapper.DeptMapper.findById")
							)
			}
			)
	List<Staff> find(Staff staff);
	
	
//	定义一个内部类
	static class SqlProvider{
		
//		返回字符串(动态SQL)
		public String findStaff(Staff staff) {
			
			

			
			return new SQL() {{
				SELECT("*");
				FROM("staff");
				if(staff !=null) {
					if(staff.getName() !=null && staff.getName().length()>0) {
						
						WHERE("name like concat('%','#{name}','%')");
					}
					if(staff.getJob() !=null && staff.getJob().length()>0) {
						WHERE("job like #{job}");
					}
					if(staff.getPhone() !=null && staff.getPhone().length()>0) {
						WHERE("phone like #{phone}");
					}
					if(staff.getDept().getId() >0) {
						WHERE("dept_id=#{dept.id}");
					}
				}
			}
			}
					
					.toString();
		}
	}


	
}

DeptMapper.java

package com.newer.dsql.mapper;



import java.util.List;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import com.newer.dsql.pojo.Dept;

@Mapper
public interface DeptMapper {

	@Select("select *from dept where id=#{id}")
	Dept findById(int id);
	
	@Select("select * from dept")
	List<Dept> findAll();
}

HomeController.java

package com.newer.dsql.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

	@GetMapping("/")
	public String home() {
//		返回视图的名字
		return "index.html";
	}
}

StaffController.java

package com.newer.dsql.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.newer.dsql.mapper.StaffMapper;
import com.newer.dsql.pojo.Staff;

@RestController
public class StaffController {

	@Autowired
	StaffMapper staffMapper;
	
//	BeanUtil 反射,自动把参数填充为特定的对象
	@GetMapping("/staff")
	public List<Staff> find(Staff staff,@RequestParam(required = false)Integer deptId){
		
		if(deptId !=null) {
//			手动填充不匹配的参数
			staff.getDept().setId(deptId);
		}
//		传入查询
		return staffMapper.find(staff);
	}
	
//	Post 
//	数据HTTP 负载payload(协议)
//	json格式
//	协议:通讯时各方约定的规则或契约
	@PostMapping("/staff")
	public Staff create( @RequestBody Staff staff) {
		staffMapper.save(staff);
		return staff;
	}
}

DeptMapper.java

package com.newer.dsql.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.newer.dsql.mapper.DeptMapper;
import com.newer.dsql.pojo.Dept;

@RestController
@RequestMapping("/dept")
public class DeptController {

	
	@Autowired
	DeptMapper deptMapper;
	
	@GetMapping
	public List<Dept> list(){
		return deptMapper.findAll();
	}
}

applicaton.properties

spring.datasource.url=jdbc:mysql://你的阿里云ip:3306/hr
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

logging.level.web=debug
spring.http.log-request-details=true

index.html

<!doctype html>
<html lang="en">

<head>
  <title>hr</title>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
    integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>

<body>


  <div class="jumbotron jumbotron-fluid">
    <div class="container">
      <h1 class="display-3">动态 SQL</h1>
    </div>
  </div>

  <div id="app" class="container-fluid">
    <div class="row">

      <div class="col-lg-3 col-sm-12">
        <div class="card">

          <div class="card-body">

            <div class="form-group">
              <label for="">姓名</label>
              <input v-model="fName" type="text" name="" id="" class="form-control" placeholder="" aria-describedby="helpId">

            </div>
            <div class="form-group">
              <label for="">电话</label>
              <input  v-model="fPhone" type="text" name="" id="" class="form-control" placeholder="" aria-describedby="helpId">

            </div>
            <div class="form-group">
              <label for="">职位</label>
              <select v-model="fJob" class="form-control" name="" id="">
             <option >会计</option>
             <option>人力资源</option>
             <option>研发</option>
             <option >测试</option>
             <option >实施</option>
              </select>

            </div>

            <!-- staff表存的是dept_id -->
            <!-- 从服务端获得动态数据 -->
            <div class="form-group">
              <label for="">部门</label>
              <select v-model="fDeptId" class="form-control" name="" id="">

                <option v-for="(dept, index) in deptList" :key="index" :value="dept.id">{{dept.title}}</option>
              </select>
            </div>

            <button @click=" create" type="button" name="" id="" class="btn btn-primary btn-lg btn-block">创建</button>
          </div>

        </div>
      </div>

      <div class="col-lg-9 col-sm-12">


        <div class="row">



          <div class="card my-3">
            <div class="card-body">

              <label for="">姓名</label>
              <input type="text" v-model="name" class="mr-3">
              <label for="">电话</label>
              <input type="text" v-model="phone" class="mr-3">
              <label for="">职位</label>
              <input type="text" v-model="job" class="mr-3">
              <label for="">部门</label>
              <select v-model="dept" class="mr-3">
                <option value="0">所有部门</option>
                <option value="1">产品</option>
                <option value="2">研发</option>
                <option value="3">测试</option>
                <option value="4">实施</option>
              </select>
              <button @click="search" type="button" class="btn btn-outline-danger float-right ml-3">搜索</button>
            </div>
          </div>
        </div>
        <table class="table">
          <thead>
            <tr>
              <th>编号</th>
              <th>姓名</th>
              <th>职位</th>
              <th>电话</th>
              <th>部门</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(item, index) in staffList" :key="index">
              <td>{{ item.id }}</td>
              <td>{{ item.name }}</td>
              <td>{{ item.job }}</td>
              <td>{{ item.phone }}</td>
              <td>{{ item.dept.title }}</td>
              <td>{{ item.dept.loc }}</td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>

  <script>
    new Vue({
      el: '#app',
      data: {
        staffList: [],
        deptList: [],
        // 搜索条件
        name: '',
        job: '',
        phone: '',
        dept: 0,

        // 表单数据
        fName:'',
        fPhone:'',
        fJob:'',
        fDeptId:''

      },
      methods: {
        // 创建
        create:function(){
          let url=`http://127.0.0.1:8080/staff`;
          // JSON对象
          let params={
              name:this.fName,
              job:this.fJob,
              phone:this.fPhone,
             
              dept:{
                id:this.fDeptId
              }
          }
          // POST ,参数是HTTP负载 payload
          axios.post(url,params)
          .then(res => {
            console.log(res)

            // 再次加载
            axios.get('http://127.0.0.1:8080/staff')
            .then(res => {
              console.log(res)
              this.staffList=res.data;
            })
            .catch(err => {
              console.error(err); 
            })
          })

          .catch(err => {
            console.error(err); 
          })
        },


        // 执行搜索
        search: function () {
          let url = `http://127.0.0.1:8080/staff`;
          // 查询条件,键值对
          let queryParams = {
            name: this.name,
            job: this.job,
            phone: this.phone,
            deptId: this.dept
          }
          // 发送get请求,参数位置比较特别
          axios.get(url, {
            params: queryParams
          })
            .then(res => {
              console.log(res);
              this.staffList = res.data;
            })
        }
      },
      created() {
        // 服务端的
        let url = `http://127.0.0.1:8080/staff`;

        // 加载初始化数据
        axios.get(url)
          .then(res => {
            console.log(res)
            this.staffList = res.data;
          })
          .catch(err => {
            console.error(err);
          });


        axios.get('http://127.0.0.1:8080/dept')
          .then(res => {
            console.log(res)
            this.deptList = res.data;
          })
          .catch(err => {
            console.error(err);
          })

      },
    })
  </script>

  <!-- Optional JavaScript -->
  <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
    integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
    crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
    integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
    crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
    integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
    crossorigin="anonymous"></script>
</body>

</html>

看看效果吧(实现了创建功能。以及模糊查询),由于时间关系,就不一一实现其他功能,大致类似,有兴趣的小伙伴可以看前面的博客去实现后续功能,

正文到此结束
本文目录