SpringBoot+MyBatis中通用动态CRUDP的实现
SpringBoot+MyBatis框架的优缺点我就不表啦, 今天来说就怎么动态实现CRUDP.
先来一个通用Mapper
package cn.miw.rpc.batis.common;
import java.util.List;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;
import cn.miw.rpc.jdbc.common.BaseEntity;
/**
* 通用Mapper基础接口,使用范型,其他Mapper继承即可
* @author mrzhou
*
* @param <T>
*/
public interface GeneralMapper<T extends BaseEntity> {
@InsertProvider(method="insert",type=SQLGen.class)
@Options(useGeneratedKeys=true,keyProperty="id")
int save(T t);
@DeleteProvider(method="del",type=SQLGen.class)
int del(T t);
@UpdateProvider(method="update",type=SQLGen.class)
int update(T t);
@SelectProvider(method="select",type=SQLGen.class)
List<T> list(T t);
@SelectProvider(method="page",type=SQLGen.class)
List<T> page(T t);
}
这里需要一个SQLGen
package cn.miw.rpc.batis.common;
import java.lang.reflect.Field;
import org.apache.ibatis.jdbc.SQL;
import cn.miw.rpc.jdbc.common.BaseEntity;
/**
* 常规CRUD四个方法
* @author mrzhou
*
* @param <T>
*/
public class SQLGen<T extends BaseEntity> {
public String page(T object) {
return new SQL() {
{
SELECT("*");
FROM(object.getClass().getSimpleName());
try {
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object v = field.get(object);
if (v != null) {
String fieldName = field.getName();
if (v instanceof String && ((String)v).contains("%")) {
WHERE(fieldName + " like '"+v+"'" );
} else {
WHERE(fieldName + "=#{" + fieldName + "}");
}
}
}
} catch (Exception e) {
}
}
}.toString()+" limit #{start},#{pageSize}";
}
public String select(T object) {
return new SQL() {
{
SELECT("*");
FROM(object.getClass().getSimpleName());
try {
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object v = field.get(object);
if (v != null) {
String fieldName = field.getName();
if (v instanceof String && ((String)v).contains("%")) {
WHERE(fieldName + " like '"+v+"'" );
} else {
WHERE(fieldName + "=#{" + fieldName + "}");
}
}
}
} catch (Exception e) {
}
}
}.toString();
}
public String update(T object) {
return new SQL() {
{
UPDATE(object.getClass().getSimpleName());
try {
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object v = field.get(object);
if (v != null) {
String fieldName = field.getName();
SET(fieldName + "=#{" + fieldName + "}");
}
}
} catch (Exception e) {
}
WHERE("id=#{id}");
}
}.toString();
}
public String insert(T object) {
return new SQL() {
{
INSERT_INTO(object.getClass().getSimpleName());
try {
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object v = field.get(object);
if (v != null) {
String fieldName = field.getName();
VALUES(fieldName,"#{"+fieldName+"}");
}
}
} catch (Exception e) {
}
}
}.toString();
}
public String del(T object) {
return new SQL() {
{
DELETE_FROM(object.getClass().getSimpleName());
try {
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object v = field.get(object);
if (v != null) {
String fieldName = field.getName();
if (v instanceof String && ((String)v).contains("%")) {
WHERE(fieldName + " like '"+v+"'" );
} else {
WHERE(fieldName + "=#{" + fieldName + "}");
}
}
}
} catch (Exception e) {
}
}
}.toString();
}
}
在这里的分页查询中, 可以看到多了两个变量, 其实这个是我对每个实体都定义了一个基础类, 但这些属性对于使用来说是不需要的, 所以在这里忽略了.
package cn.miw.rpc.jdbc.common;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class BaseEntity {
@JsonIgnore
private int page = 1;
@JsonIgnore
private int pageSize = 10;
public int getPage() {
return page;
}
@JsonIgnore
public int getStart() {
return (page - 1) * pageSize;
}
public void setPage(int page) {
this.page = page;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
}
再下看一下具体的实体
package cn.miw.rpc.jdbc.model;
import org.springframework.data.annotation.Id;
import cn.miw.rpc.jdbc.common.BaseEntity;
public class User extends BaseEntity {
@Id
private Integer id;
private String name;
private Integer age;
public Integer getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
}
public User() {
super();
}
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
来看看实例对应的mapper, 在这里还可以继续定义其他你喜欢的方法
package cn.miw.rpc.batis.mapper;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;
import com.github.pagehelper.Page;
import cn.miw.rpc.batis.common.GeneralMapper;
import cn.miw.rpc.jdbc.model.User;
@Mapper
@Repository("umapper")
public interface UserMapper extends GeneralMapper<User> {
@Insert("insert into User(name,age) values(#{name},#{age})")
int addUser(@Param("name") String name, @Param("age") int age);
@Select("select * from User where id =#{id}")
User findById(@Param("id") int id);
@Update("update User set name=#{name} where id=#{id}")
void updataById(@Param("id") int id, @Param("name") String name);
@Delete("delete from User where id=#{id}")
void deleteById(@Param("id") int id);
@Select("select * from User order by id desc")
Page<User> getPage();
}
最后来看看Controller中的调用
package cn.miw.rpc.batis;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import cn.miw.rpc.batis.common.JSON;
import cn.miw.rpc.batis.mapper.UserMapper;
import cn.miw.rpc.jdbc.model.User;
import io.swagger.annotations.Api;
@Api
@RestController
public class BatisController {
@Autowired
private UserMapper userMapper;
@GetMapping("/batis/{id}")
public User insert(@PathVariable int id) {
return userMapper.findById(id);
}
@GetMapping("/batis/find/{page}")
public Object find(@PathVariable int page) {
User user = new User();
user.setName("%");
user.setPage(page);
user.setPageSize(10);
List<User> list = userMapper.page(user);
return list;
}
}
使用是不是很简单呢?