目标
- 1、抛弃mapper的xml文件
- 2、根据插入的实体对象,自动生成动态sql
- 3、实现一个简单的动态查询
代码
- mapper接口:
package com.huwc.mapper;
import com.huwc.TestMapperProvider;
import com.huwc.bean.User;
import org.apache.ibatis.annotations.SelectProvider;
import java.util.List;
public interface TestMapper {
@SelectProvider(type = TestMapperProvider.class, method = "select")
public List<User> select(User user);
}
- Provider:
package com.huwc;
import com.huwc.bean.User;
import org.apache.ibatis.jdbc.SQL;
import java.lang.reflect.Field;
public class TestMapperProvider {
public String select(User user) throws IllegalAccessException { ;
return new SQL(){{
SELECT("*");
FROM("hwc_users");
Field[] fields = user.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
if(field.get(user) != null){
WHERE(field.getName()+"=#{"+field.getName()+"}");
}
}
}}.toString();
}
}
通过反射的方式获取传入的实体类的所有属性,并对属性值进行判断,如果非空,则拼接对应的sql语句。
- 测试代码:
@Test
public void test_SqlProvider() throws Exception {
InputStream input = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(input);
SqlSession sqlSession = factory.openSession();
TestMapper mapper = sqlSession.getMapper(TestMapper.class);
User user = new User();
user.setName("胡文超");
user.setAge(35);
List<User> users = mapper.select(user);
for (User u : users) {
System.out.println(u);
}
sqlSession.close();
}
- 测试结果:
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@6ebf0f36]
==> Preparing: SELECT * FROM hwc_users WHERE (name=? AND age=?)
================================= execute sql ==============================
com.mysql.jdbc.JDBC42PreparedStatement@25a6944c: SELECT *
FROM hwc_users
WHERE (name='胡文超' AND age=35)
================================= execute sql ==============================
==> Parameters: 胡文超(String), 35(Integer)
测试结果很完美,由衷的说一句,mybatis的SQL类组装sql语句还是非常好用的,并且有两种代码风格:匿名内部类风格和流式风格。
通用mapper的原理就是使用上面的动态语句生成,后面继续深入学习一下通用mapper的源码。