day_23 mybatis

1.#和$的区别
    #{ } 表示一个占位符,${ } 表示一个拼接符
    #{ } 可以防止sql注入,自动添加 ' ' 单引号

2.@Param(" ") 解决无法识别数据类型问题
    报错:There is no getter for property named 'xxx' in 'class java.lang.String'
    
3.resultType
    可以指定结果集类型,支持基本类型和实体类型,可以使用别名
    实体类中的属性名称必须和查询语句中的列名保持一致

4.resultMap
    <resultMap id="userResult" type="User">
        <id column="id" property="id" />
        <result property="nickname" column="nickname" />
        <result property="schoolName" column="school_name" />
    </resultMap>

5.mybatis-config.xml 配置文件
    1.直接配置属性
        <properties> 
            <property name="jdbc.driver" value="com.mysql.jdbc.Driver"/> 
            <property name="jdbc.url" value="jdbc:mysql://localhost:3306/test"/>
            <property name="jdbc.username" value="root"/> 
            <property name="jdbc.password" value="root"/> 
        </properties>

    2.读取配置文件
        创建 db.properties
            driver=com.mysql.jdbc.Driver
            url=jdbc:mysql://localhost:3306/erp16?useUnicode=true&characterEncoding=UTF-8
            username=root
            password=root

        配置文件读取
            <properties resource="db.properties" />

6.typeAliases属性
        <typeAliases> 
            <!-- 单个别名定义 --> 
            <typeAlias alias="user" type="com.tledu.zrz.pojo.User"/> 
            <!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) --> 
            <package name="com.tledu.zrz.pojo"/> 
            <package name="其它包"/> 
        </typeAliases>
   
7.mapper属性
    映射器,通过mybatis配置文件去找对应的mapper文件
    用法1:Resource
        使用相对于类路径的资源如:<mapper resource="com/tledu/zrz/dao/IUserDao.xml" />
    用法2:calss
        使用mapper接口类路径
        如:<mapper class="com.tledu.zrz.dao.UserDao"/>
        注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。
    用法3:package
        注册指定包下所有的mapper接口
        如:<package name="com.tledu.zrz.mapper"/>
        注意:mapper接口名必须和mapper映射文件名相同,且在同一目录中

8.动态sql
        <select id="list" parameterType="User" resultMap="userResult">
            select * from t_user where 1=1
            <choose>
                <when test="id != null">
                    and id = #{id}
                </when>
                <when test="username != null and username != ''">
                    and username = #{username}
                </when>
                <otherwise>
                    and nickname = #{nickname}
                </otherwise>
            </choose>
        </select>

    
    <where>标签优点:1、可以省略where后面的 and  2、可以放空where内容

    更新:
    <update id="updateNickname">
        update t_user
        <set>
            <if test="nickname != null and nickname != ''">
                nickname = #{nickname},
            </if>
            <if test="username != null and username != ''">
                username = #{username},
            </if>
        </set>
        where id = #{id}
    </update>

    批量操作foreach
     <insert id="batchInsert">
        insert into t_user (username, password, nickname) VALUES
        <foreach collection="list" index="idx" item="item" separator=",">
            (#{item.username},#{item.password},#{item.nickname})
        </foreach>
    </insert>

    in查询 (易错)
        <select id="list" parameterType="User" resultMap="userResult">
            select * from t_user
            <where>
                <if test="user.username != null and user.username != ''">
                    and username = #{user.username}
                </if>
                <if test="user.nickname != null and user.nickname != ''">
                    and nickname like concat('%',#{user.nickname},'%')
                </if>
                and id in
                <foreach collection="idList" item="item" separator="," open="(" close=")">
                    #{item}
                </foreach>
            </where>
        </select>

        属性说明:
            •    collection 需要遍历的列表
            •    item 每一项的形参名
            •    index 每一项索引名
            •    separtor 分隔符
            •    open 开始符号
            •    close 关闭符号

9.联查
    通过association和collection,处理一对一,一对多等关系

    1对1
    在实现1对1映射的时候,可以通过association属性进行设置。在这里有三种方式
    在地址表中,每个地址对应有一个创建用户,每次查询地址的时候希望查询到创建用户的内容
        1.1 使用select
            <resultMap id="address" type="Address">
                    <id column="id" property="id" />
                    <association property="user" column="user_id" javaType="User" select="com.tledu.erp.dao.IUser2Dao.selectById"/>
            </resultMap>
            •    property配置了实体类对应的属性
            •    column配置了关联字段
            •    select对应了IUser2Dao中的查询语句
            在执行sql的过程中就会同时调用在IUserDao中定义的sql进行联查。
            这种方式会执行两次sql语句,效率相对较低,同时还需要先在IUserDao中进行定义后才能使用,比较麻烦
        1.2 直接进行联查,在association中配置映射字段
            这里可以直接写联查,需要转换的字段可以在association中进行配置。
                <resultMap id="address" type="Address" autoMapping="true">
                    <id column="id" property="id" />
                    <association property="user" column="user_id" javaType="User" >
                        <id column="user_id" property="id" />
                        <result column="school_name" property="schoolName" />
                    </association>
                </resultMap>

                <select id="selectOne" resultMap="address">
                    select * from t_address left join t_user tu on tu.id = t_address.user_id where t_address.id = #{id}
                </select>
            autoType代表自动封装,如果不填写,则需要添加所有的对应关系。
            这种方式的问题是,当association需要被多次引用的时候,就需要进行多次重复的配置,所以我们还有第三种方式,引用resultMap。

        1.3 嵌套的resultType
        <resultMap id="addressMap" type="Address" autoMapping="true">
                <id column="id" property="id"/>
                <association property="user" column="user_id" resultMap="userMap">
                </association>
            </resultMap>

            <resultMap id="userMap" type="User" autoMapping="true">
                <id column="user_id" property="id" />
                <result column="school_name" property="schoolName"/>
            </resultMap>

            <select id="selectOne" resultMap="addressMap">
                select t_address.id,
                    addr,
                    phone,
                    postcode,
                    user_id,
                    username,
                    password,
                    nickname,
                    age,
                    sex,
                    school_name
                from t_address
                        left join t_user tu on tu.id = t_address.user_id
                where t_address.id = #{id}
            </select>
        通过这种方式,userMap就可以被多次引用了。
        1.    通过别名保证查询的每一个元素是唯一的,以防止出现错乱的情况
        2.    mybatis官网提醒,需要设置id提高查询性能


        1对多:
        对于address来说,一个地址对应一个创建用户,但是对于User来说,一个用户可能对应创建了多条地址信息,这种情况,在mybatis中就可以通过collections解决。
        同样也是有三种方法
        2.1 使用select
            这里的用法和1对1的时候一致
            在AddressDao中添加
                <select id="selectByUserId" resultType="Address">
                select * from t_address where user_id = #{userId}
                </select>
            在UserDao中添加
                <resultMap id="userResult" type="User" autoMapping="true">
                    <id column="id" property="id"/>
                    <result property="nickname" column="nickname"/>
                    <result property="schoolName" column="school_name"/>
                    <collection property="addressList" column="id" autoMapping="true" select="com.tledu.erp.dao.IAddressDao.selectByUserId" >
                    </collection>
                </resultMap>


                <select id="selectById" parameterType="int" resultMap="userResult">
                    select *
                    from t_user
                    where id = #{id}
                </select>
        2.2 直接进行联查,在collection中配置映射字段
            这里可以直接写联查,需要转换的字段可以在collection中进行配置。
            <resultMap id="userResult" type="User" autoMapping="true">
                    <id column="id" property="id"/>
                    <result property="nickname" column="nickname"/>
                    <result property="schoolName" column="school_name"/>
                    <collection property="addressList" column="phone" ofType="Address" autoMapping="true">
                        <id column="address_id" property="id" />
                    </collection>
                </resultMap>


                <select id="selectById" parameterType="int" resultMap="userResult">
                    select tu.id,
                        username,
                        password,
                        nickname,
                        age,
                        sex,
                        school_name,
                        ta.id as address_id,
                        addr,
                        phone,
                        postcode,
                        user_id
                    from t_user tu
                            left join t_address ta on tu.id = ta.user_id
                    where tu.id = #{id}
                </select>
            autoMapping代表自动封装,如果不填写,则需要添加所有的对应关系。
            这里需要配置ofType来指定返回值类型
            这种方式的问题是,当collection需要被多次引用的时候,就需要进行多次重复的配置,所以我们还有第三种方式,引用resultMap。
        1.3 嵌套的resultType
        <resultMap id="userResult" type="User" autoMapping="true">
                <!--        <id column="id" property="id"/>-->
                <result property="nickname" column="nickname"/>
                <result property="schoolName" column="school_name"/>
                <collection property="addressList" column="phone" ofType="Address" resultMap="addressResultMap" autoMapping="true">
                </collection>
            </resultMap>

            <resultMap id="addressResultMap" type="Address" autoMapping="true">
                <id column="address_id" property="id" />
            </resultMap>


            <select id="selectById" parameterType="int" resultMap="userResult">
                select tu.id,
                    username,
                    password,
                    nickname,
                    age,
                    sex,
                    school_name,
                    ta.id as address_id,
                    addr,
                    phone,
                    postcode,
                    user_id
                from t_user tu
                        left join t_address ta on tu.id = ta.user_id
                where tu.id = #{id}
            </select>
        通过这种方式,userMap就可以被多次引用了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值