介绍MyBatis
- 目前最主流的持久层框架为hibernate与mybatis,而且国内目前情况使用Mybatis的公司比hibernate要多。
- Hibernate学习门槛不低,要精通门槛更高。门槛高在怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate缓存与数据加载策略方面需要你的经验和能力都很强才行。国内目前前的情况精通hibernate技术大牛非常少。
- sql优化方面,Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。当然了,Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。说得更深入一些,如果有个查询要关联多张表,比如5张表,10张表时,而且,我们要取的字段只是其中几张表的部分字段。这时用hibernate时就会显得非常力不从心。就算用hibernate的sqlquery,后续的维护工作也会让人发狂。
1.工程搭建
我感觉框架的工作就是把许多事情都帮你去完成了,越是简洁的代码,背后实现的原理也就越复杂,每一个框架学习最难适应的就是工程的搭建,即入门。
1.1导jar包
1.2准备pojo类(实体类相当于JavaBean)
mybatis的查询返回,查询参数的输入都是以对象为实参进行
package pojo;
import java.util.Date;
public class User {
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
private String uuid2;//uuid
public String getUuid2() {
return uuid2;
}
public void setUuid2(String uuid2) {
this.uuid2 = uuid2;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="
+ address + ", uuid2=" + uuid2 + "]";
}
}
1.3配置SqlMapConfig.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>
<!-- 先加载内部标签,再加载外部文件,属性名称一致时,替换内容 -->
<properties resource="db.properties">
<property name="jdbc.username" value="root1"/>
<property name="jdbc.password" value="root"/>
</properties>
<!--
别名配置:
为什么要使用别名:我们的关系映射文件的parameterType往往是一个类名.包名,此时我们需要简写
有两种配置方式
1.单个别名定义:包名.类名
2.别名包扫描器(推荐使用)直接包名,在关系映射中可直接类名,
相当于在使用的时候不用写包名,更加方便
-->
<typeAliases>
<!-- <typeAlias type="pojo.User" alias="user"/> -->
<package name="pojo"/>
</typeAliases>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClass}" />
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<!--
加载mapper映射文件有四种方式
1.加载resource <mapper resource="mybatis/user.xml"/>
2.class扫描(dao动态代理 接口+关系映射文件)<mapper class="Mapper.mapper"/>
要求 :1.映射文件必须和接口位于同一目录
2.映射文件一定要与接口同名(否则映射文件找不到接口)
3.包扫描
使用场景:当我们有几百个pojo的接口时,需要对某一个包下面的配置文件进行同一扫描
要求 :1.映射文件必须和接口位于同一目录
2.映射文件一定要与接口同名(否则映射文件找不到接口)
4.<mapper url=""/>绝对路径(从磁盘上找,一般不使用该方法)
-->
<mappers>
<!-- resource基于calsspath的路径去查找 -->
<!--<mapper resource="mybatis/userMapper.xml"/> -->
<!-- <mapper class="Mapper.mapper"/> -->
<mapper resource="mybatis/user.xml"/>
<package name="Mapper"/>
</mappers>
</configuration>
1.4配置关系映射文件(多个)
关系映射配置文件一般是对某一个实体的增删查改操作封装在一个映射文件中,在SqlMapConfig.xml中注入,实际开发中有多个。
user.xml
<?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">
<!-- nameSpace:命名空间,用于分离sql语句 -->
<mapper namespace="user">
<!-- id:statementId 语句的唯一标识符
1. resultType:返回结果集的数据类型 ========>包名.类名(如果是查询所有集)
2. parameterType:查询的入参的数据类型 规定死了等一下要传入参数的类型
3. #{}:点位符,相当于JDBC中的 ?
4.${}是字符串拼接符 目的是使我们传入的字符串不用每一次都带一个%String%,如何去掉百分号
!!!如果你要传入的是基本类型,括号里面一定要写value!!!
-->
<select id="getUserById" parameterType="int" resultType="user">
SELECT * FROM USER WHERE id = #{id1}
</select>
<!-- =================================================================================================== -->
<!-- 如果你返回值是为集合(例如一个list),那么你只需要返回值类型填返回list中的类型就行 -->
<select id="getUserByName" parameterType="String" resultType="pojo.User">
<!-- SELECT * FROM USER WHERE username LIKE #{name111} -->
<!-- 注意:
${}是字符串拼接符 目的是使我们传入的字符串不用每一次都带一个%String%,如何去掉百分号
!!!如果你要传入的是基本类型,括号里面一定要写value!!!
-->
SELECT id,username,birthday,sex,address FROM USER WHERE username LIKE '%${value}%';
</select>
<!-- =================================================================================================== -->
<!--插入用户
mysql内部函数:select LAST_INSERT_ID()返回最后一次插入值的ID
#{}占位符里面填User类中的属性 尝试过,必须使用User类中的属性,否则报错
useGeneratedKeys:使用自增
keyProperty,这里是user的主键
这两个配置会自动调用 select LAST_INSERT_ID() mysql自带函数,返回最后一次插入值的ID
-->
<insert id="insertUser" parameterType="pojo.User" useGeneratedKeys="true" keyProperty="id">
<!--
需求:当我们插入一条语句时,我们往往可能将对另外一张表产生影响,需要得到该插入数据的主键ID
selectKey:主键返回
keyProperty:user表中的主键的属性 考虑的是UUID要交给user类的哪一个属性
resultType:主键的数据类型
order:指selectKey在何时执行,AFTER表示在之后,BEFORE表示在之前
将返回的主键返回到user类中的id属性
-->
<!-- <selectKey keyProperty="id" resultType="int" order="AFTER">
select LAST_INSERT_ID()
</selectKey> -->
INSERT INTO mybatis.user ( username, birthday, sex, address)
VALUES(#{username}, #{birthday}, #{sex}, #{address});
</insert>
<!-- ================================================================================================ -->
<!--
一般我们数据表中有时候没有ID,此时需要我们定义一个标识来标致主键
mysql内部函数 select UUID 返回其查询数据表中的唯一标识
-->
<insert id="insertUserUUID" parameterType="pojo.User" useGeneratedKeys="true" keyProperty="id">
<!--
将会将会生成每条数据对应的唯一标识UUID并返回
但是,当使用selectKey的时候,就相当于我们自己定义每条数据的返回标识(主键),
useGeneratedKeys="true" keyProperty="id"不会生效
而generateKey默认使用id为表示并返回,二者取其一
-->
<selectKey keyProperty="uuid2" resultType="String" order="BEFORE">
select UUID()
</selectKey>
INSERT INTO mybatis.user ( username, birthday, sex, address,uuid2)
VALUES(#{username}, #{birthday}, #{sex}, #{address},#{uuid2});
</insert>
<!-- ================================================================================================= -->
<update id="updateUserName" parameterType="pojo.User">
update user set username=#{username} where id=#{id}
</update>
<!-- ================================================================================================== -->
<delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
</delete>
</mapper>
1.5测试类(增删查改)
package Test;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
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 org.junit.Test;
import Utils.SqlSessionFactoryUtils;
import pojo.User;
public class testDemo1 {
//根据用户ID查询用户信息,查询结果是一个
@Test
public void test1() throws Exception{
//1.创建sqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//2.查找配置文件创建输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//3.加载配置文件,创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
//4.创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//注意:SQL中的增删改查方法都在SqlSession对象中
User user = sqlSession.selectOne("user.getUserById",1);
System.out.println(user);
//5.释放资源
sqlSession.close();
}
//根据用户的姓进行模糊查询,返回值是一个集合
@Test
public void test2(){
//通过工具类得到SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
//创建SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//查询,返回一个list
List<User> user = sqlSession.selectList("user.getUserByName","张");
for(User u:user){
System.out.println(u);
}
//关闭资源
sqlSession.close();
}
//插入用户
@Test
public void test3(){
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
//设置为true,sqlSession会默认提交 就不用手动提交 openSession.commit();
// SqlSession openSession = sqlSessionFactory.openSession(true);
User user = new User();
user.setUsername("大虎22");
user.setAddress("宜昌");
user.setBirthday(new Date());
user.setSex("1");
//通过selectKey将插入后生成的主键返回
openSession.insert("user.insertUser", user);
System.out.println(user);
//提交事务(默认不提交)
openSession.commit();
openSession.close();
}
//插入用户,返回UUID
@Test
public void test4(){
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
//设置为true,sqlSession会默认提交 就不用手动提交 openSession.commit();
// SqlSession openSession = sqlSessionFactory.openSession(true);
User user = new User();
user.setUsername("大虎24");
user.setAddress("宜昌");
user.setBirthday(new Date());
user.setSex("1");
//通过selectKey将插入后生成的主键返回
openSession.insert("user.insertUserUUID", user);
System.out.println(user);
//提交事务(默认不提交)
openSession.commit();
openSession.close();
}
//更新
//--------------------------------注意:更新与删除后一定要提交事务
@Test
public void test5(){
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
User user = new User();
user.setId(10);
user.setUsername("大虎25");
//通过selectKey将插入后生成的主键返回
// openSession.insert("user.updateUserName", user);
//注意:此处用insert、select都可以达到相同的效果,但是为了规范
openSession.update("user.updateUserName", user);
System.out.println(user);
//提交事务(默认不提交)
openSession.commit();
openSession.close();
}
//删除
@Test
public void test6(){
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
openSession.delete("user.deleteUser",30);
//提交事务(默认不提交)
openSession.commit();
openSession.close();
}
}
mybatis的核心类:SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession
1.6入门小结
- 连接池的配置是在SqlMapConfig.xml映射文件中配置完毕的。其中就包括了数据库的连接。
- sql查询语句的配置是在关系映射文件中实现的,在此工程下是user.xml
- 框架图(记)
框架图的解释:
MyBatis有两种配置文件- 核心配置文件SqlMapConfig.xml(一个)
- 关系映射配置文件(多个)一般对应表的数量
通过SqlSeessionFactoryBulder类连加载
SqlSession只是一个接口,真正干活的是底层的执行器(Executor)
2.MyBatis的dao开发(两种实现方式,推荐第二种)
2.1原始dao开发
注:使用原有的user.xml关系配置文件
- 定义一个UserDao接口
package dao;
import java.util.List;
import pojo.User;
/*当我们@param id
* @return
* 这些的时候,在我们从别的类里面去调用的时候,也会看到其中的注释
* 养成好习惯,便于调用接口的时候,知道该接口是干嘛用的
*/
/**
* 用户信息持久化接口
* @author rong
*
*/
public interface UserDao {
/**
* 根据用户ID查询用户信息
* @param id
* @return
*/
public User getUserById(Integer id);
/**
* 根据用户名查找用户列表
* @param name
* @return
*/
public List<User>getUserByName(String name);
/**
* 添加用户
* @param user
*/
public void insertUser(User user);
}
- 定义接口的实现类
package dao.impl;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import Utils.SqlSessionFactoryUtils;
import dao.UserDao;
import pojo.User;
/**
* 用户信息接口实现类
* @author rong
*
*/
public class UserDaoImpl implements UserDao {
@Override
public User getUserById(Integer id) {
SqlSession openSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
User user = openSession.selectOne("user.getUserById",10);
openSession.close();
return user;
}
@Override
public List<User> getUserByName(String name) {
// TODO Auto-generated method stub
SqlSession openSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
List<User> users = openSession.selectList("user.getUserByName", name);
openSession.close();
return users;
}
@Override
public void insertUser(User user) {
// TODO Auto-generated method stub
SqlSession openSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
openSession.insert("user.insertUser", user);
openSession.commit();
openSession.close();
}
}
- 测试类
小技巧:使用dao测试 一键生成
package Test;
import static org.junit.Assert.fail;
import java.util.Date;
import java.util.List;
import org.junit.Test;
import dao.UserDao;
import dao.impl.UserDaoImpl;
import pojo.User;
/**
* 直接针对接口生成测试类
* @author rong
*
*/
public class UserDaoTest {
@Test
public void testGetUserById() {
UserDao userDao=new UserDaoImpl();
User user = userDao.getUserById(10);
System.out.println(user);
}
@Test
public void testGetUserByName() {
UserDao userDao=new UserDaoImpl();
List<User> users = userDao.getUserByName("张");
for(User u:users){
System.out.println(u);
}
}
@Test
public void testInsertUser() {
UserDao userDao=new UserDaoImpl();
User user = new User();
user.setUsername("大虎25");
user.setAddress("宜昌");
user.setBirthday(new Date());
user.setSex("1");
userDao.insertUser(user);
}
}
2.2接口动态代理(只有接口,没有实现类)
1 定义dao接口
package Mapper;
import java.util.List;
import pojo.User;
/*当我们@param id
* @return
* 这些的时候,在我们从别的类里面去调用的时候,也会看到其中的注释
* 养成好习惯,便于调用接口的时候,知道该接口是干嘛用的
*/
/**
* 用户信息持久化接口(dao动态代理)核心方法openSession.getMapper(mapper.class)得到代理对象
* @author rong
*
*/
public interface mapper{
/**
* 根据用户ID查询用户信息
* @param id
* @return
*/
public User getUserById(Integer id);
/**
* 根据用户名查找用户列表
* @param name
* @return
*/
public List<User>getUserByName(String name);
/**
* 添加用户
* @param user
*/
public void insertUser(User user);
}
- 关系配置文件的规则
1.namespace必需是接口的全路径名
2.接口的方法名必需与映射文件的sql id一致
3.接口的输入参数必需与映射文件的parameterType类型一致
4.接口的返回类型必须与映射文件的resultType类型一致
<?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">
<!--
dao的动态代理规则:
1.namespace必须是dao接口类的全路径
2.映射文件的sql ID必须与接口的方法名一致
3.映射文件parameterType的类型必须与接口输入参数一致
4.映射文件的resultType的类型必须与接口的输出参数一致
-->
<mapper namespace="Mapper.mapper">
<select id="getUserById" parameterType="int" resultType="pojo.User">
SELECT *
FROM USER WHERE id = #{id1}
</select>
<!-- =================================================================================================== -->
<!-- 如果你返回值是为集合(例如一个list),那么你只需要返回值类型填返回list中的类型就行 -->
<select id="getUserByName" parameterType="String" resultType="pojo.User">
<!-- SELECT * FROM USER WHERE username LIKE #{name111} -->
<!-- 注意: ${}是字符串拼接符 目的是使我们传入的字符串不用每一次都带一个%String%,如何去掉百分号 !!!如果你要传入的是基本类型,括号里面一定要写value!!! -->
SELECT id,username,birthday,sex,address FROM USER WHERE username LIKE
'%${value}%';
</select>
<!-- =================================================================================================== -->
<!--插入用户 mysql内部函数:select LAST_INSERT_ID()返回最后一次插入值的ID #{}占位符里面填User类中的属性
尝试过,必须使用User类中的属性,否则报错 useGeneratedKeys:使用自增 keyProperty,这里是user的主键 这两个配置会自动调用
select LAST_INSERT_ID() mysql自带函数,返回最后一次插入值的ID -->
<insert id="insertUser" parameterType="pojo.User"
useGeneratedKeys="true" keyProperty="id">
<!-- 需求:当我们插入一条语句时,我们往往可能将对另外一张表产生影响,需要得到该插入数据的主键ID selectKey:主键返回 keyProperty:user表中的主键的属性
考虑的是UUID要交给user类的哪一个属性 resultType:主键的数据类型 order:指selectKey在何时执行,AFTER表示在之后,BEFORE表示在之前
将返回的主键返回到user类中的id属性 -->
<!-- <selectKey keyProperty="id" resultType="int" order="AFTER"> select
LAST_INSERT_ID() </selectKey> -->
INSERT INTO mybatis.user ( username, birthday, sex, address)
VALUES(#{username}, #{birthday}, #{sex}, #{address});
</insert>
<!-- ================================================================================================ -->
<update id="updateUserName" parameterType="pojo.User">
update user set username=#{username} where id=#{id}
</update>
<!-- ================================================================================================== -->
<delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
</delete>
</mapper>
- 在SqlMapConfig中加载映射文件
<mappers>
<!-- resource基于calsspath的路径去查找 -->
<mapper resource="mybatis/userMapper.xml"/>
<mapper resource="mybatis/user.xml"/>
</mappers>
- 测试类
那么,动态代理将会自动帮我们
核心方法 openSession.getMapper(mapper.class)返回该类口的一个匿名实现类,你只需要用接口去接
package Test;
import java.util.Date;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import Mapper.mapper;
import Utils.SqlSessionFactoryUtils;
import pojo.User;
/**
* dao动态代理的测试类
* @author rong
*
*/
public class mapperTest {
@Test
public void testGetUserById() {
SqlSession openSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
//获得代理对象,传入的参数是接口的class文件
mapper mapp = openSession.getMapper(mapper.class);
User user = mapp.getUserById(10);
System.out.println(user);
openSession.close();
}
@Test
public void testGetUserByName() {
SqlSession openSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
//获得代理对象
mapper mapp = openSession.getMapper(mapper.class);
List<User> users = mapp.getUserByName("大");
for(User user:users){
System.out.println(user);
}
openSession.close();
}
@Test
public void testInsertUser() {
SqlSession openSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
//获得代理对象
mapper mapp = openSession.getMapper(mapper.class);
User user = new User();
user.setUsername("大虎26");
user.setAddress("宜昌");
user.setBirthday(new Date());
user.setSex("1");
mapp.insertUser(user);
openSession.commit();
openSession.close();
}
}
3.SqlMapConfig.xml配置
SqlMapConfig.xml作为mybatis的核心配置文件,其约束采用DTD,其各个标签的含义如下:
3.1 properties配置
配置原因:在我们配置数据库连接词时往往有许多参数,我们需要把这些参数抽取出来方便统一化管理。
db.properties
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
3.2 typeAliases(别名配置)
别名配置:
为什么要使用别名:我们的关系映射文件的parameterType往往是一个类名.包名,此时我们需要简写
有两种配置方式
1.单个别名定义:包名.类名
2.别名包扫描器(推荐使用)直接包名,在关系映射中可直接类名,
相当于在使用的时候不用写包名,更加方便
3.3mappers(映射器配置)
加载mapper映射文件有四种方式
1.加载resource
2.class扫描(dao动态代理 接口+关系映射文件)
要求 :1.映射文件必须和接口位于同一目录
2.映射文件一定要与接口同名(否则映射文件找不到接口)
3.包扫描
使用场景:当我们有几百个pojo的接口时,需要对某一个包下面的配置文件进行同一扫描
要求 :1.映射文件必须和接口位于同一目录
2.映射文件一定要与接口同名(否则映射文件找不到接口)
4.绝对路径(从磁盘上找,一般不使用该方法)
最后将上述操作放在一起SqlMapConfig.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>
<!-- 先加载内部标签,再加载外部文件,属性名称一致时,替换内容 -->
<properties resource="db.properties">
<property name="jdbc.username" value="root1"/>
<property name="jdbc.password" value="root"/>
</properties>
<!--
别名配置:
为什么要使用别名:我们的关系映射文件的parameterType往往是一个类名.包名,此时我们需要简写
有两种配置方式
1.单个别名定义:包名.类名
2.别名包扫描器(推荐使用)直接包名,在关系映射中可直接类名,
相当于在使用的时候不用写包名,更加方便
-->
<typeAliases>
<!-- <typeAlias type="pojo.User" alias="user"/> -->
<package name="pojo"/>
</typeAliases>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClass}" />
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<!--
加载mapper映射文件有四种方式
1.加载resource <mapper resource="mybatis/user.xml"/>
2.class扫描(dao动态代理 接口+关系映射文件)<mapper class="Mapper.mapper"/>
要求 :1.映射文件必须和接口位于同一目录
2.映射文件一定要与接口同名(否则映射文件找不到接口)
3.包扫描
使用场景:当我们有几百个pojo的接口时,需要对某一个包下面的配置文件进行同一扫描
要求 :1.映射文件必须和接口位于同一目录
2.映射文件一定要与接口同名(否则映射文件找不到接口)
4.<mapper url=""/>绝对路径(从磁盘上找,一般不使用该方法)
-->
<mappers>
<!-- resource基于calsspath的路径去查找 -->
<!--<mapper resource="mybatis/userMapper.xml"/> -->
<!-- <mapper class="Mapper.mapper"/> -->
<mapper resource="mybatis/user.xml"/>
<package name="Mapper"/>
</mappers>
</configuration>