@[Toc]
Mybatis代理
1、为什么使用Mybatis代理?
Mybatis开发者给了用户两个配置的方式,一个是如我们JavaWeb Mybatis-02-Mybatis的快速入门里的那样单纯使用XML配置,另外一种是直接从Java代码创建配置,这无疑是对Java用户非常友好的。但是Mybatis开发者还说了:“由于 Java 注解的一些限制以及某些 MyBatis 映射的复杂性,要使用大多数高级映射(比如:嵌套联合映射),仍然需要使用 XML 配置。有鉴于此,如果存在一个同名 XML 配置文件,MyBatis 会自动查找并加载它(在这个例子中,基于类路径和 BlogMapper.class 的类名,会加载 BlogMapper.xml)。”这意味着高级映射仍然需要xml文件配置,但是Mybatis又作出一些调整,对于同名的xml配置文件,Mybatis会自动查找并加载它。
Mybatis开发人员指出:这种方法有很多优势,首先它不依赖于字符串字面值,会更安全一点;其次,如果你的 IDE 有代码补全功能,那么代码补全可以帮你快速选择到映射好的 SQL 语句。
2、开始使用Mybatis代理
1)创建一个java接口
对于映射Sql语句的接口来说,它的命名规范一般是“实体类”+“Mapper”的形式。如我此处代码的实体类是Dept,那么我接口的名字即为DeptMapper,当然是于配置文件同名。
package com.you.Mapper;
import com.you.pojo.Dept;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface DeptMapper {
public List<Dept> queryAll();
}
2)DeptMapper.xml文件的修改
DeptMapper.xml有两处要修改的地方,第一是位置,第二是namespace。
小游:为什么要修改namespace?
坦之:在第二篇文章中,namespace并没有发挥作用,因为我们并未使用到接口。Mybatis的开发人员指出,namespace有两种好处,一个是 利用更长的全限定名来将不同的语句隔离开来,另一个便是 实现了接口绑定。这里修改namespace的目的就是为了实现接口绑定,将DeptMapper.interface和DeptMapper.xml通过namespace绑定起来,namespace的值也就是DeptMapper.interface相对于根目录的位置。然后再通过xml文件中sql语句唯一的id和接口中方法名对应起来,找到SQL语句。
<?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="com.you.Mapper.DeptMapper">
<select id="queryAll" resultType="com.you.pojo.Dept">
select * from dept;
</select>
</mapper>
小游:那位置也是一定要修改的吗?
坦之: 不一定,如果你只是很小的项目,你当然可以随便放,只需要config.xml里找到Mapper.xml的位置即可。但是如果你应对的是大的项目,随意乱放Mapper会导致你的代码缺乏可读性,所以我们要养成一个编写代码的规范。
Mapper.xml一般放在resources文件下,在resources文件下,建一个与Mapper.interface一模一样的包,这样二者在工作的时候就被放在了一起, 要注意,在resources文件下,创建多级目录,不应该用' . '分隔,而应该用'/'分隔,而且将所有的Mapper.xml放在同一个文件夹下,还有另外一个好处。
DeptMapper.xml的位置变了,config.xml中的resource也要作相应的变化,这样才能确保找到DeptMapper.xml。
<?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="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/dp83?useSSL=false&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="200201203332"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com\you\Mapper\DeptMapper.xml"/>
</mappers>
</configuration>
坦之:包扫描的优越性
坦之:刚才我们提到,把所有的Mapper文件放在一个包下,还有一个好处,那就是方便配置。就我们当前的知识而言,每多一个Mapper配置文件,都要在config.xml文件中写入,这样的话,Mybatis才可以找到这个文件。
但是有了包扫描后,当再有新的配置文件放到相应的包下,我们就不用手动添加了。
<mappers>
<!-- <mapper resource="com\you\Mapper\DeptMapper.xml"/>-->
<!--包扫描的方式-->
<package name="com.you.Mapper"/>
</mappers>
通过包扫描,当Mapper文件夹下有新的配置文件写入的时候,Mybatis会自动引入。
3)启动类的改动
package com.you;
import com.you.Mapper.DeptMapper;
import com.you.pojo.Dept;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MybatisRun2 {
public static void main(String[] args) {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException ioException) {
ioException.printStackTrace();
}
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
/* 执行sql语句 */
// List<Dept> list = sqlSession.selectList("test.queryAll");
/*通过Mapper接口*/
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
List<Dept> list = mapper.queryAll();
for (Dept dept : list) {
System.out.println(dept);
}
}
}
4)不需要xml配置的Mapper
小游:刚才你说,可以不需要xml文件,这个可以实现吗?
坦之:可以的。对于一些简单的sql语句,我们可以通过@Select这种注解的方式来完成。例如下面的图片,对于这种利用注解映射sql语句的方法,就不需要配置xml文件了。
类型别名(typeAliases)
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。
类型别名有两种配置方式:
对单独类配置类型别名
如下,这样配置的时候,就可以直接写Alias里面的值了
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>
对包配置类型别名
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:
<typeAliases>
<package name="domain.blog"/>
</typeAliases>
每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author;
注意
在配置文件的时候,最好按照以下顺序一次配置, 否则有可能报错