Mybatis学习笔记

本文深入探讨MyBatis框架的高级配置,包括SQL注入预防、动态SQL、一对多及多对多关系处理、懒加载策略等核心概念,旨在帮助开发者掌握MyBatis的进阶技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. #{}表示一个占位符号,#{}可以有效防止 sql 注入。${}表示拼接 sql 串 

 

2. SqlMapConfig.xml mybatis配置

<?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">
 <!--mybatis的主配置文件-->
<configuration>
    <properties resource="db.properties" />
    <typeAliases>
        <!-- 单个别名定义 -->
        <!--<typeAlias alias="user" type="com.itheima.domain.User"/>-->
        <!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
        <package name="com.itheima.domain"/>
        <!--<package name=" 其它包 "/>-->
    </typeAliases>

    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源(连接池) -->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的4个基本信息 -->
                <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>
        </environment>
    </environments>

    <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
    <mappers>
        <!--<mapper resource="com/itheima/dao/IUserDao.xml"></mapper>-->
        <!-- package标签是用于指定dao接口所在的包,当指定了之后就不需要在写mapper以及resource或者class了 -->
        <package name="com.itheima.dao"></package>
    </mappers>


</configuration>

 3.UserDao.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.dao.IUserDao">

    <!-- 配置 查询结果的列名和实体类的属性名的对应关系 -->
    <resultMap id="userMap" type="user">
        <!-- 主键字段的对应 -->
        <id property="id" column="id"></id>
        <!--非主键字段的对应-->
        <result property="username" column="username"></result>
        <result property="address" column="address"></result>
        <result property="sex" column="sex"></result>
        <result property="birthday" 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>

    <!-- 根据id查询
    parameterType: 用于指定传入参数的类型 -->
    <select id="findById" resultType="com.itheima.domain.User" parameterType="int">
        select * from user where id = #{uid}
    </select>

    <insert id="saveUser" parameterType="user">

        <!-- 配置保存时获取出入的id -->
        <selectKey keyColumn="id" keyProperty="id" resultType="int">
            SELECT last_insert_id();
        </selectKey>
        INSERT INTO user (username,birthday,sex,address) VALUES
        (#{username},#{birthday},#{sex},#{address})
    </insert>

    <update id="updateUser" parameterType="com.itheima.domain.User">
        UPDATE user SET username=#{username},birthday=#{birthday},sex=#{sex},
        address=#{address}  where id=#{id}
    </update>

    <delete id="deleteUser" parameterType="java.lang.Integer">
        DELETE FROM user WHERE id = #{uid}
    </delete>


    <!--
     #{}表示一个占位符号  通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换,
     #{}可以有效防止 sql 注入。 #{}可以接收简单类型值或 pojo 属性值。 如果 parameterType 传输单个简单类 型值,
     #{}括号中可以是 value 或其它名称。
     ${}表示拼接 sql 串  通过${}可以将 parameterType 传入的内容
     拼接在 sql中且不进行 jdbc 类型转换, ${}可以接收简 单类型值或 pojo 属性值,如果 parameterType
      传输单个简单类型值,${}括号中只能是 value。
     -->
    <select id="findByName" resultType="com.itheima.domain.User" parameterType="String">
        SELECT * FROM user WHERE username LIKE '%${value}%'
    </select>

    <select id="findByVo" resultType="com.itheima.domain.User" parameterType="com.itheima.domain.QueryVo">
        SELECT * FROM user WHERE username like #{user.username};
    </select>

</mapper>

 4.UserDao.xml  1.动态Sql(if where )用法2. 抽取重复的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.itheima.dao.IUserDao2">

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

    <!--抽取重复的sql语句
        使用:<include refid="defaultSql"></include>
    -->
    <sql id="defaultUser">
        SELECT * FROM user
    </sql>

    <!--根据queryvo中的id集合实现查询用户列表-->

    <!--SQL 语句:
    select 字段 from user where id in (?)
    <foreach>标签用于遍历集合,它的属性:
    collection:代表要遍历的集合元素,注意编写时不要写#{}
    open:代表语句的开始部分
    close:代表结束部分
    item:代表遍历集合的每个元素,生成的变量名
    sperator:代表分隔符
    -->

    <select id="findUserInIds" resultMap="userMap" parameterType="queryvo">
        <include refid="defaultUser"></include>
        <where>
            <if test="ids != null and ids.size()>0">
                <foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
                    #{uid}
                </foreach>
            </if>
        </where>
    </select>


    <!--根据条件查询:有可能有用户名,有可能有性别,也有可能有地址还有可能什么都有-->
    <!--<select id="findByUser" resultType="user" parameterType="user">-->
        <!--SELECT * FROM user WHERE 1 = 1-->
        <!--<if test="username!=null and username != ''">-->
            <!--AND username LIKE #{username}-->
        <!--</if>-->
        <!--<if test="address != null">-->
            <!--AND address LIKE #{address}-->
        <!--</if>-->
    <!--</select>-->

    <!--把where套在if外可以省去where 1 = 1-->
    <select id="findByUser" resultType="user" parameterType="user">
        SELECT * FROM user
        <where>
            <if test="username!=null and username != ''">
                AND username LIKE #{username}
            </if>
            <if test="address != null">
                AND address LIKE #{address}
            </if>
        </where>
    </select>

</mapper>

 5.AccountDao.xml 一对一关系映射 association 

public class Account implements Serializable {
    private Integer id;
    private Integer uid;
    private Double money;
    private User user;
}
<?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.IAccountDao">


    <!-- 定义封装account和user的resultMap -->
    <resultMap id="accountUserMap" type="account">
        <id property="id" column="aid"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <!--
            一对一的关系映射:配置封装user的内容 javaType:提示封装到哪个类型
            association:作用:将关联查询信息映射到一个pojo对象中。
        -->
        <association property="user" column="uid" javaType="user">
            <id property="id" column="id"></id>
            <result column="username" property="username"></result>
            <result column="address" property="address"></result>
            <result column="sex" property="sex"></result>
            <result column="birthday" property="birthday"></result>
        </association>
    </resultMap>

    <!-- 查询所有 -->
    <select id="findAll" resultMap="accountUserMap">
        select a.*,u.username,u.address from account a , user u where u.id = a.uid;
    </select>

    <!--查询所有账户同时包含用户名和地址信息-->
    <select id="findAllAccount" resultType="accountuser">
        select a.*,u.username,u.address from account a , user u where u.id = a.uid;
    </select>

</mapper>

6.懒加载

SqlMapConfig.xml

<configuration>
    <!--配置参数-->
    <settings>
        <!--开启mybatis支持延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
    <typeAliases>
        <package name="com.itheima.domain"/>
    </typeAliases>
</configuration>
<mapper namespace="com.itheima.dao.IAccountDao">
    <!-- 定义封装account和user的resultMap -->
    <resultMap id="accountUserMap" type="account">
        <id property="id" column="id"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <!--一对一关系映射,配置封装user的内容
        select属性指定的内容,出阿薰用户的唯一标识
        colum属性指定的内容,用户根据id查询时,所需要的参数的值
        -->
        <association property="user" column="uid" javaType="user"
                     select="com.itheima.dao.IUserDao.findById">
        </association>
    </resultMap>

    <!-- 查询所有 -->
    <select id="findAll" resultMap="accountUserMap">
        select * from account
    </select>
</mapper>

7. @result db字段对应bean字段 一对一 ,立即加载

public interface IAccountDao {

    @Select("select * from account")
    @Results(id = "accountMap",value = {
            @Result(id = true,column = "id",property = "id"),
            @Result(column = "uid",property = "uid"),
            @Result(column = "money",property = "money"),
            @Result(property = "user",column = "uid",
                    one = @One(select="com.itheima.dao.IUserDao_One2Many.findById",fetchType=FetchType.EAGER))
    })
    List<Account> findAll();

    @Select("select * from account where uid = #{userId}")
    List<Account> findAccountByUid(Integer userId);
}

8.使@result注解db字段和bean字段对应,多对多,懒加载

/**
 * 使用@result注解实现数据库字段和实体字段对应
 */
public interface IUserDao_One2Many {

    @Select("select * from user where id = #{id}")
    @ResultMap("userMap")
    User_One2Many findById(Integer userId);

    @Select("select * from user")
    @Results(id = "userMap",value={
            @Result(id=true,column = "id",property = "userId"),
            @Result(column = "username",property = "userName"),
            @Result(column = "address",property = "userAddress"),
            @Result(column = "sex",property = "userSex"),
            @Result(column = "birthday",property = "userBirthday"),
            @Result(column = "id",property = "accounts",many =
                    @Many(select = "com.itheima.dao.IAccountDao.findAccountByUid",
                    fetchType = FetchType.LAZY))

    })
    List<User_One2Many> findAll();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值