MyBatis---映射文件

增删改

增删改大同小异,没什么复杂的东西,只是标签不一样。

需要注意的是,增删改必须进行提交操作之后才会将改变提交给数据库。

Mybatis有以下获取session对象的方法,如果是第一种,需要手动提交事务;如果是第二种,传入参数true设置自动提交事务,false和第一种一样。

    SqlSession openSession();

    SqlSession openSession(boolean var1);

代码

以下是代码:

    /**
     * 添加用户
     * @param user 一个用户实体信息封装类
     */
    void insertUser(User user);

    /**
     * 修改用户
     * @param user
     */
    void updateUser(User user);

    /**
     * 删除用户
     * @param id 要删除用户的ID
     */
    void deleteUser(int id);
	<insert id="insertUser" parameterType="com.modevil.domain.User">
		INSERT INTO user(userName, sex, address) VALUES(#{userName}, #{sex}, #{address});
	</insert>

	<update id="updateUser" parameterType="com.modevil.domain.User">
		UPDATE user SET userName=#{userName}, sex=#{sex},address=#{address} WHERE id=#{id}
	</update>

	<delete id="deleteUser" parameterType="com.modevil.domain.User">
		DELETE FROM user WHERE id=#{id}
	</delete>

对于标签中的属性

  • id:对应方法名
  • parameterType:对应输入的参数类型

获取执行的结果

直接在接口种的方法上面写上需要的返回值,Mybatis会自动进行封装。

需要注意的是只支持Boolean、Integer、Long这三种。

    /**
     * 添加用户
     * @param user 一个用户实体信息封装类
     * @return 是否插入成功
     */
    boolean insertUser(User user);

    /**
     * 修改用户
     * @param user
     * @return 是否修改成功
     */
    boolean updateUser(User user);

    /**
     * 删除用户
     * @param id 要删除用户的ID
     * @return 删除了多少行
     */
    int deleteUser(int id);

Mysql获取自增主键的值

只用增加两个属性就行了。
以下是配置文件

	<insert id="insertUser" parameterType="com.modevil.domain.User" useGeneratedKeys="true" keyProperty="id">
		INSERT INTO user(userName, sex, address) VALUES(#{userName}, #{sex}, #{address});
	</insert>

增加了两个属性:

  • useGeneratedKeys:告诉Mybatis使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键
  • keyProperty:指定对应实体类的属性

1、返回一个封装好的对象

    /**
     * 通过ID查询用户
     * @param id 用户的ID
     * @return
     */
    User getUserById(int id);
	<select id="getUserById" resultType="com.modevil.domain.User">
		SELECT * FROM user WHERE id=#{id}
	</select>

其中,resultType应为要返回的对象的全类名

2、返回封装好的对象的列表

    /**
     * 查询所有用户
     * @return 所有用户信息
     */
    List<User> getAllUser();
    <select id="getAllUser" resultType="com.modevil.domain.User">
		SELECT * FROM user
	</select>

和第一个并没有太多的区别,resultType中的值为列表中的对象的类型。

3、将返回的数据封装为Map

    /**
     * 获取指定用户的部分信息
     * @param id 用户Id
     * @return 用户信息封装成的Map对象
     */
    Map<String, Object> getPartMessageById(int id);
	<select id="getPartMessageById" resultType="map">
		SELECT id, userName, sex FROM user WHERE id=#{id}
	</select>

查询数据的时候不一定每次都是返回一个对象,也可以将数据封装为一个Map。

其中,查询出来的结果是一条记录,Map的Key为列名,Value为值。

最后就是resultType中写map就可以的原因是mybatis已经给我们常用的一些数据起了别名。当然,直接写java.util.Map也是可以的。

4、将返回的多个对象封装为一个map

    /**
     * 根据名字进行模糊查询
     * @param name 名字中包含的字段
     * @return 用户列表
     */
    @MapKey("userName")
    Map<String, User> getUsersByName(String name);
	<!-- Map<String, User> getUsersByName(String name);-->
	<select id="getUsersByName" resultType="com.modevil.domain.User">
		SELECT * FROM user WHERE userName LIKE #{name}
	</select>

在这个中resultType的值为Map中Value的类型,然后还需要在方法上面使用注解@MapKey("")指定Map的Key是那一列,不然会报错。

5、一对一、多对一

如果一个对象中引用了另一个对象,在查询这个对象的时候,想把与其相关联的对象一起查出来。可以使用连接查询,或者是分布查询,在这种情况下就需要用resultMap来映射了。

关联查询

    /**
     * 通过Id查询用户,并一起获得其角色的信息
     * @param id 用户Id
     * @return
     */
    User getUserWithRoleById(int id);
	<resultMap id="MyUser1" type="com.modevil.domain.User">
		<id column="id" property="id"/>
		<result column="userName" property="userName"/>
		<result column="sex" property="sex"/>
		<result column="address" property="address"/>
		<result column="roleId" property="role.id"/>
		<result column="roleName" property="role.roleName"/>
		<result column="authority" property="role.authority"/>
	</resultMap>
	
	<resultMap id="MyUser2" type="com.modevil.domain.User">
		<id column="id" property="id"/>
		<result column="userName" property="userName"/>
		<result column="sex" property="sex"/>
		<result column="address" property="address"/>
		<association property="role" javaType="com.modevil.domain.Role">
			<id column="roleId" property="id"/>
			<result column="roleName" property="roleName"/>
			<result column="authority" property="authority"/>
		</association>
	</resultMap>
	
	<select id="getUserWithRoleById" resultMap="MyUser1">
		SELECT u.id, u.userName, u.sex, u.address, u.roleId, r.roleName, r.authority
		FROM user u LEFT JOIN role r ON u.roleId = r.id WHERE u.id=#{id}
	</select>
  • resultMap:自定义的映射规则,id为其唯一的索引,type是其映射的对象的全类名
    • id:对应数据库中的主键列,column对应列名,property对应属性
    • result:对应数据库的其他列
    • association 映射关联的对象,property属性名,javaType关联对象的全类名
  • select:resultMap,对应自定义的resultMap的Id

在这种情况下

  1. 在resultMap中可以直接使用对象名.属性名来映射User中的Role属性。对应MyUser1
  2. 在resultMap中使用association来映射关联的对象,对应MyUser2

分步查询

顾名思义,这个就是将原本的一个查询语句分开,分成两个不同的查询语句来分别进行查询。先查询到除关联对象之外的所有属性,然后再进行一次查询,单独查关联对象的属性。

在这种情况下,关联对象也需要有一个自己的Mapper映射文件,去映射相应的查询方法。

    /**
     * 分步查询用户,及其对应的关联角色
     * @param id
     * @return
     */
    User getUserWithRoleStepById(int id);
	<resultMap id="MyUser3" type="com.modevil.domain.User">
		<id column="id" property="id"/>
		<result column="userName" property="userName"/>
		<result column="sex" property="sex"/>
		<result column="address" property="address"/>
		<association column="roleId" property="role" select="com.modevil.dao.RoleDao.getRoleById"/>
	</resultMap>
	
	<select id="getUserWithRoleStepById" resultMap="MyUser3">
		SELECT * FROM user WHERE id=#{id}
	</select>

association的select属性对应根据Id查询role对象的方法的全类名。

6、一对多

和上面的情况类似,但是是一个对象和多个其他的对象相关联,也有级联查询和分步查询两种情况。

级联

    /**
     * 通过角色Id查询相应的数据,并一同查出来对应的User对象
     * @param id
     * @return
     */
    Role getRoleWithUserById(int id);
    <resultMap id="myRole1" type="com.modevil.domain.Role">
        <id column="id" property="id"/>
        <result column="roleName" property="roleName"/>
        <result column="authority" property="authority"/>

        <collection property="users" ofType="com.modevil.domain.User">
            <id column="uid" property="id"/>
            <result column="userName" property="userName"/>
            <result column="sex" property="sex"/>
            <result column="address" property="address"/>
        </collection>
    </resultMap>

    <select id="getRoleWithUserById" resultMap="myRole1">
        SELECT r.id, r.roleName, r.authority, u.id uid, u.userName, u.sex, u.address
        FROM role r LEFT JOIN user u ON r.ID = u.roleId WHERE r.id=#{id}
    </select>

其中collection的属性property对应集合的属性名,ofType对应集合中元素的类型

分步

    /**
     * 分步的
     * @param id
     * @return
     */
    Role getRoleWithUserStepById(int id);
    <resultMap id="myRole2" type="com.modevil.domain.Role">
        <id column="id" property="id"/>
        <result column="roleName" property="roleName"/>
        <result column="authority" property="authority"/>
        <collection property="users" column="{roleId=id}" select="com.modevil.dao.UserDao.getUsersByRoleId"/>
    </resultMap>

    <select id="getRoleWithUserStepById" resultMap="myRole2">
        SELECT * FROM role WHERE id=#{id}
    </select>

其中collection的属性select对应根据roleId查询user方法的全类名。

鉴别器

使用鉴别器可以根据不同值使用不同的映射方法。

    /**
     * 使用鉴别器获取数据
     * @param id
     * @return
     */
    User getUserSpecialById(int id);
	<resultMap id="MyUser4" type="com.modevil.domain.User">
		<id column="id" property="id"/>
		<result column="userName" property="userName"/>
		<result column="sex" property="sex"/>
		<result column="address" property="address"/>

		<discriminator javaType="String" column="sex">
			<case value="" resultType="com.modevil.domain.User">
				<association column="roleId" property="role" select="com.modevil.dao.RoleDao.getRoleById"/>
			</case>
			<case value="" resultType="com.modevil.domain.User">
			</case>
		</discriminator>
	</resultMap>

	<select id="getUserSpecialById" resultMap="MyUser4">
		SELECT * FROM user WHERE id=#{id}
	</select>

鉴别器和Java中的switch有点类似。
discriminator 参数:javaType指定判断的数据的类型,column数据的列
case 参数:value指定值为当前情况下的处理,resultType处理的结果的类型

输入参数

只有一个基本数据类型

在输入只有一个参数的情况下,Mybaits是不进行特殊处理的,不管sql语句的#{}中是什么,都可以成功执行。

传入一个对象作为参数

在这种情况下,我们可以直接使用#{属性名}来获取值。

传入多个参数

在这种情况下,MyBatis会对数据进行特殊处理,将参数封装成一个map;具体是怎么进行的可以去看尚硅谷的课程,讲的挺清楚的。

在这种情况下,我们可以使用索引或者是paramN(N为索引值)来获取,具体形式如下:#{N},#{paramN}。

这样获取一旦数据多了起来之后,容易混淆,可以在方法的参数前面加上注解@Param(“name”),这样在获取参数的时候就可以使用#{name}开获取数据了。

传入参数类型为Map

在传入参数类型为Map的情况下,可以直接使用#{Key}来获取值。

传入数据为Collection对象或者是数组

在这种情况下可以使用collection、list、array等来获取对象。

#{}与${}

相同之处:这两个都可以获取到值

不同之处:
#{}:是以预编译的形式,将参数设置到sql语句中;可以防止sql注入。
$ {}:取出的值直接拼装在sql语句中;会有安全问题。但是在原生jdbc不支持占位符的地方我们就可以使用${}进行取值。

最后就是#{}支持一些更高级的用法来对参数进行设置。

其他

还有缓存、懒加载等等配置,想了解的可以自己去看官方文档。

最后,如果有什么问题还请指正。

参考文档

  • Mybatis的官方文档
  • 尚硅谷的Mybatis教程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值