例子、
<?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
<mapper namespace="com.atguigu.dao.EmployeeDao">
<!-- namespace="com.atguigu.dao.EmployeeDao":写dao接口的全类名 -->
<!-- 这个文件中能写的所有标签:
cache:和缓存有关
cache-ref:和缓存有关
parameterMap:参数map:废弃的。。。原本是来做复杂参数映射;
resultMap:结果映射:自定义结果集的封装规则;
sql:抽取可重用的sql;
delete、update、insert、select:增删改查;
databaseId:指定这个CRUD属于哪个数据库的;
-->
<!-- public int insertEmployee(Employee employee); -->
<!--
让MyBatis自动的将自增id赋值给传入的employee对象的id属性
useGeneratedKeys="true":原生jdbc获取自增主键的方法;
keyProperty="":将刚才自增的id封装给哪个属性
-->
<insert id="insertEmployee" useGeneratedKeys="true"
keyProperty="id">
INSERT INTO t_employee(empname,gender,email)
VALUES(#{empName},#{gender},#{email})
</insert>
<!-- public int insertEmployee2(Employee employee); -->
<insert id="insertEmployee2">
<!--查询主键
order="BEFORE":
在核心sql语句之前先运行一个查询sql查到id;将查到的id赋值给javaBean的哪个属性;
-->
<selectKey order="BEFORE" resultType="integer" keyProperty="id">
select max(id)+1 from t_employee
</selectKey>
INSERT INTO t_employee(id,empname,gender,email)
VALUES(#{id},#{empName},#{gender},#{email})
</insert>
<!--public int updateEmployee(Employee employee); -->
<update id="updateEmployee" >
UPDATE t_employee
SET
empname=#{empName},gender=#{gender},email=#{email}
WHERE id=#{id}
</update>
<!--public boolean deleteEmployee(Integer id); -->
<delete id="deleteEmployee" >
DELETE FROM t_employee WHERE id=#{id}
</delete>
<!-- 传参到底能传哪些 -->
<!-- public Employee getEmpById(Integer id); -->
<select id="getEmpById" resultType="com.atguigu.bean.Employee">
select * from t_employee
where id=#{haha}
</select>
<!-- Caused by: org.apache.ibatis.binding.BindingException:
Parameter 'id' not found.
Available parameters are [0, 1, param1, param2]
-->
<!--public Employee getEmpByIdAndEmpName(Integer id,String empName); -->
<select id="getEmpByIdAndEmpName" resultType="com.atguigu.bean.Employee">
select * from t_employee where id=#{id} and empname=#{empName}
</select>
<!-- public Employee getEmployeeByIdAndEmpName(Map<String, Object> map); -->
<select id="getEmployeeByIdAndEmpName" resultType="com.atguigu.bean.Employee">
select * from ${tableName} where id=#{id} and empname=#{empName}
</select>
<!--现象:
1)、单个参数:
基本类型:
取值:#{随便写}
传入pojo:
2)、多个参数:
public Employee getEmpByIdAndEmpName(Integer id,String empName)
取值:#{参数名}是无效了;
可用:0,1(参数的索引)或者param1,param2(第几个参数paramN)
原因:只要传入了多个参数;mybatis会自动的将这些参数封装在一个map中;
封装时使用的key就是参数的索引和参数的第几个表示
Map<String,Object> map = new HashMap<>();
map.put("1",传入的值);map.put("2","传入的值");
#{key}就是从这个map中取值;
3)、@Param:为参数指定key;命名参数;我们以后也推荐这么做;
我们可以告诉mybatis,封装参数map的时候别乱来,使用我们指定的key
4)传入了pojo(javaBean)
取值:#{pojo的属性名}
5)、传入了map:将多个要使用的参数封装起来
取值:#{key}
扩展:多个参数:自动封装map;
method01(@Param("id")Integer id,String empName,Employee employee);
Integer id -> #{id}
String empName -> #{param2}
Employee employee(取出这个里面的email) ->#{param3.email}
无论传入什么参数都要能正确的取出值;
#{key/属性名}
1)#{key}取值的时候可以设置一些规则:
id=#{id,jdbcType=INT};
javaType、jdbcType、mode、numericScale、resultMap、typeHandler、jdbcTypeName、expression
只有jdbcType才可能是需要被指定的;
默认不指定jdbcType;mysql没问题;oracle没问题;
万一传入的数据是null;
mysql插入null没问题;【oracle不知道null到底是什么类型;】
实际上在mybatis中:两种取值方式:
#{属性名}:是参数预编译的方式,参数的位置都是用?替代,参数后来都是预编译设置进去的;安全,不会有sql注入问题
${属性名}:不是参数预编译,而是直接和sql语句进行拼串;不安全;
//id=1 or 1=1 or and empname=
传入一个'1 or 1=1 or';
有:sql语句只有参数位置是支持预编译的;
log_2017_12、log_2018_1;
select * from log_2018_1 where id=? and empname=?
id=${id} and empname=#{empName}:
select * from t_employee where id=1 and empname=?
id=#{id} and empname=#{empName}:
select * from t_employee where id=? and empname=?
一般都是使用#{};安全;在不支持参数预编译的位置要进行取值就使用${};
-->
<!-- public List<Employee> getAllEmps(); -->
<!-- resultType="":如果返回的是集合,写的是集合里面元素的类型 -->
<select id="getAllEmps" resultType="com.atguigu.bean.Employee">
select * from t_employee
</select>
<!-- 查询返回一个map -->
<!--public Map<String, Object> getEmpByIdReturnMap(Integer id); -->
<select id="getEmpByIdReturnMap" resultType="map">
select * from t_employee where id=#{id}
</select>
<!-- 查询多个返回一个map;查询多个情况下:集合里面写元素类型;
public Map<Integer, Employee> getAllEmpsReturnMap(); -->
<select id="getAllEmpsReturnMap" resultType="com.atguigu.bean.Employee">
select * from t_employee
</select>
接口、
//
/**
* id empname gender email login_account
------ ------------ ------ -------------- ---------------
1 admin 0 admin@qq.com a
* @param id
* @return
*
* 列名作为key,值作为value
*/
public Map<String, Object> getEmpByIdReturnMap(Integer id);
public List<Employee> getAllEmps();
/**
* key就是这个记录的主键;value就是这条记录封装好的对象;
* @return
*
* 把查询的记录的id的值作为key封装这个map
* @MapKey("id")
*/
@MapKey("id")
public Map<Integer, Employee> getAllEmpsReturnMap();
public Employee getEmpById(Integer id);
public Employee getEmpByIdAndEmpName(@Param("id")Integer id,@Param("empName")String empName);
public Employee getEmployeeByIdAndEmpName(Map<String, Object> map);
public int updateEmployee(Employee employee);
public boolean deleteEmployee(Integer id);
public int insertEmployee(Employee employee);
public int insertEmployee2(Employee employee);
ResultMap的例子、
<mapper namespace="com.atguigu.dao.CatDao">
<!-- getCatById(Integer)
resultType="com.atguigu.bean.Cat":使用默认规则;属性列名一一对应
resultMap="mycat":查出数据封装结果的时候,使用mycat自定义的规则
-->
<select id="getCatById" resultMap="mycat">
select * from t_cat where id=#{id}
</select>
<!-- 自定义结果集(resultMap):自己定义每一列数据和javaBean的映射规则
type="":指定为哪个javaBean自定义封装规则;全类名
id="":唯一标识;让别名在后面引用
id cName cAge cgender
1 加菲猫 12 0
-->
<resultMap type="com.atguigu.bean.Cat" id="mycat">
<!-- 指定主键列的对应规则;
column="id":指定哪一列是主键列
property="":指定cat的哪个属性封装id这一列数据
-->
<id property="id" column="id"/>
<!-- 普通列 -->
<result property="name" column="cName"/>
<result property="age" column="cAge"/>
<result property="gender" column="cgender"/>
</resultMap>
</mapper>