SpringBoot+JdbcTemplate通用Mapper的实现

SpringBoot+JdbcTemplate通用Mapper的实现

就我个人而言, 使用某个框架, 还是建议尽是只使用框架原生提供的方法来完成相关的操作, 这样从各方面来说应该都是性能最优的. 代码也应该是最好阅读和理解的. 这里还用上一篇中的model来说明. 各位也可以对两篇进行一下对比, 看看哪一种更适合你.

通用Mapper

package cn.miw.rpc.jdbc.common;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

/**
 * 基于JdbcTemplate的通用Mapper
 * @author mrzhou<br>
 * @link http://www.miw.cn<br>
 * @email mrzhou@miw.cn<br>
 *        2018年10月6日下午5:24:32<br>
 * @param <T>
 */
public abstract class GernalRowMapper<T extends BaseEntity> implements RowMapper<T> {
    @Autowired
    protected JdbcTemplate jdbcTemplate;

    @SuppressWarnings("unchecked")
    @Override
    public T mapRow(ResultSet rs, int rowNum) throws SQLException {
        Object instance = null;
        Class<?> clz = getTrueClass();
        try {
            instance = clz.newInstance();
            Field[] fields = clz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                field.set(instance, rs.getObject(field.getName()));
            }
        } catch (InstantiationException | IllegalAccessException e) {

        }
        return (T) instance;
    }

    private Class<T> getTrueClass() {
        ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
        @SuppressWarnings("unchecked")
        Class<T> clazz = (Class<T>) type.getActualTypeArguments()[0];
        return clazz;
    }

    public List<T> list(String sql, Object... args) {
        return jdbcTemplate.query(sql, this, args);
    }

    public T find(String sql, Object... args) {
        return jdbcTemplate.queryForObject(sql, this, args);
    }

    public void save(T object) {
        String sql = "insert into " + object.getClass().getSimpleName();
        Field[] fields = object.getClass().getDeclaredFields();
        List<String> f = new ArrayList<String>();
        List<String> v = new ArrayList<String>();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Object value = field.get(object);
                if (value != null) {
                    f.add(field.getName());
                    v.add("'" + value.toString() + "'");
                }
            } catch (IllegalArgumentException | IllegalAccessException e) {
            }
        }
        sql += "(" + StringUtils.join(f) + ") values(" + StringUtils.join(v) + ")";
        jdbcTemplate.execute(sql);
    }

    public void del(T object) {
        String sql = "delete from " + object.getClass().getSimpleName() + " where 1=1";
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Object value = field.get(object);
                if (value != null) {
                    if (value instanceof String && ((String) value).contains("%")) {
                        sql += " and " + field.getName() + " like '" + value.toString() + "'";
                    } else {
                        sql += " and " + field.getName() + " = '" + value.toString() + "'";
                    }
                }
            } catch (IllegalArgumentException | IllegalAccessException e) {
            }
        }
        jdbcTemplate.execute(sql);
    }

    public int update(T object) {
        String sql = "update " + object.getClass().getSimpleName();
        String id = "";
        List<String> list = new ArrayList<>();
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Object value = field.get(object);
                if ("id".equals(field.getName())) {
                    id = value.toString();
                } else {
                    list.add(field.getName() + " = " + (value == null ? "NULL" : "'" + value.toString() + "'"));
                }
            } catch (IllegalArgumentException | IllegalAccessException e) {
            }
        }
        sql += " set " + StringUtils.join(list) + " where id=" + id;
        return jdbcTemplate.update(sql);
    }

    public List<T> page(T object) {
        String sql = "select * from " + object.getClass().getSimpleName() + " where 1=1";
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Object value = field.get(object);
                if (value != null) {
                    if (value instanceof String && ((String) value).contains("%")) {
                        sql += " and " + field.getName() + " like '" + value.toString() + "'";
                    } else {
                        sql += " and " + field.getName() + " = '" + value.toString() + "'";
                    }
                }
            } catch (IllegalArgumentException | IllegalAccessException e) {
            }
        }
        sql += " limit " + object.getStart() + "," + object.getPageSize();
        return jdbcTemplate.query(sql, this);
    }
}

针对User的jdbcMapper

package cn.miw.rpc.jdbc.mapper;

import org.springframework.stereotype.Repository;

import cn.miw.rpc.jdbc.common.GernalRowMapper;
import cn.miw.rpc.jdbc.model.User;

@Repository
public class UserMapper extends GernalRowMapper<User>{

}

就这样简单, 其实什么也不用写了

针对 User的Service

package cn.miw.rpc.jdbc.service;

import java.util.List;

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

import cn.miw.rpc.jdbc.mapper.UserMapper;
import cn.miw.rpc.jdbc.model.User;

@Service
public class UserService {

    @Autowired
    private UserMapper mapper;

    public List<User> list(){
        String sql = "select * from User where name like ? ";
        List<User> list = mapper.list(sql,"%");
        return list;
    }
    /**
     * 没使用通用Mapper的情况下我们只能拼接sql来完成分页操作
     * @param page
     * @param pageSize
     * @return
     */
    public List<User> list(int page,int pageSize){
        String sql = "select * from User where name like ? limit "+((page-1)*pageSize)+","+pageSize;
        List<User> list = mapper.list(sql,"%");
        return list;
    }
    /**
     * 现在我们可以优雅地获取page
     * @param page
     * @param pageSize
     * @return
     */
    public List<User> page(int page,int pageSize){
        User object=new User();
        object.setPage(page);
        List<User> list = mapper.page(object);
        return list;
    }


    public User find(int id) {
        String sql = "select * from User where id=?";
        return mapper.find(sql, id);
    }

    public void save(User user) {
        mapper.save(user);
    }
    public void del(User user) {
        mapper.del(user);
    }
    public void update(User user) {
        mapper.update(user);
    }

}

相应的Controller

package cn.miw.rpc.jdbc;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

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.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import cn.miw.rpc.batis.common.JSON;
import cn.miw.rpc.jdbc.model.MovieInfo;
import cn.miw.rpc.jdbc.model.User;
import cn.miw.rpc.jdbc.service.UserService;
import io.swagger.annotations.Api;
@Api
@RestController
public class IndexController {

    @Autowired
    private UserService service;

    @GetMapping("/")
    public List<User> index() {
        List<User> list = service.page(1, 5);
        return list;
    }
    @GetMapping("/add")
    public void add() {
        User user=new User();
        user.setAge(50);
        user.setName("赵钱孙");
        service.save(user);
    }
    @GetMapping("/del")
    public void del() {
        User user=new User();
        user.setAge(50);
        user.setName("赵钱孙");
        service.del(user);
    }
    @GetMapping("/update")
    public void update() {
        User user=new User();
        user.setId(13);
        user.setAge(52);
        user.setName("赵钱孙");
        service.update(user);
    }


    @GetMapping("/user/{id}")
    public User user(@PathVariable int id) {
        User list = service.find(id);
        return list;
    }

}

与 Mybatis的使用一样, 同样非常的简单, 但不用引入更多的东西.


上一篇
SpringBoot集成Jfinal Enjoy模板引擎热加载问题的解决 SpringBoot集成Jfinal Enjoy模板引擎热加载问题的解决
SpringBoot集成Jfinal Enjoy模板引擎热加载问题的解决Jfinal Enjoy模板引擎通过一段时间的使用, 感觉比freeMarker更方便, 与Jfinal的配置更是天衣无缝, 同时也可以在 SpringBoot中集成,
下一篇
SpringBoot+MyBatis中通用动态CRUDP的实现 SpringBoot+MyBatis中通用动态CRUDP的实现
SpringBoot+MyBatis中通用动态CRUDP的实现SpringBoot+MyBatis框架的优缺点我就不表啦, 今天来说就怎么动态实现CRUDP.先来一个通用Mapper package cn.miw.rpc.batis.com