1. 程式人生 > >SpringBoot + MyBatis 動態查詢支援的通用方法

SpringBoot + MyBatis 動態查詢支援的通用方法

2018國慶, 已經提前預知會陰雨綿綿, 再說大家都能夠想像得到的場景, 還是在家學習吧.

人人人人人人人人人人人人人人人
人人人人人人人人人人人人人人人
人人人人人人人人人人人人人人人
人人人人人人人人人人人人人人人
人人人人人人人人人人人人人人人
人人人人人人人人人人人人人人人
人人人人人人人我人人人人人人人
人人人人人人人人人人人人人人人
人人人人人人人人人人人人人人人
人人人人人人人人人人人人人人人
人人人人人人人人人人人人人人人
人人人人人人人人人人人人人人人
人人人人人人人人人人人人人人人

這幾天除了買菜,做飯,再看看別人的堵, 其實我也還是蠻開心的, 你所擁有的一切, 除了知識好像其他都可能會被小偷偷掉或者遺落. 

跑偏了, 迴歸正題吧.

這幾天研究使用了一下 springBoot + MyBatis動態註解. 看了好多人說myBatis不支援動態,其實不然, 我個人不喜歡太多配置, 所以一慣喜歡使用註解模式, 但spring體系當中註解實在太多了, 其實常用的也就那麼幾個. 呵呵又跑題了.回來

package cn.miw.rpc.batis.comm;

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;

/**
 * 通用Mapper基礎介面,使用範型,其他Mapper繼承即可
 * @author mrzhou
 *
 * @param <T>
 */
public interface GeneralMapper<T> {
	@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);
	
}

我個常用的也就是CRUD這4個方法, 其他的Mapper方法你可以在繼承中再繼續寫吧, 那些就是大家常用的可以寫在繼承介面當中.

這裡我寫了一個通用的SQLProvider類SQLGen.java

package cn.miw.rpc.batis.comm;

import java.lang.reflect.Field;

import org.apache.ibatis.jdbc.SQL;
/**
 * 常規CRUD四個方法
 * @author mrzhou
 *
 * @param <T>
 */
public class SQLGen<T> {
	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();
	}
}

在呼叫Mapper方法時傳入相應的實體, 如果欄位型別為String且包含%, 將使用like 進行查詢, 該操作僅對select和delete操作有效. insert,update則不受此限制, '%'百分號將作為內容被儲存進資料庫

在對應的Service中我們只需要這樣使用

User user = new User();
user.setName("張%");// 或者user.setName("%趙%");
List<User> list = userMapper.list(user);

是不是很方便呢?

當然你的其他方法可以繼續在相應的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 cn.miw.rpc.batis.comm.GeneralMapper;
import cn.miw.rpc.model.User;
/**
 * 使用者Mapper,定義其他常規的方便方法
 * @author mrzhou
 *
 */
@Mapper
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);
}

各位看包名, 其實我這個假期是在研究一些rpc的東西, 順帶折騰了一下mybatis. 希望對各位看官有幫助.