MyBatis-注解配置sql语句与参数传递
1、注解配置sql语句
编写一个模块,使用注解去配置方法的sql语句
UserMapper接口:
public interface UserMapper {
/**
* @Insert 配置 insert的sql语句 <br/>
* @SelectKey 配置一个查询语句( 主要用于配置一个Select语句,用于查询主键 ) <br>
* statement 配置你的sql语句 <br>
* before 配置是否是先执行selectKey中语句 <br/>
* keyProperty 配置查询回来的Key主键给哪个属性赋值 <br/>
* resultType 属性配置返回的主键数据类型
* @param user
* @return
*/
@SelectKey(statement = "select last_insert_id()",before = false, keyProperty = "id",resultType = Integer.class)
@Insert("insert into t_user(`last_name`,`sex`) values(#{lastName},#{sex})")
public int saveUser(User user);
/**
* @Update 配置 update语句
* @param user
* @return
*/
@Update("update t_user set `last_name` = #{lastName} , `sex` = #{sex} where id = #{id}")
public int updateUserById(User user);
/**
* @Delete 注解 配置 delete 语句
* @param id
* @return
*/
@Delete("delete from t_user where id = #{id}")
public int deleteUserById(Integer id);
/**
*@Select 注解配置 select语句
* @param id
* @return
*/
@Select("select `id`, `last_name` lastName,`sex` from t_user where id = #{id}")
public User queryUserById(Integer id);
/**
* @Select 注解配置 select语句
* @return
**/
@Select("select `id`, `last_name` lastName,`sex` from t_user")
public List<User> queryUsers();
}
测试的代码:
public class UserMapperTest {
/**
* sqlSessionFactory是单例的. 一个数据库只有一个SqlSessionFactory对象实例
*/
static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init() throws Exception{
sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
}
@Test
public void saveUser() {
SqlSession session = sqlSessionFactory.openSession();
try {
// 获取UserMapper实现类
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User(null,"ddee" , 1);
System.out.println(userMapper.saveUser(user));
System.out.println(user);
session.commit();
} finally {
session.close();
}
}
@Test
public void updateUserById() {
SqlSession session = sqlSessionFactory.openSession();
try {
// 获取UserMapper实现类
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User(7,"bbj" , 0);
userMapper.updateUserById(user);
session.commit();
} finally {
session.close();
}
}
@Test
public void deleteUserById() {
SqlSession session = sqlSessionFactory.openSession();
try {
// 获取UserMapper实现类
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User(7,"bbj" , 0);
userMapper.deleteUserById(8);
session.commit();
} finally {
session.close();
}
}
@Test
public void queryUserById() {
SqlSession session = sqlSessionFactory.openSession();
try {
// 获取UserMapper实现类
UserMapper userMapper = session.getMapper(UserMapper.class);
System.out.println(userMapper.queryUserById(9));
} finally {
session.close();
}
}
@Test
public void queryUsers() {
SqlSession session = sqlSessionFactory.openSession();
try {
// 获取UserMapper实现类
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.queryUsers().forEach(System.out::println);
} finally {
session.close();
}
}
}
2、mybatis的参数传递
参数传递是指如何将mapper接口方法中的参数传递给sql语句的占位符. 简单点说,就是 #{} 里应该写啥
2.1、单个普通数据类型
Mapper接口:
public interface UserMapper {
public User queryUserById(Integer id) ;
}
Mapper.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">
<!--
namespace名称空间的值要改为对应的Mapper接口的全类名
-->
<mapper namespace="com.atguigu.mapper.UserMapper">
<!-- public User queryUserById(Integer id);
当Mapper接口参数是一个普通类型的时候,#{}中可以写任意的内容,
只是推荐写成为参数名.为了更好的可读性
-->
<select id="queryUserById" resultType="com.atguigu.pojo.User">
select `id`,`last_name` lastName,`sex` from t_user where id = #{id}
</select>
</mapper>
测试代码:
public class UserMapperTest {
static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init() throws Exception{
sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
}
@Test
public void queryUserById() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.queryUserById(1);
System.out.println(user);
} finally {
session.close();
}
}
}
2.2、多个普通数据类型
Mapper接口:
/**
* 根据给定的性别和名称查询用户信息 <br/>
*
* @Param("name") String name 表示将第一个参数的参数名设置为name.
*
* @return
*/
public List<User> queryUsersBySexOrName(String name, Integer sex);
Mapper.xml配置文件:
<!-- /**
* 根据给定的性别和名称查询用户信息
* @return
*/
public List<User> queryUsersBySexOrName(String name,Integer sex);
resultType属性是指定查询回来的每一行数据转换的具体的类型,
在传递的参数是多个普通类型的情况下.有两种方案可以传递参数的值到占位符中.
第一种情况是:
arg0 表示第一个参数
arg1 表示第二个参数
......以此类推
argN 表示第N+1个参数
第二种情况是:
param1 表示第一个参数
param2 表示第二个参数
......以此类推
paramN 表示第n个参数
-->
<select id="queryUsersBySexOrName" resultType="com.atguigu.pojo.User">
select
`id`,`last_name` lastName,`sex`
from
t_user
where
`last_name` = #{param1} or `sex` = #{param2}
</select>
测试的代码:
@Test
public void queryUsersBySexOrName(){
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.queryUsersBySexOrName("ccccccc", 1).forEach(System.out::println);
} finally {
session.close();
}
}
2.3、@Param注解命名参数
Mapper接口:
/**
* 根据给定的性别和名称查询用户信息 <br/>
*
* @Param("name") String name 表示将第一个参数的参数名设置为name.
*
* @return
*/
public List<User> queryUsersBySexOrName(@Param("name") String name, @Param("sex") Integer sex);
Mapper.xml配置文件:
<!--
public List<User> queryUsersBySexOrName(@Param("name") String name, @Param("sex") Integer sex);
如果我们在参数中使用了注解@Param("name") String name,则参数name的值可以通过注解指定的名称来进行传递
也就是如下:
@Param("name") String name =====>>>>> #{ name }
@Param("sex") Integer sex =====>>>>> #{ sex }
....... 以此类推
@Param("xxxx") Integer sex =====>>>>> #{ xxxx }
-->
<select id="queryUsersBySexOrName" resultType="com.atguigu.pojo.User">
select
`id`,`last_name` lastName,`sex`
from
t_user
where
`last_name` = #{name} or `sex` = #{sex}
</select>
2.4、传递一个Map对象作为参数
Mapper接口
/**
* 按照map中给定的name和sex来进行查询用户信息
* @param paramMap
* @return
*/
public List<User> queryUsersByMap(Map<String,Object> paramMap);
Mapper.xml
配置文件:
<!-- /**
* 按照map中给定的name和sex来进行查询用户信息
* @param paramMap
* @return
*/
public List<User> queryUsersByMap(Map<String,Object> paramMap);
如果传递的参数是Map类型,则在#{}中需要写上map的key值表示传递相应key的值到sql的占位符中.
示例代码:
UserMapper userMapper = session.getMapper(UserMapper.class);
Map<String,Object> map = new HashMap<>();
map.put("name","ccccccc");
map.put("sex",1);
userMapper.queryUsersByMap(map).forEach(System.out::println);
使用如下:
Map<String,Object> map = new HashMap<>();
map.put("name","ccccccc"); ====>>>> #{ name }
map.put("sex",1); ====>>>> #{ sex }
-->
<select id="queryUsersByMap" resultType="com.atguigu.pojo.User">
select
`id`,`last_name` lastName,`sex`
from
t_user
where
`last_name` = #{name} or `sex` = #{sex}
</select>
测试的代码
@Test
public void queryUsersByMap(){
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
Map<String,Object> map = new HashMap<>();
map.put("name","ccccccc");
map.put("sex",1);
userMapper.queryUsersByMap(map).forEach(System.out::println);
} finally {
session.close();
}
}
2.5、一个Pojo数据类型( pojo就是JavaBean )
Mapper接口:
/**
* 把 User 保存到数据库
* @param user
* @return
*/
public int saveUser(User user);
Mapper.xml
配置文件:
<!-- /**
* 把 User 保存到数据库
* @param user
* @return
*/
public int saveUser(User user);
如果参数是一个javaBean的时候,只需要在#{}占位符中写上对应数据库列的javaBean的属性名即可.
public class User {
private Integer id;
private String lastName; ====>>> #{lastName} 表示传递 lastName 属性值给相应的占位符
private Integer sex; ====>>> #{sex} 表示传递 sex 属性值给相应的占位符
-->
<insert id="saveUser" parameterType="com.atguigu.pojo.User">
insert
into t_user(`last_name`,`sex`)
values (#{lastName},#{sex})
</insert>
测试代码:
@Test
public void saveUser(){
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.saveUser(new User(null,"xxx", 1));
session.commit();
} finally {
session.close();
}
}
2.6、模糊查询
需求:现在要根据用户名查询用户对象。 也就是希望查询如下:
select * from t_user where user_name like '%张%'
Mapper接口:
/**
* 根据给定的name值做like模糊查询用户信息
* @param name
* @return
*/
public List<User> queryUsersByNameLike(String name);
Mapper.xml
配置文件:
<!-- /**
* 根据给定的name值做like模糊查询用户信息
* @param name
* @return
*/
public List<User> queryUsersByNameLike(String name);-->
<select id="queryUsersByNameLike" resultType="com.atguigu.pojo.User">
select
`id`,`last_name` lastName,`sex`
from
t_user
where
`last_name` like #{name}
</select>
测试的代码:
@Test
public void queryUsersByNameLike() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
String name = "%xx%";
userMapper.queryUsersByNameLike(name).forEach(System.out::println);
} finally {
session.close();
}
}
2.7、${}
的使用
#{}和${}
的区别
#{} 是占位符, 所以不会有sql注入的问题
${} 是把参数内容原样输出 , 然后和原sql语句做字符串拼接操作. 会有sql注入的安全性问题
#{} 在一个参数的时候,可以任意写内容
${} 里只能写value, 或者使用@Param注解
#{} 一般用于给参数注入值
${} 一般用于表名
2.8、MySQL的字符串拼接,concat函数实现
在Mapper.xml
中的使用:
<!-- /**
* 根据给定的name值做like模糊查询用户信息
* @param name
* @return
*/
public List<User> queryUsersByNameLike(String name);-->
<select id="queryUsersByNameLike" resultType="com.atguigu.pojo.User">
select
`id`,`last_name` lastName,`sex`
from
t_user
where
`last_name` like concat('%',#{name},'%');
</select>