1. 获取插入数据后的自增主键
使用insert标签的属性:useGeneratedKeys="true" keyProperty="id"
<mapper namespace="com.hh.dao.EmployeeDao">
<!--
先设置useGeneratedKeys="true"
keyProperty:让mybatis自动的将自增id赋值给传入的employee对象的id属性
-->
<insert id="insertEmployee" useGeneratedKeys="true" keyProperty="id" >
insert into t_employee(empname,gender,email)
values(#{empName},#{gender},#{email})
</insert>
</mapper>
@Test
public void testInsert() throws IOException {
SqlSession sqlSession = sqlsessionFactory.openSession();
try {
Employee employee = new Employee(null, "zhnagsan", "zhangsan@qq.com", "0");
EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
int i = mapper.insertEmployee(employee);
System.out.println(i);
sqlSession.commit();
System.out.println("插入的主键:"+employee.getId());
} finally {
sqlSession.close();
}
}
2.参数传递问题
JavaBean:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {
private Integer id;
private String empName;
private String email;
private String gender;
}
从数据库中查询数据:仅传入一个参数
public interface EmployeeDao {
public Employee getEmpById(int id);
}
<select id="getEmpById" resultType="com.hh.bean.Employee">
select * from t_employee where id=#{id}
</select>
对于只有一个参数时我么可以使用#{属性名}
来取值,那么对于多个参数还可以吗?
public interface EmployeeDao {
public Employee getEmpByIdAndName(int id,String empName);
}
<select id="getEmpByIdAndName" resultType="com.hh.bean.Employee">
select * form t_employee where id=#{id} and empname=#{empName}
</select>
测试类:
@Test
public void testSelectByIdAndName() throws IOException {
SqlSession sqlSession = sqlsessionFactory.openSession();
EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
//传入getEmpByIdAndName(1,"admin"),能取出吗?
Employee employee = mapper.getEmpByIdAndName(1,"admin");
System.out.println(employee);
sqlSession.close();
}
可以看到报了异常,也就是说当传入的参数有多个时,不可以再使用#{属性名}
取值。根据异常提醒,可以传入的参数0,1(索引)或者param1,param2(参数标识)来取值,这是因为传入多个参数时,mybatis会自动将其封装为map
<select id="getEmpByIdAndName" resultType="com.hh.bean.Employee">
select * from t_employee where id=#{0} and empname=#{1}
</select>
<select id="getEmpByIdAndName" resultType="com.hh.bean.Employee">
select * from t_employee where id=#{param1} and empname=#{param2}
</select>
但是不推荐使用这两种方式,首先不够直观,其次如果改变了传入参数的位置也会出现问题。
如果还想按照#{属性名}
来取值怎么办?下面来介绍两种解决方法:
方法1:推荐使用
因为方法传入多个参数时会自动的封装为map,可以在传入参数的前面加上一个注解,用来指定参数封装成map时所用的key
public interface EmployeeDao {
public Employee getEmpById(int id);
public Employee getEmpByIdAndName( @Param("id") int id,@Param("empName") String empName);
}
这时就可以通过#{key}
取值
<select id="getEmpByIdAndName" resultType="com.hh.bean.Employee">
select * from t_employee where id=#{id} and empname=#{empName}
</select>
方法2:
不让MyBatis自动封装为map,直接使用map将参数封装。
public interface EmployeeDao {
public Employee getEmployeeByIdAndName(Map<String,Object> map);
}
手动封装时就是按照JavaBean的属性名作为key的
<select id="getEmployeeByIdAndName" resultType="com.hh.bean.Employee">
select * from t_employee where id=#{id} and empname=#{empName}
</select>
测试类:
@Test
public void testSelectByIdAndName1() throws IOException {
SqlSession sqlSession = sqlsessionFactory.openSession();
EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("id",1);
map.put("empName","admin");
Employee employee = mapper.getEmployeeByIdAndName(map);
System.out.println(employee);
sqlSession.close();
}
如果传入的为pojo:
public interface EmployeeDao {
public int insertEmployee(Employee employee);
}
<insert id="insertEmployee">
insert into t_employee(empname,gender,email)
values(#{empName},#{gender},#{email})
</insert>
@Test
public void testInsert() throws IOException {
SqlSession sqlSession = sqlsessionFactory.openSession();
try {
Employee employee = new Employee(null, "zhnagsan", "zhangsan@qq.com", "0");
EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
int i = mapper.insertEmployee(employee);
sqlSession.commit();
} finally {
sqlSession.close();
}
}
总结:
- 传单个参数
如果是基本类型:#{随便写}
如果传入的是pojo:#{pojo的属性名}
如果传入的是map:那么map的key默认为pojo的属性名,因此可以通过#{属性名}
进行取值。 - 传多个参数
如果传入多个参数,MyBatis会自动的将这些参数封装为map,但是key不确定,因此可以使用一个注解@Param
指定map的key
,取值时直接通过map的key进行取值,即#{key}
3.#与$的区别
#{属性名}
:参数预编译的方式,参数的位置都是用?
代替,参数时后来预编译设置进去的,相当于PreparedStatement
${属性名}
:不是参数预编译方式,而是直接和sql语句进行拼接,会引起SQL注入,相当于Statement
一般使用#{属性名}
,不支持预编译时,会使用${属性名}