上一章【Mybatis】MyBatis对表执行CRUD操作(三),已经讲了基本操作,本章介绍Sql配置文件中常用功能
1、插入返回主键
2、参数值的获取方式
3、resultMap使用
插入返回主键
在实际项目中,插入一条数据,id是数据库自动生成的,但是我们插入完数据,往往需要返回数据的id进行使用。
1、在EmployeeMapper.xml映射文件中加入2条sql
1 <!-- parameterType 可写可不写 --> 2 <insert id="insertEmployee" parameterType="com.hd.test.pojo.Employee"> 3 insert into employee(last_name, email, gender) values(#{lastName}, #{email}, #{gender}) 4 </insert> 5 6 <!-- 7 获取自增主键的值: 8 mysql支持自增主键,自增主键值的获取,mybatis也是利用statement.genGenreatedKeys() 9 useGeneratedKeys="true",使用自增主键获取主键值策略 10 keyProperty:指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值封装给JavaBean的属性 11 --> 12 <insert id="insertEmployeeReturnId" parameterType="com.hd.test.pojo.Employee" useGeneratedKeys="true" keyProperty="id"> 13 insert into employee(last_name, email, gender) values(#{lastName}, #{email}, #{gender}) 14 </insert>
2、EmployeeMapper接口中加入方法
1 // 新增 2 public Integer insertEmployee(Employee employee); 3 4 // 新增并返回id 5 public Integer insertEmployeeReturnId(Employee employee);
3、单元测试类方法
1 @Test 2 public void test5() throws IOException { 3 4 // 获取SqlSessionFactory 5 InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); 6 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 7 8 // 获取的sqlsession自动提交数据 9 SqlSession session = sqlSessionFactory.openSession(true); 10 try { 11 EmployeeMapper mapper = session.getMapper(EmployeeMapper.class); 12 13 // 插入数据 14 Employee employee = new Employee("小黑", "1", "[email protected]"); 15 Integer returnValue = mapper.insertEmployee(employee); 16 System.out.println("插入小黑返回值:" + returnValue); 17 System.out.println("插入后小黑对象:" + employee); 18 19 Employee employee2 = new Employee("小白", "1", "[email protected]"); 20 Integer returnValue2 = mapper.insertEmployeeReturnId(employee2); 21 System.out.println("插入小黑返回值:" + returnValue2); 22 System.out.println("插入后小黑对象:" + employee2); 23 24 } finally { 25 session.close(); 26 } 27 }
4、运行单元测试类,结果如下:
参数值的获取方式
1、#{},可以获取普通变量的值、map中的值或者pojo对象属性的值;
2、${},只能获取map中的值或者pojo对象属性的值;
区别:
#{}:是以预编译的形式,将参数设置到sql语句中;PreparedStatement;防止sql注入
${}:取出的值直接拼装在sql语句中;会有安全问题;
大多情况下,我们去参数的值都应该去使用#{},特色情况可以使用${},
比如:按照年份分表拆分 select * from ${year}_salary;
案例:
使用前面的查询sql
1、使用#{},获取参数
sql如下:
1 <select id="getEmployeeByMap" resultType="com.hd.test.pojo.Employee"> 2 select id, last_name lastName, gender, email from employee where id = #{id} 3 </select>
Mapper接口中加入方法
1 public Employee getEmployeeByMap(Map map);
测试代码
1 /** 2 * 查询 3 * @throws IOException 4 */ 5 @Test 6 public void test() throws IOException { 7 8 InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); 9 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 10 SqlSession session = sqlSessionFactory.openSession(); 11 12 try { 13 EmployeeMapper mapper = session.getMapper(EmployeeMapper.class); 14 Map<String, Object> map = new HashMap<String, Object>(); 15 Employee employee = mapper.getEmployeeByMap(map); 16 // 输出信息 17 System.out.println("查询返回值:" + employee); 18 } finally { 19 // 关闭session 20 session.close(); 21 } 22 }
执行,输出结果
2、使用${},获取参数
修改sql如下:
1 <select id="getEmployeeByMap" resultType="com.hd.test.pojo.Employee"> 2 select id, last_name lastName, gender, email from employee where id = #{id} 3 </select>
测试代码,执行,输出结果
通过日志,可以看出,使用 #{}格式的语法会导致 MyBatis 创建 PreparedStatement 参数并安全地设置参数,而使用${}格式直接在 SQL 语句中插入一个不转义的字符串
resultMap使用
在项目开发中,表中的字段名和表对应实体类的属性名称不一定都是完全相同的,这是我们可以通过<resultMap>来映射字段名和实体类属性名的一一对应关系
案例:
employee表字段如下:
1 -- ---------------------------- 2 -- Table structure for employee 3 -- ---------------------------- 4 DROP TABLE IF EXISTS `employee`; 5 CREATE TABLE `employee` ( 6 `id` int(11) NOT NULL AUTO_INCREMENT, 7 `last_name` varchar(255) DEFAULT NULL, 8 `gender` char(1) DEFAULT NULL, 9 `email` varchar(255) DEFAULT NULL, 10 PRIMARY KEY (`id`) 11 ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
Employee实体类:
1 package com.hd.test.pojo; 2 3 public class Employee { 4 5 private Integer id; 6 private String lastName; 7 private String gender; 8 private String email; 9 public Integer getId() { 10 return id; 11 } 12 public void setId(Integer id) { 13 this.id = id; 14 } 15 public String getLastName() { 16 return lastName; 17 } 18 public void setLastName(String lastName) { 19 this.lastName = lastName; 20 } 21 public String getGender() { 22 return gender; 23 } 24 public void setGender(String gender) { 25 this.gender = gender; 26 } 27 public String getEmail() { 28 return email; 29 } 30 public void setEmail(String email) { 31 this.email = email; 32 } 33 @Override 34 public String toString() { 35 return "Employee [id=" + id + ", lastName=" + lastName + ", gender=" + gender + ", email=" + email + "]"; 36 } 37 38 39 }
可以看到其中表字段last_name与实体类中属性lastName不对应,此时需要使用到<resultMap>,sql配置文件如下:
1 <!--自定义某个javaBean的封装规则 2 type:自定义规则的Java类型 3 id:唯一id方便引用 4 --> 5 <resultMap type="com.hd.test.pojo.Employee" id="EmployeeMap"> 6 <!--指定主键列的封装规则 7 id定义主键会底层有优化; 8 column:指定哪一列 9 property:指定对应的javaBean属性 10 --> 11 <id column="id" property="id"/> 12 <!-- 定义普通列封装规则 --> 13 <result column="last_name" property="lastName"/> 14 <!-- 其他不指定的列会自动封装:我们只要写resultMap就把全部的映射规则都写上。 --> 15 <result column="email" property="email"/> 16 <result column="gender" property="gender"/> 17 </resultMap> 18 19 <select id="getEmployeeById" resultMap="EmployeeMap"> 20 select id, last_name, gender, email from employee where id = ${id} 21 </select>
通过测试代码,执行,调用getEmployeeById方法,可以看出查出来的Employee对象,属性lastName也是有值的。
原文地址:https://www.cnblogs.com/h--d/p/10323012.html