【Java47】Mybatis:两个xml文件的标签


1.mybatis-config.xml核心配置文件中标签:test -> interface/impl -> sql

在这里插入图片描述
在这里插入图片描述

//jdbc.properties文件,如下前面加上jdbc.是防止如上${}字符串拼接拿到下面参数,没有拿到方法中参数
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root
//mybatis-config.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>
    <!--
        1.将jdbc.properties配置文件加载到mybatis的环境中。
        2.通过${key}读取配置文件中的配置信息
        properties声明属性的2种方式:1.resource:相对路径引入外部的properties配置文件
       							    2.property子标签来动态声明
        -->
    <properties resource="jdbc.properties">  <!--在下面第二个environment标签里用到-->
      <!--<property name="username" value="root"></property>-->   <!--这行也可以,不用外部jdbc.properties文件,优先级最低-->
    </properties>

<!--111111111111111111111111111111111111111111111111111111111111111111111111111111111-->
    <settings>
        <!--
            开启驼峰映射
            经典的映射规范 : 数据库列名   A_COLUMN  ————>  属性名  aColumn
         -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

<!--111111111111111111111111111111111111111111111111111111111111111111111111111111111-->    
    <typeAliases>   <!--类型别名-->  <!-- 如下两种方式:这样UserMapper.xml中resultType="User"就行-->
        <!-- 第一种配置方式:typeAlias标签配置单个别名 -->
        <!--<typeAlias type="com.itheima.domain.User" alias="User"></typeAlias>-->       

        <!-- 第二种配置方式:常用,包扫描 ,默认类名就是别名-->
        <package name="com.itheima.domain"></package>
    </typeAliases>

<!--111111111111111111111111111111111111111111111111111111111111111111111111111111111-->
    <!-- 数据源环境:default: 数据源配置的环境的id。默认采用的环境 -->
    <environments default="development">   
    <!-- 配置单个数据源环境,id是当前环境配置的唯一标识。dist生产环境 -->     
        <environment id="development"> 
            <!--
                如下事务管理:
                type: JDBC or MANAGED
                JDBC: 采用jdbc的事务管理。 底层connection.commit/.rollback
                MANAGED: 不采用事务。
             -->
            <transactionManager type="JDBC"/>  <!--采用事务-->
            <!--
                如下配置数据源的具体链接参数:                    
                 type: POOLED: 支持连接池配置,除了最基本的数据源连接参数配置,
                       还可以配置连接池相关的参数如:最大连接数,最大空闲连接数...                                
                       UNPOOLED: 不支持连接池配置。
            -->
            <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>

<!--111111111111111111111111111111111111111111111111111111111111111111111111111111111-->
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driverClass}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="aaa"/>
                <property name="password" value="bbb"/>
            </dataSource>
        </environment>
    </environments>

<!--111111111111111111111111111111111111111111111111111111111111111111111111111111111-->    
    <mappers>  <!--告知mybatis映射文件的位置,一般一个接口对应一个xxxMapper映射文件-->
        <!-- 第一种配置: 相对路径配置映射文件的位置 -->
        <!--<mapper resource="UserMapper.xml"/>-->
        
        <!-- 第二种配置:url绝对路径方式,肯定不用 -->
        <!--  <mapper url="file:///var/mappers/AuthorMapper.xml"/>-->

        
        <!-- 第三种配置:采用接口的全路径配置方式
             此处注意:虽然配置的是类的全路径,但是我们都知道,io流读取资源的本质都是需要知道
                      文件的名字和位置。
                所以: 我们需要通过 com.itheima.mapper.UserMapper
                      能够知道接口对应的映射文件的  位置  和 名字。

         文件的位置和名字必须得满足2个规范: 1.mapper文件名 必须和接口的名字一致。
                                         2.mapper文件 必须和接口放在同一个包下。
         所以将UserMapper.xml和UserMapper.java文件放在com.itheima.mapper文件夹下
        -->
       <!-- <mapper class="com.itheima.mapper.UserMapper"></mapper>-->


        <!-- 第四种配置:包扫描方式 ,基于第三种的规范。-->   <!--要么第一种,要么第四种-->
       <!-- <package name="com.itheima.mapper"></package>-->

        <mapper resource="com/itheima/mapper/UserMapper.xml"></mapper>
        <mapper resource="com/itheima/mapper/commonSql.xml"></mapper> <!--不要忘了引入-->
    </mappers>
</configuration>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.UserMapper.xml映射文件中增删改查标签:文件命,namespace,id,resultType

动态代理规定namespace,id。mybatis-config.xml中< typeAliases > 和< mappers > 规定文件命和resultType。

2.1 UserMapper.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">
<mapper namespace="com.itheima.mapper.UserMapper">
    <!--
        select: 查询的statement(声明),用来编写查询语句
        id: 语句的唯一标识
        resultType:配置返回的结果集类型
        parameterType:传递的参数类型,可以省略
    -->
    <select id="findUserById" resultType="User">
        select * from tb_user where id = #{a}
    </select>

    <!--
        useGeneratedKeys=true, 开启主键的自动回显。(主键必须是自增长的)
        keyProperty="id" 主键属性值回显到的实体的属性名  //user对象的id属性
        keyColumn="id"  主键的列名
     -->
    <insert id="addUser" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        insert into tb_user(user_name,password,name) values(#{userName},#{password},#{name})
    </insert>

    <!--
            #{} : 预编译的传参方式
            1.如果传递 单个 基本类型参数,sql语句中的参数名可以是任意名称,如上findUserById中#{a}  
            2.如果传递的是多个基本类型参数
               a. #{arg0} #{arg1}  或者  #{param1} #{param2} 获取方法传递的参数(不推荐)
               b. 注解方式(推荐),在方法的参数上使用@Param(参数名),
                    在sql语句中 #{参数名} 来引入方法调用时传递的参数,两参数名要一样。
                                        
            3.对象类型的参数:#{property}  property就是对象的属性名。                   
            4.Hash类型的参数:#{key}  key就是map集合中的key。

            ${} : 字符串拼接方式,语法格式和获取properties配置中的参数语法一致,所以加jdbc.区分。
                #{} 预编译方式,参数在传递时,如果是字符串,会自动添加''
                ${} 字符串拼接方式,只是字符串的拼接。预编译可预防sql注入,但是传的参数是sql语句关键字就不行了
     -->
    <select id="findUserByPasswordAndSex" resultType="User">
        select * from tb_user where password=#{p} and sex=#{sex}
    </select>

    <select id="findUserByUsername" resultType="User">
        select * from tb_user where user_name = #{username}
    </select>

    <select id="findUserByHash" resultType="User">
        select * from tb_user where password=#{password} and sex=#{sex}
    </select>

    <select id="findUserByTable" resultType="User">
        select * from ${tableName}
    </select>

    <select id="findUserLikeUsername" resultType="User">
        select * from tb_user where user_name like #{username}
    </select>

<!--11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111-->   
    <select id="findUsersBySex" resultMap="myResultMap">   <!-- 自定义结果集映射:resultMap: 自定义结果集的id -->
        select <include refid="commonSql.mySql"></include> from tb_user where sex = #{sex}
    </select>
    <!--
            id:自定义结果集的唯一标识
            type: 类型。实体的类型,支持别名写法
        autoMapping="true" 自动映射,
            默认值为true,那么会将列名和属性名一致的进行自动映射。
            值为false,只会将我们配置的列进行映射,没有配置的列不进行映射
     -->
    <resultMap id="myResultMap" type="User" autoMapping="false">
        <!--
              配置主键和属性的映射的
              column:主键的列名
              property:实体的属性名
         -->
        <id column="uid" property="id"></id>
        <!-- 如下配置非主键的列的映射的 -->
        <result column="user_name" property="userName"></result>
        <result column="uage" property="age"></result>
    </resultMap>

<!--1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111-->
    <!--
        sql片段:类似抽成函数方法,反复调用
            1.通过<sql>标签来声明一段通用sql
            2.在执行sql时,通过<include refid="namespace.sqlId">来引入声明好的sql
            如下<include refid="mySql"></include>就行
    -->
    <sql id="mySql">
        *,age uage,id uid
    </sql>

	<!-- select * from tb_user where age &lt; #{age}-->
    <select id="findUsersByAge" resultType="User">
        select * from tb_user where age <![CDATA[ < ]]> #{age}
    </select>
</mapper>
//commonSql.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">
<mapper namespace="commonSql">
    <sql id="mySql">
        *,age uage,id uid
    </sql>
</mapper>

2.2 mapper

一个订单可以买多个商品,一种商品可以被多个订单购买,所以订单和商品多对多的关系,需要中间表分别添加另外两个表主键。生成订单详情需要订单的标识id,插入数据库才有id,这个id也只存在数据库中。
在这里插入图片描述

package com.itheima.mapper;
import com.itheima.domain.User;
import org.apache.ibatis.annotations.Param;
import java.util.HashMap;
import java.util.List;

public interface UserMapper {
    
    
    public List<User> findUserByUsername(@Param("username") String username);
    public void addUser(User user);
    public User findUserById(int id);
    public List<User> findUserByPasswordAndSex(@Param("p") String password, @Param("sex") int sex);
    public List<User> findUserByHash(HashMap<String,Object> map);
    // 如下1千万信息放一张表性能低,所以分表两张表,根据表名查询用户的信息
    public List<User> findUserByTable(@Param("tableName") String tableName);
    public List<User> findUserLikeUsername(@Param("username") String username);
    // 如下自定义结果集(驼峰映射和起别名不起作用)
    public List<User> findUsersBySex(@Param("sex") int sex);    
    // 如下查询年龄小于某个指定的值的用户信息
    public List<User> findUsersByAge(@Param("age") int age);
}

2.3 test

package com.itheima.mapper;
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.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import static org.junit.Assert.*;

public class UserMapperTest {
    
    
    private UserMapper userMapper;
    @Before
    public void setUp() throws Exception {
    
    
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        userMapper = sqlSession.getMapper(UserMapper.class);
    }
    @Test
    public void findUserById() {
    
    
        User user = userMapper.findUserById(1);
        System.out.println(user);
    }
    @Test
    public void addUser(){
    
    
        User user = new User();
        user.setUserName("zhangwuji");
        user.setPassword("zhaoming");
        user.setName("zhouzhiruo");
        userMapper.addUser(user); //user没有id信息,但UserMapper.xml中配置了主键id回显
        System.out.println(user.getId()); //执行后数据库插入一条id=9,删除id=9后插入一条id=10不是9
    }
    @Test
    public void findUserByPasswordAndSex(){
    
    
        String password = "123456";
        int sex = 1;
        List<User> userList = userMapper.findUserByPasswordAndSex(password, sex);
        for(User user:userList){
    
    
            System.out.println(user);
        }
    }
    @Test
    public void findUserByUsername(){
    
    
        List<User> userList = userMapper.findUserByUsername("lisi");
        for(User user:userList){
    
    
            System.out.println(user);
        }
    }
    @Test
    public void findUserByHash(){
    
    
        HashMap<String,Object> map = new HashMap<>();
        map.put("pwd","123456");
        map.put("sex","1");
        List<User> userList = userMapper.findUserByHash(map);
        for(User user:userList){
    
    
            System.out.println(user);
        }
    }
    @Test
    public void findUserByTable(){
    
    
        String tableName = "tb_user_copy";
        List<User> userList = userMapper.findUserByTable(tableName);
        for(User user:userList){
    
    
            System.out.println(user);
        }
    }
    @Test
    public void findUserLikeUsername(){
    
    
        String username = "%zhang%";
        List<User> userList = userMapper.findUserLikeUsername(username);
        for(User user:userList){
    
    
            System.out.println(user);
        }
    }
    @Test
    public void findUsersBySex(){
    
    
        List<User> userList = userMapper.findUsersBySex(1);
        for(User user:userList){
    
    
            System.out.println(user);
        }
    }
    @Test
    public void  findUsersByAge(){
    
    
        List<User> userList = userMapper.findUsersByAge(30);
        for(User user:userList){
    
    
            System.out.println(user);
        }
    }
}

在这里插入图片描述
如上正确产生如下。
在这里插入图片描述
如下要加引号。
在这里插入图片描述
如下字符串拼接。
在这里插入图片描述
B站/知乎/微信公众号:码农编程录
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43435675/article/details/113705843