一、Mapper与XML进行CRUD
1.select
- Mapper接口方法:public Employee getEmployeeById(Integer id);
- Mapper映射文件:
<select id="getEmployeeById" resultType="com.mybatis.beans.Employee"> select * from tbl_employee where id = ${_parameter} </select>
2.insert
- Mapper接口方法:public Integer insertEmployee(Employee employee);
- Mapper映射文件:
<insert id="insertEmployee" parameterType="com.mybatis.beans.Employee" > insert into tbl_employee(last_name,email,gender) values(#{lastName},#{email},#{gender} </insert>
3.update
- Mapper接口方法:public Boolean updateEmployee(Employee employee);
- Mapper映射文件:
<update id="updateEmployee" > update tbl_employee set last_name = #{lastName}, email = #{email}, gender = #{gender} where id = #{id} </update>
4.delete
- Mapper接口方法:public void deleteEmployeeById(Integer id );
- Mapper映射文件:
<delete id="deleteEmployeeById" > delete from tbl_employee where id = #{id} </delete>
二、参数传递
1.获取参数的两种方式${},#{}:
- ${}。通过Statement处理sql语句,不能通过通配符赋值,必须使用字符串拼接的方式操作SQL,需要手动添加单引号。【模糊查询和批量删除时使用${}】
- #{}。通过PrepareStatement操作SQL语句【防止SQL注入】,可以使用通配符操作SQL,通配符会自动加单引号。
通配符赋值时,与名字没关系,与顺序有关系
${}取值时,默认会把传过来的参数作为一个实体类对象,然后把大括号内的内容作为属性,通过get方法去取得属性所对应的值
2.获得不同参数值的方式
不同参数类型,${},#{}的不同取值方式:t
- 当传输参数为单个String或者基本数据类型和其它包装类时:${}:只能以${value}或者${_parameter}获取.。 #{}:可以以任意的名字获取参数值。
- 当传输参数为JavaBean时,${},#{} 都可以通过属性名直接获得属性值,但是要注意${}的单引号问题。
- 当传输参数多个参数时,可以写 #{0},#{1},#{param1},#{param2},不可以写${0},${1}【计算值】,可以${param1},${param2}。原因:传输多个参数时,mybatis默认会将这些参数放在map集合中。所以可以把参数直接封装在一个map里面。
- 当传输参数封装在map里时,${},#{},都可以通过key的名字来获取value,但是需要注意${}的单引号问题。
- 命名参数,可以通过在接口中方法的参数前面添加 @param("key")为map集合指定键的名字。
- 当传输参数为List或Array时,Mybatis把参数放在map中,List以list为键,Array以array为键。
三、添加对象时获得自动生成的id
1.MySQL,SQL Server等支持主键支持主键自增,可以设置useGeneratedKeys=“true”,然后把keyProperty设置到目标属性上。
<insert id="insertEmployee"
parameterType="com.mybatis.beans.Employee"
databaseId="mysql"
useGeneratedKeys="true"
keyProperty="id"> //keyProperty:生成的主键要赋值给对象的哪一个属性
insert into tbl_employee(last_name,email,gender) values(#{lastName},#{email},#{gender})
</insert>
四、多对一与一对多的表关系查询
假设有两个Bean对象,员工Emp 与 部门Dept,一个员工属于一个部门,一个部门下有多个员工。
public class Emp { // get,set方法省略
private Integer eid;
private String ename;
private Integer age;
private String sex;
private Dept dept;
}
public class Dept {
private Integer did;
private String dname;
}
1.查询所有员工信息
//1.EmpDeptMapper中定义方法:
List<Emp> getAllEmp();
//2.EmpDeptMapper.xml中配置SQL映射
<resultMap type="Emp" id="empMap">
<id column="eid" property="eid"/>
<result column="ename" property="ename"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
<association property="dept" javaType="Dept">
<id column="did" property="did"/>
<result column="dname" property="dname"/>
</association>
</resultMap>
<select id="getAllEmp" resultMap="empMap">
select e.eid,e.ename,e.age,e.sex,e.did,d.dname from emp e left join dept d on e.did = d.did
</select>
//3.测试方法
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);//自动处理事务
EmpDeptMapper mapper = sqlSession.getMapper(EmpDeptMapper.class);
List<Emp> emp = mapper.getAllEmp();
System.out.println(emp);
解释:<resultMap>:自定义映射,处理复杂的表关系
<id column="eid" property="eid"/>
<id>:设置主键的映射关系,column设置字段名,property设置属性名
<result column="ename" property="ename"/>
<result>:设置非主键的映射关系,column设置字段名,property设置属性名<association> 使用联合查询,并以级联属性的方式封装对象.使用association标签定义对象的封装规则:通过association去帮忙创建一个javaType所写的对象,然后赋值给property所指的对象。也可以不用association标签,直接通过prepertry="对象.属性名赋值"
2.查询某个员工的信息,必要时再查对应的部门信息。分步查询,懒加载!
// 1.Mapper接口中的方法
Emp getEmpStep(String eid);
Dept getDeptEmpsByDid(String did);
// 2. Mapper.xml中的SQL映射配置
<resultMap type="Emp" id="empMapStep">
<id column="eid" property="eid"/>
<result column="ename" property="ename"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
<association property="dept" select="com.mybatis.mapper.DeptMapper.getDeptByDid" column="did"/>
</resultMap>
<select id="getEmpStep" resultMap="empMapStep">
select eid,ename,age,sex,did from emp where eid = #{eid}
</select>
解释:
select:分步查询的SQL的id,即接口的全限定名.方法名或namespace.SQL的id
column:分步查询的条件,注意:此条件必须是从数据库查询得来的。
3.查询一个部门的信息,以及部门下的所有员工
// 1.Mapper接口中的方法
Dept getDeptEmpsByDid(String did);//此时Dept里有属性List<Emp> list;
// 2.Mapper.xml配置SQL映射
<resultMap type="Dept" id="deptMap">
<id column="did" property="did"/>
<result column="dname" property="dname"/>
<collection property="emps" ofType="Emp">
<id column="eid" property="eid"/>
<result column="ename" property="ename"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
</collection>
</resultMap>
<select id="getDeptEmpsByDid" resultMap="deptMap">
select d.did,d.dname,e.eid,e.ename,e.age,e.sex from dept d left join emp e on d.did = e.did where d.did = #{did}
</select>
解释:
<collection>: 处理一对多和多对多的关系
ofType:指集合中的类型,不需要指定javaType。
4.分步查询查询一个部门的信息,以及部门下的所有员工
// 1.Mapper接口中的方法
Dept getOnlyDeptByDid(String did);
List<Emp> getEmpListByDid(String did);
// 2.Mapper.xml中的SQL映射
<select id="getEmpListByDid" resultType="Emp">
select eid,ename,age,sex from emp where did = #{did}
</select>
<resultMap type="Dept" id="deptMapStep">
<id column="did" property="did"/>
<result column="dname" property="dname"/>
<collection property="emps" select="com.mybatis.mapper.EmpDeptMapper.getEmpListByDid" column="{did=did}" fetchType="eager"></collection>
</resultMap>
<select id="getOnlyDeptByDid" resultMap="deptMapStep">
select did,dname from dept where did = #{did}
</select>
解释:
1. 开启延迟加载:<setting name="lazyLoadingEnabled" value="true"/>
2. 设置加载的数据是按需还是全部:<setting name="aggressiveLazyLoading" value="false"/>
3. 单独指定某一个sql语句的延迟加载情况。在association或collection内的属性,fetcyType="lazy" 代表懒加载,fetcyType="eager"不进行懒加载。
4. collection用来处理一对多,多对多的关系,ofType指定集合中的数据类型,不需要指定javaType。
5. 如果分步查询时,需要传递给调用的查询中多个参数,则需要将多个参数封装成 Map来进行传递,语法如下: {k1=v1, k2=v2....}
其他
自动处理事务 :
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);//true表示自动处理事务如果没有传递true,则需要手动提价事务。【sqlSession.commit();】
通过<package>配置映射文件的引入:
【要求mapper接口与xml配置文件在同一个包下 [ 即包的名字相同 ] 】
<!-- 引入映射文件 --> <mappers> <!-- 此种写法用于一个mapper接口写一个配置信息,麻烦~~ /> <mapper resource="DeptMapper.xml" /> --> <!-- 此种写法要求mapper接口和mapper映射文件必须在同一个包下 --> <package name="com.mybatis.mapper"/> </mappers>