MyBatis从零开始-MyBatis XML方式的基本用法

9 篇文章 0 订阅
6 篇文章 0 订阅

系列博客目录:MyBatis从零开始博客目录

2. MyBatis XML方式的基本用法

2.1 使用XML方式

MyBatis的真正强大之处在于它的映射语句,由于它的映射语句很强大,映射器的XML文件就显得相对简单。

在src/main/resources的com.xiangty.mapper目录创建接口类UserMapper.xml和src/main/java的com.xiangty.mapper包下创建UserMapper.Java;

UserMapper.java内容如下:

public interface UserMapper {

}

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.xiangty.mapper.UserMapper">

</mapper>

需要注意< mapper > 根标签namespace属性。当Mapper接口和XML文件关联的时候,命名空间namespace的值就需要配置成接口的全限定名称,例如UserMapper接口对应的com.xiangty.mapper.UserMapper,MyBatis内部就是通过这个值将接口和XML关联起来的。

2.2 编写SqlSessionUtil工具类和表结构

单元测试过程中需要重复使用SqlSessionFactory创建SqlSession链接,所以提取一个工具类SqlSessionUtil,后面代码中使用。

import java.io.IOException;
import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class SqlSessionUtil {

	public static SqlSession getSqlSession() {
		SqlSession sqlSession = null;
		// 此处可以不使用try抛异常,SqlSessionFactoryBuilder().build()方法中有reader流关闭的操作
		try (Reader reader = Resources.getResourceAsReader("mybatis-config.xml");) {
			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
			sqlSession = sqlSessionFactory.openSession();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (sqlSession != null) {
			return sqlSession;
		} else {
			throw new NullPointerException("sqlSession为空");
		}
	}

}
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(32) NOT NULL AUTO_INCREMENT,
  `password` varchar(32) DEFAULT '' COMMENT '密码',
  `username` varchar(32) DEFAULT '' COMMENT '用户名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-------------------------------------------
INSERT INTO `user` VALUES ('1', '123456', '管理员');
INSERT INTO `user` VALUES ('2', '123456', '路人甲');
INSERT INTO `user` VALUES ('3', 'testpassword', 'testname');

2.3 select用法

2.3.1 单表查询

根据id查询用户信息

UserMapper.java代码如下:

public interface UserMapper {

	/**
	 * 根据id查询用户信息
	 * @param id
	 * @return
	 */
	User getUserById(Integer id);
	
	/**
	 * 根据username查询用户信息
	 * @param username
	 * @return
	 */
	User getUserByUsername(String username);
	
}

然后在UserMapper.xml中添加如下的< resultMap >和< select >部分的代码。

<?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.xiangty.mapper.UserMapper">

	<!--  -->
	<resultMap id="userMap" type="com.xiangty.bean.User">
		<id property="id" column="id" />
		<result property="username" column="username" />
		<result property="password" column="password" />
	</resultMap>
	
	<!-- 
		select标签:映射查询语句使用的标签
		id:命名空间中的唯一标识符,可用来代表这条语句
		resultMap:用于设置返回值的类型和映射关系
		select标签中的 SELECT id, username, password FROM user WHERE id=#{id}是查询语句
		#{id}:MyBatis SQL中使用的预编译参数的一种方式
	-->
	<select id="getUserById" resultMap="userMap">
		SELECT id, username, password FROM user 
        WHERE id=#{id}
	</select>
	
	<!-- 
		${value}接收输入参数的内容,如果传入的是简单类型,${}中只能使用value或者_parameter来作为参数名 
		username='${_parameter}' 或者 username='${value}' 效果一致
		"${}"和"#{}"相比容易被SQL注入,在作为查询条件的时候,不建议使用"${}"方式
	-->
	<select id="getUserByUsername" resultMap="userMap">
		SELECT id, username, password FROM user 
        WHERE username='${_parameter}'
	</select>

</mapper>

测试类方法代码:

import org.junit.Test;
import com.xiangty.bean.User;

public class UserTest {

	@Test
	public void getUserById(){
		SqlSession sqlSession = SqlSessionUtil.getSqlSession();
		try{
            System.out.println("-----------#{}方式,开始-----------");
            User user = sqlSession.selectOne("getUserById", 1);
            System.out.println(user);
            System.out.println("-----------#{}方式,结束-----------");
            System.out.println("-----------${}方式,开始-----------");
            user = sqlSession.selectOne("getUserByUsername", "testname");
            System.out.println(user);
            System.out.println("-----------${}方式,结束-----------");
		} finally{
			sqlSession.close();
		}
	}
}

输入结果:

-----------#{}方式,开始-----------
DEBUG [main] - ==>  **Preparing: SELECT id, username, password FROM user WHERE id=?** 
DEBUG [main] - ==> Parameters: 1(Integer)
TRACE [main] - <==    Columns: id, username, password
TRACE [main] - <==        Row: 1, 管理员, 123456
DEBUG [main] - <==      Total: 1
User [id=1, username=管理员, password=123456]
-----------#{}方式,结束-----------
-----------${}方式,开始-----------
DEBUG [main] - ==>  **Preparing: SELECT id, username, password FROM user WHERE username='testname'** 
DEBUG [main] - ==> Parameters: 
TRACE [main] - <==    Columns: id, username, password
TRACE [main] - <==        Row: 3, testname, testpassword
DEBUG [main] - <==      Total: 1
User [id=3, username=testname, password=testpassword]
-----------${}方式,结束-----------

注意:从上面输出信息可以发现"KaTeX parse error: Expected 'EOF', got '#' at position 6: {}"和"#̲{}"相比容易被SQL注入,在…{}"方式。

通过mapper的方式来调用:

@Test
public void getMapperById() {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.getUserById(1);
        System.out.println(user);
    } finally {
        sqlSession.close();
    }
}

输出内容:
DEBUG [main] - ==>  Preparing: SELECT id, username, password FROM user WHERE id=? 
DEBUG [main] - ==> Parameters: 1(Integer)
TRACE [main] - <==    Columns: id, username, password
TRACE [main] - <==        Row: 1, 管理员, 123456
DEBUG [main] - <==      Total: 1
User [id=1, username=管理员, password=123456]
2.3.2 多表查询

添加一个用户联系信息的表

DROP TABLE IF EXISTS `user_contact`;
CREATE TABLE `user_contact` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(50) DEFAULT NULL,
  `phone` varchar(20) DEFAULT NULL,
  `home_address` varchar(100) DEFAULT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

------------------------------------
INSERT INTO `user_contact` VALUES ('1', 'testname@qq.com', '13612345678', 'testname地址', '3');
INSERT INTO `user_contact` VALUES ('2', 'admin@qq.com', '13412345677', '管理员home地址', '1');


UserContact.java

public class UserContact {
	private Integer id;
	private String email;
	private String phone;
	private String homeAddress;
	private User user;
	
	// 此处省略无参构造方法
	// 此处省略属性的get,set方法
    // 此处省略toString()方法
    // 此处省略重写的hashCode()和equals()方法

}

第一种场景只是返回userContact信息

UserMapper.java

public interface UserMapper {
	/**
	 * 根据userid查询用户联系信息,这是输出userContact信息
	 * @param userid
	 * @return
	 */
	UserContact getUserContactByUserId(Integer userid);
}

UserMapper.xml

<select id="getUserContactByUserId" resultType="com.xiangty.bean.UserContact">
    SELECT b.id, b.email, b.phone, b.home_address
    FROM user a 
    LEFT JOIN user_contact b
    ON b.user_id = a.id
    WHERE b.user_id = #{userid}
</select>

UserTest.java

/**
 * 这是输出userContact信息
 */
@Test
public void getUserContactByUserId(){
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        UserContact userContact = userMapper.getUserContactByUserId(1);
        System.out.println(userContact);
    } finally {
        sqlSession.close();
    }
}

输出信息:
DEBUG [main] - ==>  Preparing: SELECT b.id, b.email, b.phone, b.home_address FROM user a LEFT JOIN user_contact b ON b.user_id = a.id WHERE b.user_id = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
TRACE [main] - <==    Columns: id, email, phone, home_address
TRACE [main] - <==        Row: 2, admin@qq.com, 13412345677, 管理员home地址
DEBUG [main] - <==      Total: 1
UserContact [id=2, email=admin@qq.com, phone=13412345677, homeAddress=管理员home地址, user=null]

第二种场景既要返回userContact信息还要返回user信息

方法一:写一个新的实体类,该类包含需要返回的查询信息

UserContactAndUser.java

public class UserContactAndUser {
	private Integer id;
	private String email;
	private String phone;
	private String homeAddress;
	private String username;
	private String password;
	private Integer userid;
    
 	// 此处省略无参构造方法
	// 此处省略属性的get,set方法
    // 此处省略toString()方法
    // 此处省略重写的hashCode()和equals()方法
}

UserMapper.java

	/**
	 * 根据id既要返回userContact信息还要返回user信息
	 * @param id
	 * @return
	 */
	UserContactAndUser getUserContactAndUserById(Integer id);

UserMapper.xml

<select id="getUserContactAndUserById" resultType="com.xiangty.bean.UserContactAndUser">
    SELECT b.id, b.email, b.phone, b.home_address, 
        a.username ,
        a.password , 
        a.id as userid
    FROM user a 
    LEFT JOIN user_contact b
    ON b.user_id = a.id
    WHERE a.id = #{id}
</select>

UserTest.java

/**
 * 既要返回userContact信息还要返回user信息,方法一:创建新的实体类
 */
@Test
public void getUserContactAndUserById1(){
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        UserContactAndUser userContactAndUser = userMapper.getUserContactAndUserById(1);
        System.out.println(userContactAndUser);
    } finally {
        sqlSession.close();
    }
}

输出信息:
DEBUG [main] - ==>  Preparing: SELECT b.id, b.email, b.phone, b.home_address, a.username , a.password , a.id as userid FROM user a LEFT JOIN user_contact b ON b.user_id = a.id WHERE a.id = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
TRACE [main] - <==    Columns: id, email, phone, home_address, username, password, userid
TRACE [main] - <==        Row: 2, admin@qq.com, 13412345677, 管理员home地址, 管理员, 123456, 1
DEBUG [main] - <==      Total: 1
UserContactAndUser [id=2, email=admin@qq.com, phone=13412345677, homeAddress=管理员home地址, username=管理员, password=123456, userid=1]

方法二:使用resultMap

UserMapper.java

/**
 * 根据id既要返回userContact信息还要返回user信息 方法二:使用resultMap
 * @param id
 * @return
 */
UserContact getUserContactAndUserById2(Integer id);

UserMapper.xml

<!--
	association:一对一关系
	<association property="" javaType="类路径">
		
	collection:一对多关系
	<collection property="" ofType="类路径">
-->
<resultMap id="userContactAndUserMap" type="com.xiangty.bean.UserContact">
    <id property="id" column="id" />
    <result property="email" column="email" />
    <result property="phone" column="phone" />
    <result property="homeAddress" column="home_address" />
    <association property="user" javaType="com.xiangty.bean.User">
        <id property="id" column="userid" />
        <result property="username" column="username" />
        <result property="password" column="password" />
    </association>
</resultMap>
<select id="getUserContactAndUserById2" resultMap="userContactAndUserMap">
    SELECT b.id, b.email, b.phone, b.home_address, 
    a.username ,
    a.password , 
    a.id as userid
    FROM user a 
    LEFT JOIN user_contact b
    ON b.user_id = a.id
    WHERE a.id = #{id}
</select>

UserTest.java

/**
 * 既要返回userContact信息还要返回user信息,方法二:使用resultMap
 */
@Test
public void getUserContactAndUserById2(){
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        UserContact userContact = userMapper.getUserContactAndUserById2(1);
        System.out.println(userContact);
    } finally {
        sqlSession.close();
    }
}

信息输出:
DEBUG [main] - ==>  Preparing: SELECT b.id, b.email, b.phone, b.home_address, a.username , a.password , a.id as userid FROM user a LEFT JOIN user_contact b ON b.user_id = a.id WHERE a.id = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
TRACE [main] - <==    Columns: id, email, phone, home_address, username, password, userid
TRACE [main] - <==        Row: 2, admin@qq.com, 13412345677, 管理员home地址, 管理员, 123456, 1
DEBUG [main] - <==      Total: 1
UserContact [id=2, email=admin@qq.com, phone=13412345677, homeAddress=管理员home地址, user=User [id=1, username=管理员, password=123456]]

2.4 insert用法

2.4.1 简单的insert方法

UserMapper.java

public interface UserMapper {
	/**
	 * 新增用户
	 * @param user
	 * @return
	 */
	int insert(User user);
}

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.xiangty.mapper.UserMapper">
	<insert id="insert">
		INSERT INTO user(id, username, password)
		VALUES(#{id}, #{username}, #{password})
	</insert>
</mapper>

UserTest.java

@Test
public void insert() {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setUsername("demo1");
        user.setPassword("demo1");
        // 将新建的对象插入数据库中,特别是这里的result是执行的SQL影响的行数
        int result = userMapper.insert(user);
        /*
		 * commit():由于默认的sqlSessionFactory.openSession()是不自动提交的
		 * 所以需要使用commit()才能将执行的插入数据生效将数据写入到数据库中,不然数据是不会写入数据库中的
		 * rollback(): 回滚事务,如果插入程序出现异常,可以使用rollback()回滚事务。
		 */
        sqlSession.commit();
        if (result > 0) {
            System.out.println("添加成功");
        } else {
            System.out.println("添加失败");
        }
    } finally {
        sqlSession.close();
    }
}

程序输出:
DEBUG [main] - ==>Preparing: INSERT INTO user(id, username, password) VALUES(?, ?, ?) 
DEBUG [main] - ==> Parameters: null, demo1(String), demo1(String)
DEBUG [main] - <==    Updates: 1
添加成功
2.4.2 使用useGeneratedKeys返回主键自增的值

使用主键自增的时候,插入数据库后可能需要得到自增的主键值,MyBatis提供了useGeneratedKeys设置。useGeneratedKeys设置为true后,MyBatis会使用JDBC的getGeneratedKeys方法获取由数据库内部生成的主键。获得主键值后将其赋值给keyProperty配置的id属性。示例代码如下:

UserMapper.java

public interface UserMapper {
	/**
	 * 新增用户-使用useGeneratedKeys方式
	 * @param user
	 * @return
	 */
	int insert2(User user);
}

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.xiangty.mapper.UserMapper">
	<insert id="insert2" useTGeneratedKeys="true" keyProperty="id">
		INSERT INTO user(id, username, password)
		VALUES(#{username}, #{password})
	</insert>
</mapper>

UserTest.java

@Test
public void insert2() {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setUsername("demo2");
        user.setPassword("demo2");
        int result = userMapper.insert2(user);

        sqlSession.commit();
        if(result > 0){
            System.out.println("insert2方法添加的数据,返回的主键值为:" + user.getId());
        } else {
            System.out.println("添加失败");
        }
    } catch (Exception e) {
        // 发生异常回滚事务
        sqlSession.rollback();
        e.printStackTrace();
    } finally {
        sqlSession.close();
    }
}

程序输出:
DEBUG [main] - ==>  Preparing: INSERT INTO user(username, password) VALUES(?, ?) 
DEBUG [main] - ==> Parameters: demo2(String), demo2(String)
DEBUG [main] - <==    Updates: 1
insert2方法添加的数据,返回的主键值为:9
2.4.3 使用selectKey返回主键值

​ useGeneratedKeys这种写主键的方法只适用于支持主键自增的数据库。像Oracle这样的数据库不提供主键自增的功能,而是使用序列得到的值,然后在将这个值赋给主键,再将数据插入数据库。对于这种情况,使用< selectKey > 标签来获取主键的值,这种方法对于提供和不提供主键的方法都适用。

UserMapper.java

public interface UserMapper {
	/**
	 * 新增用户-使用selectKye方式
	 * @param user
	 * @return
	 */
	int insert3(User user);
}

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.xiangty.mapper.UserMapper">
	<insert id="insert3">
		INSERT INTO user(username, password)
		VALUES(#{username}, #{password})
		<selectKey keyColumn="id" resultType="int" keyProperty="id" order="AFTER">
			SELECT LAST_INSERT_ID()
		</selectKey>
	</insert>
</mapper>

UserTest.java

@Test
public void insert3() {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setUsername("demo3");
        user.setPassword("demo3");
        int result = userMapper.insert2(user);

        sqlSession.commit();
        if(result > 0){
            System.out.println("insert3方法添加的数据,返回的主键值为:" + user.getId());
        } else {
            System.out.println("添加失败");
        }
    } catch (Exception e) {
        // 发生异常回滚事务
        sqlSession.rollback();
        e.printStackTrace();
    } finally {
        sqlSession.close();
    }
}

程序输出:
DEBUG [main] - ==>  Preparing: INSERT INTO user(username, password) VALUES(?, ?) 
DEBUG [main] - ==> Parameters: demo3(String), demo3(String)
DEBUG [main] - <==    Updates: 1
insert3方法添加的数据,返回的主键值为:10

UserMappe.xml中的

	<selectKey keyColumn="id" resultType="int" keyProperty="id" order="AFTER">
		SELECT LAST_INSERT_ID()
	</selectKey>

selectKey标签中的keyColumn、keyProperty和上面的userGeneratedKeys的用法含义相同,keyColumn属性值和数据库的列名一致、keyProperty属性值是Java实体类的值,这里resultType用于设置返回值类型。order属性的设置和使用的数据库相关。MySQL数据库中,order属性设置的值是AFTER,因为当前记录的主键值在insert语句执行成功后才能获取。而在Oracle数据库中,order的值要设置BEFORE,这是因为Oracle需要先获取序列值,然后在将值插入数据库中。

<!-- Oracle数据库的示例,注意:Oracle的写法的话id主键是需要写在SQL语句中 -->
<insert id="insert3">
    <selectKey keyColumn="id" resultType="int" keyProperty="id" order="BEFORE">
        SELECT SEQ_ID.nextval FROM dual
    </selectKey>
    INSERT INTO user(id, username, password)
    VALUES(#{id}, #{username}, #{password})
</insert>

2.5 update用法

UserMapper.java

public interface UserMapper {
	/**
	 * 根据主键更新
	 * @param user
	 * @return
	 */
	int updateById(User user);
}

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.xiangty.mapper.UserMapper">
	<update id="updateById">
		UPDATE user
		SET username=#{username},
			password=#{password}
		WHERE id=#{id}
	</update>
</mapper>

UserTest.java

@Test
public void updateById() {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setId(10);
        user.setUsername("demo3_修改");
        user.setPassword("demo3_修改");
        int result = userMapper.updateById(user);

        sqlSession.commit();
        if (result > 0) {
            System.out.println("updateById方法修改成功,主键:" + user.getId());
        } else {
            System.out.println("修改失败");
        }
    } catch (Exception e) {
        // 发生异常回滚事务
        sqlSession.rollback();
        e.printStackTrace();
    } finally {
        sqlSession.close();
    }
}

程序输出:
DEBUG [main] - ==>  Preparing: UPDATE user SET username=?, password=? WHERE id=? 
DEBUG [main] - ==> Parameters: demo3_修改(String), demo3_修改(String), 10(Integer)
DEBUG [main] - <==    Updates: 1
updateById方法修改成功,主键:10

2.6 delete用法

UserMappe.java

public interface UserMapper {
	/**
	 * 通过username模糊删除
	 * @param user
	 * @return
	 */
	int deleteByUsername(User user);
}

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.xiangty.mapper.UserMapper">
	<delete id="deleteByUsername">
		DELETE FROM user WHERE username LIKE CONCAT('%',#{username},'%')
	</delete>
</mapper>

UserTest.java

@Test
public void deleteById() {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setUsername("demo");
        int result = userMapper.deleteByUsername(user);

        sqlSession.commit();
        if (result > 0) {
            System.out.println("deleteById方法删除成功");
        } else {
            System.out.println("删除失败");
        }
    } catch (Exception e) {
        // 发生异常回滚事务
        sqlSession.rollback();
        e.printStackTrace();
    } finally {
        sqlSession.close();
    }
}

输出内容:
DEBUG [main] - ==>  Preparing: DELETE FROM user WHERE username LIKE CONCAT('%',?,'%') 
DEBUG [main] - ==> Parameters: demo(String)
DEBUG [main] - <==    Updates: 6
deleteById方法删除成功

2.7 多个接口参数用法

在实际应用中经常会遇到使用多个参数的情况。前面的例子是将多个参数合并到一个JavaBean中间,用这个JavaBean作为参数。如果没遇到这样的情况就创建JavaBean会造成JavaBean过多,那么MyBatis提供了两种方法:使用Map或者@Param注解。

方法一:使用Map类型做为参数的方法,就是在Map中通过key来映射XML中SQL使用的参数值名字,value来存放参数值,需要多个参数是,通过Map的key-value方式传递参数值。

UserMappe.java

public interface UserMapper {
	/**
	 * 根据用户和密码查询用户-参数以map的参数形式
	 * @param paramterMap
	 * @return
	 */
	List<User> selectUserByUsernameAndPassword2(Map<String, String> paramterMap);
}

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.xiangty.mapper.UserMapper">
	<select id="selectUserByUsernameAndPassword2" resultType="com.xiangty.bean.User" parameterType="java.util.Map">
		SELECT id, username, password
		FROM user
		WHERE username = #{username}
		AND password = #{password}
	</select>
</mapper>

UserTest.java

@Test
public void selectUserByUsernameAndPassword2(){
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        Map<String, String> paramterMap = new HashMap<>();
        paramterMap.put("username", "demo3");
        paramterMap.put("password", "demo3");
        List<User> userList = userMapper.selectUserByUsernameAndPassword2(paramterMap);
        userList.forEach(user -> System.out.println(user));
    } finally {
        sqlSession.close();
    }
}

输出内容:
DEBUG [main] - ==>  Preparing: SELECT id, username, password FROM user WHERE username = ? AND password = ? 
DEBUG [main] - ==> Parameters: demo3(String), demo3(String)
TRACE [main] - <==    Columns: id, username, password
TRACE [main] - <==        Row: 12, demo3, demo3
DEBUG [main] - <==      Total: 1
User [id=12, username=demo3, password=demo3]

方法二:使用@Param注解,注:Param注解的value值和xml中SQL中使用的属性映射一致。

UserMappe.java

public interface UserMapper {
	/**
	 * 根据用户和密码查询用户
	 * @param username
	 * @param password
	 * @return
	 */
	List<User> selectUserByUsernameAndPassword(@Param(value="username") String username,@Param(value="password") String password);
}

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.xiangty.mapper.UserMapper">
	<select id="selectUserByUsernameAndPassword" resultType="com.xiangty.bean.User">
		SELECT id, username, password
		FROM user
		WHERE username = #{param1} <!-- 使用#{username}也可以  -->
		AND password = #{param2} <!-- 使用#{password}也可以 -->
	</select>
</mapper>

UserTest.java

@Test
public void selectUserByUsernameAndPassword(){
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.selectUserByUsernameAndPassword("demo3", "demo3");
        userList.forEach(user -> System.out.println(user));
    } finally {
        sqlSession.close();
    }
}

输出内容:
DEBUG [main] - ==>  Preparing: SELECT id, username, password FROM user WHERE username = ? AND password = ? 
DEBUG [main] - ==> Parameters: demo3(String), demo3(String)
TRACE [main] - <==    Columns: id, username, password
TRACE [main] - <==        Row: 12, demo3, demo3
DEBUG [main] - <==      Total: 1
User [id=12, username=demo3, password=demo3]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zPA06dON-1614513937815)(C:\Users\xiangty\Desktop\s8.jpg)]

如果文档中有任何问题,可以直接联系我,便于我改正和进步。希望文档对您有所帮助。文档中代码GitHub地址:https://gitee.com/xiangty1/learn-MyBatis/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值