1.1 根据 ID 查询


    1.1.1 在持久层接口中添加 findById 方法


 

/**
* 根据 id 查询
* @param userId
* @return
*/
User findById(Integer userId);

在用户的映射配置文件中配置

<!-- 根据 id 查询 -->
<select id="findById" resultType="com.itheima.domain.User" parameterType="int">
select * from user where id = #{uid}
</select>

细节 

resultType 属性:
    用于指定结果集的类型。
parameterType 属性:

    用于指定传入参数的类型。
sql 语句中使用#{}字符:
    它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。
    具体的数据是由#{}里面的内容决定的。
#{}中内容的写法:
    由于数据类型是基本类型,所以此处可以随意写。

    1.1.3 在测试类添加测试

/**
* 
* <p>Title: MybastisCRUDTest</p>
* <p>Description: 测试 mybatis 的 crud 操作</p>
* <p>Company: http://www.itheima.com/ </p>
*/
public class MybastisCRUDTest {
private InputStream in ;
private SqlSessionFactory factory;
private SqlSession session;
private IUserDao userDao;
@Test
public void testFindOne() {
//6.执行操作
User user = userDao.findById(41);
System.out.println(user);
}
@Before//在测试方法执行之前执行
public void init()throws Exception {
//1.读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建构建者对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.创建 SqlSession 工厂对象
factory = builder.build(in);
//4.创建 SqlSession 对象
session = factory.openSession();
//5.创建 Dao 的代理对象
userDao = session.getMapper(IUserDao.class);
}
@After//在测试方法执行完成之后执行
public void destroy() throws Exception{
session.commit();
//7.释放资源
session.close();
in.close();
}
}


1.2 保存操作


     1.2.1 在持久层接口中添加新增方法


/**
* 保存用户
* @param user
* @return 影响数据库记录的行数
*/
int saveUser(User user);

     1.2.2 在用户的映射配置文件中配置


<!-- 保存用户-->
<insert id="saveUser" parameterType="com.itheima.domain.User">
insert into user(username,birthday,sex,address) 
values(#{username},#{birthday},#{sex},#{address})
</insert>

细节

parameterType 属性:
    代表参数的类型,因为我们要传入的是一个类的对象,所以类型就写类的全名称。
sql 语句中使用#{}字符:
    它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。
    具体的数据是由#{}里面的内容决定的。
#{}中内容的写法:
    由于我们保存方法的参数是 一个 User 对象,此处要写 User 对象中的属性名称。
    它用的是 ognl 表达式。
ognl 表达式:
    它是 apache 提供的一种表达式语言,全称是:
        Object Graphic Navigation Language 对象图导航语言
    它是按照一定的语法格式来获取数据的。
        语法格式就是使用 #{对象.对象}的方式
        #{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用
    getUsername()方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user.
    而直接写 username


    1.2.3 添加测试类中的测试方法


@Test
public void testSave(){
User user = new User();
user.setUsername("modify User property");
user.setAddress("北京市顺义区");
user.setSex("男");
user.setBirthday(new Date());
System.out.println("保存操作之前:"+user);
//5.执行保存方法
userDao.saveUser(user);
System.out.println("保存操作之后:"+user);
}

    打开 Mysql 数据库发现并没有添加任何记录,原因是什么?
    这一点和 jdbc 是一样的,我们在实现增删改时一定要去控制事务的提交,那么在 mybatis 中如何控制事务
提交呢?
    可以使用:session.commit();来实现事务提交。加入事务提交后的代码如下:

@After//在测试方法执行完成之后执行
public void destroy() throws Exception{
session.commit();
//7.释放资源
session.close();
in.close();
}

       1.2.4 问题扩展:新增用户 id 的返回值


       新增用户后,同时还要返回当前新增用户的 id 值,因为 id 是由数据库的自动增长来实现的,所以就相



当于我们要在新增后将自动增长 auto_increment 的值返回。



<insert id="saveUser" parameterType="USER">
<!-- 配置保存时获取插入的 id -->
<selectKey keyColumn="id" keyProperty="id" resultType="int"  order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,birthday,sex,address) 
values(#{username},#{birthday},#{sex},#{address})
</insert>

1.3 用户更新

     1.3.1 在持久层接口中添加更新方法


/**
* 更新用户
* @param user
* @return 影响数据库记录的行数
*/
int updateUser(User user);



       1.3.2 在用户的映射配置文件中配置



 



<!-- 更新用户 -->
<update id="updateUser" parameterType="com.itheima.domain.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},
address=#{address} where id=#{id}
</update>

.3.3 加入更新的测试方法



@Test
public void testUpdateUser()throws Exception{
//1.根据 id 查询
User user = userDao.findById(52);
//2.更新操作
user.setAddress("北京市顺义区");
int res = userDao.updateUser(user);
System.out.println(res);
}



1.4 用户删除



 



         1.4.1 在持久层接口中添加删除方法



/**
* 根据 id 删除用户
* @param userId
* @return
*/
int deleteUser(Integer userId);

       1.4.2 在用户的映射配置文件中配置



<!-- 删除用户 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id = #{uid}
</delete>

.4.3 加入删除的测试方法

@Test
public void testDeleteUser() throws Exception {
//6.执行操作
int res = userDao.deleteUser(52);
System.out.println(res);
}



1.5 用户模糊查询



 



       1.5.1 在持久层接口中添加模糊查询方法



/**
* 根据名称模糊查询
* @param username
* @return
*/
List<User> findByName(String username);

        


       1.5.2 在用户的映射配置文件中配置



 



<!-- 根据名称模糊查询 -->
<select id="findByName" resultType="com.itheima.domain.User" parameterType="String">
 select * from user where username like #{username}
</select>



         1.5.3 加入模糊查询的测试方法



@Test
 public void testFindByName(){//5.执行查询一个方法
 List<User> users = userDao.findByName("%王%");
 for(User user : users){
 System.out.println(user);
 }
 }




java mybatis sql注入 mybatis service 注入不了dao_sql


      我们在配置文件中没有加入%来作为模糊查询的条件,所以在传入字符串实参时,就需要给定模糊查询的标
识%。配置文件中的#{username}也只是一个占位符,所以 SQL 语句显示为“?”。


 


.5.4 模糊查询的另一种配置方式


第一步:修改 SQL 语句的配置,配置如下:


<!-- 根据名称模糊查询 -->
<select id="findByName" parameterType="string" resultType="com.itheima.domain.User">
 select * from user where username like '%${value}%'
</select>


       我们在上面将原来的 #{} 占位符,改成了 ${value} 。注意如果用模糊查询的这种写法,那么 ${value} 的写


法就是固定的,不能写成其它名字。


 


             第二步:测试,如下:


/**
* 测试模糊查询操作
 */
@Test
public void testFindByName(){
 //5.执行查询一个方法
List<User> users = userDao.findByName("王");
for(User user : users){
System.out.println(user);
}
}


java mybatis sql注入 mybatis service 注入不了dao_java mybatis sql注入_02


 


        1.5.5 #{}与 ${}的区别


 


#{}表示一个占位符号
  通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换,
#{}可以有效防止 sql 注入。 #{}可以接收简单类型值或 pojo 属性值。 如果 parameterType 传输单个简单类
  型值,#{}括号中可以是 value 或其它名称。
${}表示拼接 sql 串
  通过${}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换, ${}可以接收简
  单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,${}括号中只能是 value。


 


 


1.6 查询使用聚合函数


 


 


      1.6.1 在持久层接口中添加模糊查询方法


/**
* 查询总记录条数
* @return
*/
int findTotal();

      

        1.6.2 在用户的映射配置文件中配置


<!-- 查询总记录条数 -->
<select id="findTotal" resultType="int">
select count(*) from user;
</select>


        1.6.3 加入聚合查询的测试方法


@Test
public void testFindTotal() throws Exception {
//6.执行操作
int res = userDao.findTotal();
System.out.println(res);
}


1.7 Mybatis JDBC 编程的比较


 1.数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
解决:
    在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。
2.Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。
解决:
    将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。
3.向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需要和参数对应。
解决:
    Mybatis 自动将 java 对象映射至 sql 语句,通过 statement 中的 parameterType 定义输入参数的
类型。
4.对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对
象解析比较方便。
解决:
    Mybatis 自动将 sql 执行结果映射至 java 对象,通过 statement 中的 resultType 定义输出结果的类型。


 


 


2.1 parameterType 配置参数


     


.1.1 使用说明


       SQL 语句传参,使用标签的 parameterType 属性来设定。该属性的取值可以 是基本类型,引用类型(例如:String 类型),还可以是实体类类型( POJO 类)。同时也可以使用实体类的包 类,本章节将介绍如何使用实体类的包装类作为参数传递。


 


       2.1.2 注意事项


        基本类型和String我们可以直接写类型名称也可以使用包名.类名的方式,例如 :java.lang.String。实体类类型,目前我们只能使用全限定类名。
究其原因,是 mybaits 在加载时已经把常用的数据类型注册了别名,从而我们在使用时可以不写包名,而我们的是实体类并没有注册别名,所以必须写全限定类名。


 


2.2 传递 pojo 包装对象

      

开发中通过 pojo 传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查 询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。


Pojo 类中包含 pojo 。


需求:根据用户名查询用户信息,查询条件放到 QueryVo 的 user 属性中。


/**
* 
* <p>Title: QueryVo</p>
* <p>Description: 查询条件对象</p>
* <p>Company: http://www.itheima.com/ </p>
*/
public class QueryVo implements Serializable {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}


          2.2.2 编写持久层接口


/**
* 
* <p>Title: IUserDao</p>
* <p>Description: 用户的业务层接口</p>
* <p>Company: http://www.itheima.com/ </p>
*/
public interface IUserDao {
/**
* 根据 QueryVo 中的条件查询用户
* @param vo
* @return
*/
List<User> findByVo(QueryVo vo);
}


          2.2.3 持久层接口的映射文件


<!-- 根据用户名称模糊查询,参数变成一个 QueryVo 对象了 -->
<select id="findByVo" resultType="com.itheima.domain.User"
 parameterType="com.itheima.domain.QueryVo">
select * from user where username like #{user.username};
</select>


         2.2.4 测试包装类作为参数


@Test
public void testFindByQueryVo() {
QueryVo vo = new QueryVo();
User user = new User();
user.setUserName("%王%");
vo.setUser(user);
List<User> users = userDao.findByVo(vo);
for(User u : users) {
System.out.println(u);
}
}


3.1 resultType 配置结果类型


 


    resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型。
    我们在前面的 CRUD 案例中已经对此属性进行过应用了。
    需要注意的是,它和 parameterType 一样,如果注册过类型别名的,可以直接使用别名。没有注册过的必须使用全限定类名。例如:我们的实体类此时必须是全限定类名(今天最后一个章节会讲解如何配置实体类的别名)
    同时,当是实体类名称是,还有一个要求,实体类中的属性名称必须和查询语句中的列名保持一致,否则无法实现封装。


 


    3.1.1 定义 resultMap


<!-- 建立 User 实体和数据库表的对应关系
type 属性:指定实体类的全限定类名
id 属性:给定一个唯一标识,是给查询 select 标签引用用的。
-->
<resultMap type="com.itheima.domain.User" id="userMap">
<id column="id" property="userId"/>
<result column="username" property="userName"/>
<result column="sex" property="userSex"/>
<result column="address" property="userAddress"/>
<result column="birthday" property="userBirthday"/>
</resultMap>


id 标签:用于指定主键字段


result 标签:用于指定非主键字段


column 属性:用于指定数据库列名


property 属性:用于指定实体类属性名称


 


映射配置


@Test
public void testFindAll() {
List<User> users = userDao.findAll();
for(User user : users) {
System.out.println(user);
}
}

4.1 SqlMapConfig.xml配置文件

     4.1.1 SqlMapConfig.xml 中配置的内容和顺序

-properties(属性)
--property
-settings(全局配置参数)
--setting
-typeAliases(类型别名)
--typeAliase
--package
-typeHandlers(类型处理器)
-objectFactory(对象工厂)
-plugins(插件)
-environments(环境集合属性对象)
--environment(环境子属性对象)
---transactionManager(事务管理)
---dataSource(数据源)
-mappers(映射器)
--mapper
--package


4.2 properties (属性)


   在使用 properties 标签配置时,我们可以采用两种方式指定属性配置。


 


第一种


<properties>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/eesy"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="1234"/>
</properties>

第二种


classpath 下定义 db.properties 文件


jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy
jdbc.username=root
jdbc.password=1234


properties 标签配置


<!-- 配置连接数据库的信息
resource 属性:用于指定 properties 配置文件的位置,要求配置文件必须在类路径下
resource="jdbcConfig.properties"
url 属性:
URL: Uniform Resource Locator 统一资源定位符
http://localhost:8080/mystroe/CategoryServlet URL
协议 主机 端口 URI
URI:Uniform Resource Identifier 统一资源标识符
/mystroe/CategoryServlet
它是可以在 web 应用中唯一定位一个资源的路径
-->
<properties url=
file:///D:/IdeaProjects/day02_eesy_01mybatisCRUD/src/main/resources/jdbcConfig.prop
erties">
</properties>


此时我们的 dataSource 标签就变成了引用上面的配置


<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>


 


 


 


java mybatis sql注入 mybatis service 注入不了dao_mysql_03


IUserDao

package com.itheima.dao;

import com.itheima.domain.QueryVo;
import com.itheima.domain.User;

import java.util.List;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 *
 * 用户的持久层接口
 */
public interface IUserDao {

    /**
     * 查询所有用户
     * @return
     */
    List<User> findAll();

    /**
     * 保存用户
     * @param user
     */
    void saveUser(User user);

    /**
     * 更新用户
     * @param user
     */
    void updateUser(User user);

    /**
     * 根据Id删除用户
     * @param userId
     */
    void deleteUser(Integer userId);

    /**
     * 根据id查询用户信息
     * @param userId
     * @return
     */
    User findById(Integer userId);

    /**
     * 根据名称模糊查询用户信息
     * @param username
     * @return
     */
    List<User> findByName(String username);

    /**
     * 查询总用户数
     * @return
     */
    int findTotal();

    /**
     * 根据queryVo中的条件查询用户
     * @param vo
     * @return
     */
    List<User> findUserByVo(QueryVo vo);
}

IUserDao

<?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.itheima.dao.IUserDao">

    <!-- 配置 查询结果的列名和实体类的属性名的对应关系 -->
    <resultMap id="userMap" type="uSeR">
        <!-- 主键字段的对应 -->
        <id property="userId" column="id"></id>
        <!--非主键字段的对应-->
        <result property="userName" column="username"></result>
        <result property="userAddress" column="address"></result>
        <result property="userSex" column="sex"></result>
        <result property="userBirthday" column="birthday"></result>
    </resultMap>


    <!-- 查询所有 -->
    <select id="findAll" resultMap="userMap">
        <!--select id as userId,username as userName,address as userAddress,sex as userSex,birthday as userBirthday from user;-->
        select * from user;
    </select>

    <!-- 保存用户 -->
    <insert id="saveUser" parameterType="user">
        <!-- 配置插入操作后,获取插入数据的id -->
        <selectKey keyProperty="userId" keyColumn="id" resultType="int" order="AFTER">
            select last_insert_id();
        </selectKey>
        insert into user(username,address,sex,birthday)values(#{userName},#{userAddress},#{userSex},#{userBirthday});
    </insert>

    <!-- 更新用户 -->
    <update id="updateUser" parameterType="USER">
        update user set username=#{userName},address=#{userAddress},sex=#{userAex},birthday=#{userBirthday} where id=#{userId}
    </update>

    <!-- 删除用户-->
    <delete id="deleteUser" parameterType="java.lang.Integer">
        delete from user where id = #{uid}
    </delete>
    
    <!-- 根据id查询用户 -->
    <select id="findById" parameterType="INT" resultMap="userMap">
        select * from user where id = #{uid}
    </select>

    <!-- 根据名称模糊查询 -->
    <select id="findByName" parameterType="string" resultMap="userMap">
          select * from user where username like #{name}
        <!-- select * from user where username like '%${value}%'-->
   </select>

    <!-- 获取用户的总记录条数 -->
    <select id="findTotal" resultType="int">
        select count(id) from user;
    </select>

    <!-- 根据queryVo的条件查询用户 -->
    <select id="findUserByVo" parameterType="com.itheima.domain.QueryVo" resultMap="userMap">
        select * from user where username like #{user.username}
    </select>
</mapper>

test

package com.itheima.test;

import com.itheima.dao.IUserDao;
import com.itheima.domain.QueryVo;
import com.itheima.domain.User;
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.After;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 *
 * 测试mybatis的crud操作
 */
public class MybatisTest {

    private InputStream in;
    private SqlSession sqlSession;
    private IUserDao userDao;

    @Before//用于在测试方法执行之前执行
    public void init()throws Exception{
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.获取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.获取SqlSession对象
        sqlSession = factory.openSession();
        //4.获取dao的代理对象
        userDao = sqlSession.getMapper(IUserDao.class);
    }

    @After//用于在测试方法执行之后执行
    public void destroy()throws Exception{
        //提交事务
        sqlSession.commit();
        //6.释放资源
        sqlSession.close();
        in.close();
    }

    /**
     * 测试查询所有
     */
    @Test
    public void testFindAll(){
        //5.执行查询所有方法
        List<User> users = userDao.findAll();
        for(User user : users){
            System.out.println(user);
        }

    }

    /**
     * 测试保存操作
     */
    @Test
    public void testSave(){
        User user = new User();
        user.setUserName("modify User property");
        user.setUserAddress("北京市顺义区");
        user.setUserSex("男");
        user.setUserBirthday(new Date());
        System.out.println("保存操作之前:"+user);
        //5.执行保存方法
        userDao.saveUser(user);

        System.out.println("保存操作之后:"+user);
    }

    /**
     * 测试更新操作
     */
    @Test
    public void testUpdate(){
        User user = new User();
        user.setUserId(50);
        user.setUserName("mybastis update user");
        user.setUserAddress("北京市顺义区");
        user.setUserSex("女");
        user.setUserBirthday(new Date());

        //5.执行保存方法
        userDao.updateUser(user);
    }

    /**
     * 测试删除操作
     */
    @Test
    public void testDelete(){
        //5.执行删除方法
        userDao.deleteUser(48);
    }

    /**
     * 测试删除操作
     */
    @Test
    public void testFindOne(){
        //5.执行查询一个方法
        User  user = userDao.findById(50);
        System.out.println(user);
    }

    /**
     * 测试模糊查询操作
     */
    @Test
    public void testFindByName(){
        //5.执行查询一个方法
        List<User> users = userDao.findByName("%王%");
//        List<User> users = userDao.findByName("王");
        for(User user : users){
            System.out.println(user);
        }
    }

    /**
     * 测试查询总记录条数
     */
    @Test
    public void testFindTotal(){
        //5.执行查询一个方法
        int count = userDao.findTotal();
        System.out.println(count);
    }


    /**
     * 测试使用QueryVo作为查询条件
     */
    @Test
    public void testFindByVo(){
        QueryVo vo = new QueryVo();
        User user = new User();
        user.setUserName("%王%");
        vo.setUser(user);
        //5.执行查询一个方法
        List<User> users = userDao.findUserByVo(vo);
        for(User u : users){
            System.out.println(u);
        }
    }
}

SqlMapConfig

<?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属性: 常用的
            用于指定配置文件的位置,是按照类路径的写法来写,并且必须存在于类路径下。
        url属性:
            是要求按照Url的写法来写地址
            URL:Uniform Resource Locator 统一资源定位符。它是可以唯一标识一个资源的位置。
            它的写法:
                http://localhost:8080/mybatisserver/demo1Servlet
                协议      主机     端口       URI

            URI:Uniform Resource Identifier 统一资源标识符。它是在应用中可以唯一定位一个资源的。
    -->
    <properties resource="jdbcConfig.properties">
       <!-- <property name="driver" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"></property>
        <property name="username" value="root"></property>
        <property name="password" value="1234"></property>-->
    </properties>

    <!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
    <typeAliases>
        <!--typeAlias用于配置别名。type属性指定的是实体类全限定类名。alias属性指定别名,当指定了别名就再区分大小写 
        <typeAlias type="com.itheima.domain.User" alias="user"></typeAlias>-->

        <!-- 用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写-->
        <package name="com.itheima.domain"></package>
    </typeAliases>

    <!--配置环境-->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务 -->
            <transactionManager type="JDBC"></transactionManager>

            <!--配置连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <!-- 配置映射文件的位置 -->
    <mappers>
        <!--<mapper resource="com/itheima/dao/IUserDao.xml"></mapper>-->
        <!-- package标签是用于指定dao接口所在的包,当指定了之后就不需要在写mapper以及resource或者class了 -->
        <package name="com.itheima.dao"></package>
    </mappers>
</configuration>