mybatis
一. 传参
参数类型parameterType推荐不写,除非自定义类型与引用的第三方类型重名,需要特别指定。
(1) 传递一个参数(基本类型或其包装类型)
mapper接口: public interface PersonMapper { //根据员工编号获取员工信息和员工部门 public Person getPersonById(Integer id); } xml映射文件: <mapper namespqce="com.offcn.mapper.PersonMapper"> <select id="getPersonById" resultType="Person"> select * from person where id=#{id} </select> <mapper> 说明:此时可以用任意合法的名称接收
(2) 传递多个参数
mapper接口: public interface PersonMapper{ //定义一个方法传递两个参数 public List<Person> getPersonsBymany(Integer id,Integer age); } xml映射文件: <mapper namespace="com.offcn.mapper.PersonMapper"> <select id="getPersonsByMany" resultType="Person"> //arg+参数下标的形式。参数下标从0开始 select * from person where id > #{arg0} and age> #{arg1} </select> </mapper> <mapper namespace="com.offcn.mapper.PersonMapper"> <select id="getPersonsByMany" resultType="Person"> //param+参数下标的形式。参数下标从1开始 select * from person where id > #{param1} and age> #{param2} </select> </mapper>
使用@param注解指定参数名
mapper接口: public interface PersonMapper{ public List<Person> getPersonsByMany(@Param("id") Integer id, @Param("age") Integer age); } xml映射文件: <mapper namespace="com.offcn.mapper.PersonMapper"> <select id="getPersonsByMany" resultType="Person"> select * from person where id > #{id} and age> #{age} </select> </mapper>
#{参数名} 中的参数名要和@param("参数名")对应
(3) 传一个普通对象
mapper接口: public interface PersonMapper{ //传递一个javabean对象 public List<Person> getPersonsByMany(Person person); } xml映射文件: <mapper namespace="com.offcn.mapper.PersonMapper"> <select id="getPersonsByMany" resultType="Person"> select * from person where id > #{id} and age> #{age} </select> </mapper>
存在的问题:若传递的参数较少,在使用对象进行传递的时候我们依旧要创建这个对象,而创建对象是需要在内存中开辟空间的,这样的话就比较耗费内存。
此时可以用传map对象替换。
(4)传一个map对象
mapper接口: public interface PersonMapper{ //传递一个Map集合来获取Person public List<Person> getPersonByMap(Map<String,Object> map); }
xml映射文件: <mapper namespace="com.offcn.mapper.PersonMapper"> <select id="getPersonByMap" resultType="Person"> select * from person where id > #{id} and age> #{age} </select> </mapper>
(5)直接使用JSON传递参数
当controller层收到JSON型数据后,可以直接传递给mapper层进行查询操作,简单方便。
mapper接口: List <Employee> findByJSONObject(JSONObject params); xml映射文件: <select id="findByJSONObject" resultMap="BaseResultMap" parameterType="com.alibaba.fastjson.JSONObject"> select * from employee where gender = #{gender} and age = #{age} </select>
(6)传递集合类型 List、Set、Array
mapper接口: List <Employee> findByList(List list); xml文件映射: <select id="findByList" resultMap="BaseResultMap" > SELECT * from employee where age in <foreach collection="list" open="(" separator="," close=")" item="age"> #{age} </foreach> </select>
foreach元素的属性主要有 item,index,collection,open,separator,close。 item表示集合中每一个元素进行迭代时的别名, index指定一个名字,用于表示在迭代过程中,每次迭代到的位置, open表示该语句以什么开始, separator表示在每次进行迭代之间以什么符号作为分隔符, close表示以什么结束;
在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况: 1.如果传入的是单参数且参数类型是一个List的时候,collection属性值为list 2.如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array 3.如果传入的参数是多个的时候,我们就需要把它们封装成一个Map或者Object
(7)包含集合的对象
包含集合的对象: @Data public class Department { private Long id; private String deptName; private String descr; private Date createTime; List<Employee> employees; }
mapper接口: List <Employee> findByDepartment(@Param("department")Department department); xml文件映射: <select id="findByDepartment" resultMap="BaseResultMap" parameterType="com.wg.demo.po.Department"> SELECT * from employee where dept_id =#{department.id} and age in <foreach collection="department.employees" open="(" separator="," close=")" item="employee"> #{employee.age} </foreach> </select>
二. 返回对象接收-resultType
1.1 接收返回的基本类型或其封装类型。
1.2 接收对象时,实体类的属性名要和数据库表的列名一一对应。
1.3 当数据库表字段名中与实体类的属性名不一致时。(如果此时扔直接使用resultType,不一致属性值结果将为null)
方法一:为字段名设置别名
方法二:开启下划线映射为驼峰配置
<!--引入properties文件,此时就可以${属性名}的方式访问属性值--> <properties resource="jdbc.properties"/> <!--配置mybatis自动转换为驼峰式命名--> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> <!--开启延迟加载--> <setting name="lazyLoadingEnabled" value="true" /> </settings>
方法三:自定义resultMap
resultMap是为了解决实体类属性和数据库表列名不能对应上,而创建的一种解决方案。
resultMap自定义映射标签,type 处理映射关系的实体类类型,id实体类属性名-表列名的映射的唯一标识,result单条映射标签。
<resultMap id="empDeptMapResultMapOne" type="Emp"> <id property="eid" column="eid"></id> <result property="empName" column="emp_name"></result> <result property="age" column="age"></result> <result property="sex" column="sex"></result> <result property="email" column="email"></result> <result column="did" property="dept.did"></result> <result column="dname" property="dept.dname"></result> </resultMap> <select id="getEmpAndDept" resultMap="empDeptMapResultMapTwo"> select emp.*,dept.* from emp left join dept on emp.did = dept.did where emp.eid = #{eid} </select>
(1)返回值为简单类型(基本类型或其包装类型)
String getEmpNameById(Integer id); <!-- 指定 resultType 返回值类型时 String 类型的, string 在这里是一个别名,代表的是 java.lang.String 对于引用数据类型,都是将大写字母转小写,比如 HashMap 对应的别名是 'hashmap' 基本数据类型考虑到重复的问题,会在其前面加上 '_',比如 byte 对应的别名是 '_byte' --> <select id="getEmpNameById" resultType="string"> select username from t_employee where id = #{id} </select>
(2)返回值为List类型
使用resultType=“list元素的类型”,一般是实体类如User,也可以是Map,对应返回值类型是List<User> , List<Map<String,Object>>。
最终会将resultType指定的类型的元素(User或以一条记录为一个Map),组装成List。
(3)返回值为Map类型
1. 如果查询的结果是一条,我们可以把查询的数据以{表字段名, 对应的值}
方式存入到Map
中,多条会报错。
Map<String, Object> getEmpAsMapById(Integer id); <!-- 注意这里的 resultType 返回值类型是 'map' --> <select id="getEmpAsMapById" resultType="map"> select * from t_employee where id = #{id} </select>
2. 如果查询的结果是多条数据,我们也可以把查询的数据以{表中某一字段名, JavaBean}
方式来封装成Map
。
// 查询所有员工的信息,把数据库中的 'id' 字段作为 key,对应的 value 封装成 Employee 对象 // @MapKey 中的值表示用数据库中的哪个字段名作 key @MapKey("id") Map<Integer, Employee> getAllEmpsAsMap(); <!-- 注意 resultType 返回值类型,不再是 'map',而是 Map 的 value 对应的 JavaBean 类型 --> <select id="getAllEmpsAsMap" resultType="employee"> select * from t_employee </select>
扩展.:上面返回结果的形式都是基于查询 (select
) 的,其实对于增删改的操作也可以返回一定类型的数据,比如Boolean
,Integer