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的使用一样, 同样非常的简单, 但不用引入更多的东西.