数据输出
- 无非就是使用相应的数据类型对返回的数据进行接收。
- 对于update操作一般就使用整型来接收
- 对于查询数据,要编写对应的实体类来进行数据接收
单个简单类型
// mapper接口
int selectEmpCount();
<!-- mapper配置文件 -->
<!-- select标签,通过resultType指定查询返回值类型 -->
<!-- resultType = "全限定符 | 别名 | 若是返回集合类型,直接写泛型类型" -->
<select id="selectEmpCount" resultType="int">
select count(*) from t_emp
</select>
// 测试
@Test
public void testEmpCount() {
EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
int count = employeeMapper.selectEmpCount();
log.info("count = " + count);
}
关于别名
- 类型别名可以为Java类型设置一个缩写名字,它只用于XML配置,意在降低冗余的全限定类名书写
- 列如
<typeAliases><typeAlias alias = "Author" type = "domain.blog.Author"></typeAlias></typeAliases>
- 这样配置时,Author可以在任意地方使用domain.blog.Author
- 列如
- 同时,也可以指定一个包名,MyBatis会在包名下搜索需要的Java Bean
<typeAliases> <package name="domain.blog"/> </typeAliases>
- 每一个在包
domain.blog
中的JavaBean,在没有注解的情况下,会使用Bean的首字母小写的非限定类名来作为它的别名 - 列如
@Alias("author") public class Author{...}
- 常见Mybatis与java别名映射
- _byte:byte
- _char:char
- _long:long
- _short:short
- _int:int
- _double:double
- _float:float
- _boolean:boolean
- _string:String
- byte:Byte
- char:Character
- character:Character
- long:Long
- short:Short
- int:Integer
- integer:Integer
- double:Double
- float:Float
- boolean:Boolean
- date:Date
- decimal:BigDecimal
- bigdecimal:BigDecimal
- biginteger:BigInteger
- object:Object
- object[]:Object[]
- map:Map
- hashmap:HashMap
- list:List
- arraylist:ArrayList
- collection:Collection
- 总的来说,对于别名映射,java中小写的名称Mybatis在最前面加下划线;java中大驼峰命名的,Mybatis将所有字母全小写
返回实体类对象
// Mapper接口方法
Employee selectEmployee(Integer empId)
<!-- mapper配置文件 -->
<!-- 编写具体的SQL语句,使用id属性唯一的标记一条SQL语句 -->
<!-- resultType属性:指定封装查询结果的Java实体类的全类名 -->
<select id="selectEmployee" resultType="com.atli.mybatis.entity.Employee">
<!-- Mybatis负责把SQL语句中的#{}部分替换成“?”占位符 -->
<!-- 给每一个字段设置一个别名,让别名和Java实体类中属性名一致 -->
select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{maomi}
</select>
<!-- Mybatis全局配置文件 -->
<!-- 在全局范围内对Mybatis进行配置 -->
<settings>
<!-- 具体配置 -->
<!-- 从org.apache.ibatis.session.Configuration类中可以查看能使用的配置项 -->
<!-- 将mapUnderscoreToCamelCase属性配置为true,表示开启自动映射驼峰式命名规则 -->
<!-- 规则要求数据库表字段命名方式:单词_单词 -->
<!-- 规则要求Java实体类属性名命名方式:首字母小写的驼峰式命名 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
- 通过给数据库表字段加别名,让查询结果的每一列都和java实体类中属性对应起来
- 增加全局配置自动识别对应关系
- 在Mybatis配置文件中使用配置实现驼峰命名映射
返回Map类型
适用于SQL查询返回的各个字段综合起来并不和任何一个现有实体类对应,没法封装到实体类对象中。
// mapper接口抽象方法
Map<String,Object> selectEmpNameAndMaxSalary();
<!-- mapper配置文件 -->
<!-- Map<String,Object> selectEmpNameAndMaxSalary(); -->
<!-- 返回工资最高的员工的姓名和他的工资 -->
<select id="selectEmpNameAndMaxSalary" resultType="map">
SELECT
emp_name 员工姓名,
emp_salary 员工工资,
(SELECT AVG(emp_salary) FROM t_emp) 部门平均工资
FROM t_emp WHERE emp_salary=(
SELECT MAX(emp_salary) FROM t_emp
)
</select>
// 测试
@Test
public void testQueryEmpNameAndSalary() {
EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
Map<String, Object> resultMap = employeeMapper.selectEmpNameAndMaxSalary();
Set<Map.Entry<String, Object>> entrySet = resultMap.entrySet();
for (Map.Entry<String, Object> entry : entrySet) {
String key = entry.getKey();
Object value = entry.getValue();
log.info(key + "=" + value);
}
}
返回List类型
查询结果返回多个实体类对象,希望把多个实体类对象放在List集合中返回,此时不需要任何特殊处理
// mapper接口中抽象方法
List<Employee> selectAll();
<!-- mapper配置 -->
<!-- List<Employee> selectAll(); -->
<select id="selectAll" resultType="com.atli.mybatis.entity.Employee">
select emp_id empId,emp_name empName,emp_salary empSalary
from t_emp
</select>
// 测试
@Test
public void testSelectAll() {
EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
List<Employee> employeeList = employeeMapper.selectAll();
for (Employee employee : employeeList) {
log.info("employee = " + employee);
}
}
返回主键值
自增长类型组件
// mapper接口的抽象方法
int insertEmployee(Employee employee)
<!-- mapper配置类 -->
<!-- int insertEmployee(Employee employee); -->
<!-- useGeneratedKeys属性字面意思就是“使用生成的主键” -->
<!-- keyProperty属性可以指定主键在实体类对象中对应的属性名,Mybatis会将拿到的主键值存入这个属性 -->
<insert id="insertEmployee" useGeneratedKeys="true" keyProperty="empId">
insert into t_emp(emp_name,emp_salary)
values(#{empName},#{empSalary})
</insert>
// 测试
@Test
public void testSaveEmp() {
EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
Employee employee = new Employee();
employee.setEmpName("john");
employee.setEmpSalary(666.66);
employeeMapper.insertEmployee(employee);
log.info("employee.getEmpId() = " + employee.getEmpId());
}
- 注意:Mybatis是将自增主键的值设置到实体类对象中,而不是以Mapper接口方法返回值的形式返回
非自增长类型主键
对于不支持自增型主键的数据库,或者字符串类型主键,则可以使用selectKey子元素:selectKey元素将会首先运行,id会被设置,然后插入语句会被调用,
<!-- xml -->
<insert id="insertUser" parameterType="User">
<selectKey keyProperty="id" resultType="java.lang.String"
order="BEFORE">
SELECT UUID() as id
</selectKey>
INSERT INTO user (id, username, password)
VALUES (
#{id},
#{username},
#{password}
)
</insert>
- 此处定义了一个insertUser的插入语句来将User对象插入到user表中。使用selectKye来查询UUID并设置到id字段中
- 通过keyProperty属性来指定查询到的UUID赋值给对象中的id属性,而resultType属性指定了UUID的类型为java.lang.String
- 需要注意的是,我们将selectKey放在了插入语句的前面,这是因为MySQL在insert语句中只支持一个select子句,而selectKey中查询UUID的语句是一个select自居,故需要放在前面
- 最后将User对象插入到user表中,我们直接使用对象中的id属性来插入主键值
- 使用这种方式,我们可以方便地插入UUID作为字符串类型组件。当然还有其他插入方式可以使用,如使用Java代码生成UUID并在类中显式设置值等,需要根据具体应用场景和需求选择合适的插入方式
实体类属性和数据库字段对应关系
别名对应
- 将字段的别名设置成和实体类属性一致
- 关于实体类属性的约定
- get和set方法把方法名中的get和set去掉,之后首字母小写
<!-- 编写具体的SQL语句,使用id属性唯一的标记一条SQL语句 -->
<!-- resultType属性:指定封装查询结果的Java实体类的全类名 -->
<select id="selectEmployee" resultType="com.atguigu.mybatis.entity.Employee">
<!-- Mybatis负责把SQL语句中的#{}部分替换成“?”占位符 -->
<!-- 给每一个字段设置一个别名,让别名和Java实体类中属性名一致 -->
select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{maomi}
</select>
全局配置自动识别驼峰命名规则
<!-- mybatis全局配置 -->
<!-- 使用settings对Mybatis全局进行设置 -->
<settings>
<!-- 将xxx_xxx这样的列名自动映射到xxXxx这样驼峰式命名的属性名 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- mapper配置文件 -->
<!-- Employee selectEmployee(Integer empId); -->
<select id="selectEmployee" resultType="com.atli.mybatis.entity.Employee">
select emp_id,emp_name,emp_salary from t_emp where emp_id=#{empId}
</select>
使用resultMap定义结果集映射
- 使用resultMap标签定义对应关系,再在后面的SQL语句中引用这个对应关系
<!-- 专门声明一个resultMap设定column到property之间的对应关系 -->
<resultMap id="selectEmployeeByRMResultMap" type="com.atguigu.mybatis.entity.Employee">
<!-- 使用id标签设置主键列和主键属性之间的对应关系 -->
<!-- column属性用于指定字段名;property属性用于指定Java实体类属性名 -->
<id column="emp_id" property="empId"/>
<!-- 使用result标签设置普通字段和Java实体类属性之间的关系 -->
<result column="emp_name" property="empName"/>
<result column="emp_salary" property="empSalary"/>
</resultMap>
<!-- Employee selectEmployeeByRM(Integer empId); -->
<select id="selectEmployeeByRM" resultMap="selectEmployeeByRMResultMap">
select emp_id,emp_name,emp_salary from t_emp where emp_id=#{empId}
</select>