MyBatis的传参与增删改查
传入多个参数值时
当Sql需要传入参数时,传入参数的地方要使用${}(字符串拼接,会导致sql注入问题,且要加’')或者#{}(占位符替代方式)
<!-- select * from t_user where username = #{username} -->
若要传入多个参数时,不能直接使用传入的形参名称作为参数,而要是用arg0、arg1来获取传入的参数,这是因为在mybatis中,若传入了多个参数,传入的参数是以键值对的方式存储在底层中的,存储方式为:(arg0-values1、arg1-values2…)
示例:
<!-- User getUserByUsername(String username);-->
<select id="getUserByUsername" resultType="user">
<!-- select * from t_user where username = #{username} -->
select * from t_user where username = #{arg0} and password = #{arg1}
<!-- 或者这样写
select * from t_user where username = '${username}'
-->
</select>
接口:
User checkLoginByMap(Map<String, Object> map);
当然,我们也可以自定义底层中存储的map表,只需要在最终测试前在mapper调用mapper接口时传入map就可以,例如这样:
<select id="checkLoginByMap" resultType="User">
select * from t_user where username = #{username} and password = #{password}
</select>
调用过程:
@Test
public void testCheckLoginByMap(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
Map<String, Object> map = new HashMap<>();
map.put("username", "admin");
map.put("password", "123456");
User user = mapper.checkLoginByMap(map);
System.out.println(user);
}
手动封装的工具类如下:
public static SqlSession getSqlSession() {
SqlSession sqlSession = null;
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession(true);
} catch (IOException e) {
throw new RuntimeException(e);
}
return sqlSession;
}
若参数是一个实体类对象时
直接使用实体类对象的属性使用#{}进行赋值,注意此处的#{}中的内容不是实体类中的属性,而是指get方法中去掉get以及将字母小写后得到的属性,所以实体类中所有的get、set方法必须完整编写。
接口:
int insertUser(User user);
sql:
<insert id="insertUser">
insert into t_user values(null, #{username}, #{password}, #{age}, #{sex}, #{email})
</insert>
调用:
@Test
public void testCheckLoginByMap(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
mapper.insertUser(new User(null, "root", "123456", 16, "f", "11569874123"));
}
插入成功
便捷设置sql中的键
使用@Param键便捷设置传入多个参数时的键:
接口:
//使用@Param注解将形参赋值给map集合,Param中的参数就是键
User checkLoginByParam(@Param("username")String username, @Param("password")String password);
sql:
<select id="checkLooginByParam" resultType="User">
select * from t_user where username = #{username} and password = #{password}
</select>
调用:
@Test
public void testCheckLoginByParam(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
User root = mapper.checkLoginByParam("root", "123456");
System.out.println(root);
}
注意mybatis在使用@Param注解时会有两种存储方式,一种是键设为@Param中的键值,另一种的使Param1、Param2作为键
Mybatis的各种查询功能
注意在查询例如select count(*)类似的功能时,要resultType要写java.lang.Integer
当要进行多表查询时,接口的返回值应该定义为map。表中的数据就会以键值对的形式存储在map集合中,而map集合返回给浏览器就是一个json对象,非常便于操作。
接口:
/**
* 根据id查询用户信息为一个Map集合
*/
Map<String, Object> getUserByIdToMap(@Param("id") Integer id);
sql:
/**
* 根据id查询用户信息为一个Map集合
*/
Map<String, Object> getUserByIdToMap(@Param("id") Integer id);
调用:
@Test
public void testGetUserByIdToMap() {
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
System.out.println(mapper.getUserByIdToMap(3));
}
//{password=123456, sex=m, id=3, age=23, email=123456@qq.com, username=admin}
当查询结果为多条数据时
一种方式是将返回值设置为一个map类型的List,像下面这样:
List<Map<String, Object>> getAllUsersToMap();
另一种方式是在接口上添加@MapKey注解,其value属性是寻找sql中的对应字段,并将该字段的值作为键,整条记录的其他字段作为一个个键值对存储在一个Map中
接口:
/**
* 查询所有信息并转换为map
* @MapKey()注解通过将value的字段作为键,每一条信息作为值来插入数据
*/
@MapKey("id")
Map<String, Object> getAllUsersToMap();
sql:
<!-- Map<String, Object> getAllUsersToMap();-->
<select id="getAllUsersToMap" resultType="map">
select * from t_user
</select>
调用:
@Test
public void testGetAllUsersToMap() {
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
System.out.println(mapper.getAllUsersToMap());
}
模糊查询
根据用户名进行模糊查询,在进行模糊查询时,需要插入必要的符号例如%,_等,此时可以使用${}使用拼接的方式进行模糊查询:
示例一:
接口
/**
* 根据用户名通过模糊查询获取参数
* @param username
* @return
*/
List<User> getUserByLike(@Param("username") String username);
sql
<!-- List<User> getUserByLike(@Param("username") String username);-->
<select id="getUserByLike" resultType="User">
select * from t_user where username like '%${username}%'
</select>
调用和前面一样,不粘贴了。
或者使用占位符和字符串contact函数进行字符串拼接实现模糊查询的效果:
sql:
<!-- List<User> getUserByLike(@Param("username") String username);-->
<select id="getUserByLike" resultType="User">
select * from t_user where username like concat('%', #{username}, '%')
</select>
或者第三种,直接靠在一起也可以最终得到字符串拼接在一起的效果:
<select id="getUserByLike" resultType="User">
select * from t_user where username like "%"#{username}"%"
</select>
批量删除
批量删除传入的条件必须被组合成一个字符串,其delete中的传值方式只能使用${}。
接口:
/**
* 批量删除
*/
int deleteMore(@Param("ids") String ids);
SQL:
<!-- 注意批量删除只能使用${},不能使用#{}-->
<!-- int deleteMore(@Param("ids") String ids);-->
<delete id="deleteMore">
delete from t_user where id in (${ids})
</delete>
调用:
@Test
public void testDeleteMore() {
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
int result = mapper.deleteMore("1,2,3,4");
System.out.println(result);
}
其他问题
获取自增主键
如何获取自增主键
接口:
/**
* 如何获取自增的主键
*/
void insertUser(User user);
sql:
<!-- void insertUser(User user);-->
<!-- useGenerateKeys属性设置为true表示允许获取自增主键的信息
keyProperty信息代表自增主键在获取之后将主键存储在哪个变量里,例如下面的例子就是将变量存储在id中
-->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert into t_user values(null, #{username}, #{password}, #{age}, #{sex}, #{email})
</insert>
调用:
@Test
public void testInsertUser() {
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
User user = new User(null, "adddd", "567", 20, "m", "589@788.com");
mapper.insertUser(user);
System.out.println(user);
}
//User{id=5, username='adddd', password='567', age=20, sex='m', email='589@788.com'}
//将id存储在了插入的user对象中