1.Configuration是配置解析的核心对象,类图如下:
RawSqlSource/DynamicSqlSource最终都会使用到StaticSqlSource封装sql语句,前者在解析xml时就已经实例化StaticSqlSource,后者在执行sql时实例化,即动态SQL。
2.sq语句解析
#{}与${}的区别
1.${}传参为动态sql,对应DynamicSqlSource,会在提交数据库执行前组装好完整的sql语句。
2.#{}传参为静态传参,SQL语句参数处使用“?”替代,如果需要动态传递库表名称,#{}的方式无能为力,只能使用${}。
3.尽量能用#{},${}有SQL注入风险,而且每次执行SQL前都需要解析SQL文本节点,然后进行变量替换生成最终的SQL语句。
3.动态代理
回顾下JDK动态代理:
public interface OneInterface {
void sayHello();
}
public class TestProxy {
public static void main(String[] args) {
InvocationHandler h = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(proxy.getClass().getCanonicalName() + " :: " + method.getName());
System.out.println("Hello!");
return null;
}
};
OneInterface proxyInstance = (OneInterface) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{OneInterface.class}, h);
proxyInstance.sayHello();
}
}
4.其他
若mapUnderscoreToCamelCase设置为true,则支持下划线连接的字段到驼峰式属性的映射,如deal_id对应dealId,从源码Reflect看实际上也可以对应到dEalid,根据SQL字段名查找属性名时忽略大小写,所以对于SQL字段de_alid和deal_id,获取到的JAVA对象属性是同一个,这一点需要注意一下。
属性名支持“.”分隔的多级属性,也支持下标形式的数组/list/map,不过这种属性映射都需要在用户自己配置字段和属性的映射。
5.用法示例
String resource = "demo/resources/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
try {
TestMapper mapper = session.getMapper(TestMapper.class);
TestEntity result = mapper.selectOne(17);
System.out.println(result);
} finally {
session.close();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://IP:PORT:5002/XX"/>
<property name="username" value="XX"/>
<property name="pass**" value="pass"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="demo/mapper/TestMapper.xml" />
</mappers>
</configuration>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="demo.mapper.TestMapper">
<!-- 这里的id必须和UserMapper接口中的接口方法名相同 -->
<select id="selectOne" resultType="demo.entity.TestEntity" parameterType="java.lang.Integer">
select * from table1 where id=#{id}
</select>
</mapper>