目录
1_多种参数传递问题
1单个基本数据类型
2多个基本数据类型
3单个引用数据类型
4map集合数据类型
5多个引用数据类型
接口
package com.msb.mapper;
import com.msb.pojo.Emp;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* @Author: Ma HaiYang
* @Description: MircoMessage:Mark_7001
*/
public interface EmpMapper {
/**
* 该方法用于查询全部的员工信息
* @return 全部员工信息封装的Emp对象的List集合
*/
List<Emp> findAll();
/**
* 根据员工编号查询单个员工信息的方法
* @param empno 员工编号
* @return 如果找到了返回Emp对象,找不到返回null
*/
Emp findByEmpno(int empno);
/**
* 根据员工编号和薪资下限去查询员工信息
* @param empno 员工编号
* @param sal 薪资下限
* @return 多个Emp对象的List集合
*/
List<Emp> findByDeptnoAndSal(@Param("deptno") int deptno,@Param("sal") double sal);
List<Emp> findByDeptnoAndSal2(Map<String,Object> map);
List<Emp> findByDeptnoAndSal3(Emp emp);
List<Emp> findByDeptnoAndSal4(@Param("empa") Emp empa,@Param("empb") Emp empb);
}
mapper映射文件
<?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.msb.mapper.EmpMapper">
<!--
1 接口的名字和Mapper映射为文件名字必须保持一致(不包含拓展名)
2 Mapper映射文件的namespace必须是接口的全路径名
3 sql语句的id必须是对应方法的名
4 DeptMapper映射文件应该和接口编译之后放在同一个目录下
-->
<!--List<Emp> findAll();-->
<select id="findAll" resultType="emp" >
select * from emp
</select>
<!--
单个基本数据类型作为方法参数
#{}中可以随便写,遵循见名知意
Emp findByEmpno(int empno);
-->
<select id="findByEmpno" resultType="emp" >
select * from emp where empno =#{empno}
</select>
<!--
多个基本数据类型作为方法参数
List<Emp> findByDeptnoAndSal(@Param("detpno") int deptno,@Param("sal") double sal);
方式1 arg* arg0 arg1 arg2 数字是索引,从0开始
方式2 param* param1 param2 param3 数字是编号,从1开始
使用别名
List<Emp> findByDeptnoAndSal(@Param("detpno") int deptno,@Param("sal") double sal);
通过@Param注解使用别名之后,就不能再使用arg* 但是可以继续使用param*
-->
<select id="findByDeptnoAndSal" resultType="emp">
<!--select * from emp where deptno =#{arg0} and sal >= #{arg1}-->
<!-- select * from emp where deptno =#{param1} and sal >= #{param2}-->
<!-- select * from emp where deptno =#{deptno} and sal >= #{sal}-->
</select>
<!--
参数是map,{}写键的名字
-->
<select id="findByDeptnoAndSal2" resultType="emp" parameterType="map" >
<!--select * from emp where deptno =#{arg0} and sal >= #{arg1}-->
<!-- select * from emp where deptno =#{param1} and sal >= #{param2}-->
select * from emp where deptno =#{deptno} and sal >= #{sal}
</select>
<!--单个引用类型,{}中写的使用对象的属性名-->
<select id="findByDeptnoAndSal3" resultType="emp" parameterType="emp" >
select * from emp where deptno =#{deptno} and sal >= #{sal}
</select>
<!--
多个引用类型作为方法参数
List<Emp> findByDeptnoAndSal4(@Param("empa") Emp empa,@Param("empb") Emp empb);
如果用@Param定义了别名,那么就不能使用arg*.属性名,但是可以使用param*.属性名和别名.属性名
-->
<select id="findByDeptnoAndSal4" resultType="emp" >
<!-- select * from emp where deptno =#{arg0.deptno} and sal >= #{arg1.sal} -->
select * from emp where deptno =#{param1.deptno} and sal >= #{param2.sal}
<!-- select * from emp where deptno =#{empa.deptno} and sal >= #{empb.sal}-->
</select>
</mapper>
测试 代码
package com.msb.testDemo;
import com.msb.mapper.EmpMapper;
import com.msb.pojo.Emp;
import com.msb.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class Test1 {
public static void main(String[] args) {
SqlSession sqlSession = SqlSessionUtil.getSqlSession(true);
/*
* 帮助我们生成一个接口下的实现类对象的
*
* */
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> emps = mapper.getAllEmp();
for(Emp emp:emps) {
System.out.println(emp);
}
// 1单个基本数据类型作为方法参数
Emp emp = mapper.getByEmpno(7902);
System.out.println(emp);
// 2多个基本数据类型作为方法参数
List<Emp> emps2 = mapper.getByDeptnoAndSal(10, 1500);
for(Emp em:emps2) {
System.out.println(em);
}
// 3单个引用类型作为方法参数
Emp condition=new Emp();
condition.setDeptno(10);
condition.setSal(1500.0);
List<Emp> emps3 = mapper.getByDeptnoAndSal2(condition);
for(Emp em:emps3) {
System.out.println(em);
}
// 4多个引用类型作为方法参数
Emp condition1=new Emp();
condition1.setDeptno(10);
Emp condition2=new Emp();
condition2.setSal(1500.0);
List<Emp> emps4 = mapper.getByDeptnoAndSal3(condition1,condition2);
for(Emp em:emps4) {
System.out.println(em);
}
sqlSession.close();
}
}
2_模糊查询功能
在进行模糊查询时,在映射文件中可以使用concat()函数来连接参数和通配符。另外注意对于特殊字符,比如<,不能直接书写,应该使用字符实体替换。
接口
/**
* 根据名字做模糊查询
* @param name 模糊查询的文字
* @return Emp对象List集合
*/
List<Emp> findByEname( String name);
mapper映射文件
<!--List<Emp> getByName(String name);-->
<select id="findByEname" resultType="emp" >
select * from emp where ename like concat('%',#{name},'%')
</select>
3_主键自增回填
MySQL支持主键自增。有时候完成添加后需要立刻获取刚刚自增的主键,由下一个操作来使用。比如结算构造车后,主订单的主键确定后,需要作为后续订单明细项的外键存在。如何拿到主键呢,MyBatis提供了支持,可以非常简单的获取。
接口
public interface DeptMapper {
int addDept(Dept dept);
int addDept2(Dept dept);
}
mapper映射文件
<mapper namespace="com.msb.mapper.DeptMapper">
<!-- int addDept(Dept dept);
useGeneratedKeys="true" 返回数据库帮我们生成的主键
keyProperty="deptno" 生成的主键值用我们dept对象那个属性存储
-->
<insert id="addDept" parameterType="dept" useGeneratedKeys="true" keyProperty="deptno">
insert into dept values(null,#{dname},#{loc})
</insert>
<insert id="addDept2" parameterType="dept">
<selectKey order="AFTER" keyProperty="deptno" resultType="int">
select @@identity
</selectKey>
insert into dept values(null,#{dname},#{loc})
</insert>
</mapper>
测试代码
SqlSession sqlSession = SqlSessionUtil.getSqlSession(true);
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
Dept dept =new Dept(null,"AI学院","北京");
int i = mapper.addDept2(dept);
System.out.println(i);
System.out.println(dept.getDeptno());
sqlSession.close();
方式1
useGeneratedKeys:表示要使用自增的主键
keyProperty:表示把自增的主键赋给JavaBean的哪个成员变量。
以添加Dept对象为例,添加前Dept对象的deptno是空的,添加完毕后可以通过getDeptno() 获取自增的主键。
方式2
order:取值AFTER|BEFORE,表示在新增之后|之前执行<selectKey>中的SQL命令
keyProperty:执行select @@identity后结果填充到哪个属性中
resultType:结果类型。
技术扩展
在很多应用场景中需要新增数据后获取到新增数据的主键值,针对这样的需求一般由三种解决方式:
主键自定义,用户通过UUID或时间戳等方式生成唯一主键,把这个值当做主键值。在分布式场景中应用较多。
查询后通过select max(主键) from 表获取主键最大值。这种方式在多线程访问情况下可能出现问题。
查询后通过select @@identity获取最新生成主键。要求这条SQL必须在insert操作之后,且数据库连接没有关闭。
4_实现DML操作
EmpMapper接口
/**
* 增加员工信息
* @param emp 存储新增员工信息的Emp对象
* @return 对数据库数据产生影响的行数
*/
int addEmp(Emp emp);
/**
* 根据员工编号修改员工姓名的方法
* @param empno 要修改的员工编号
* @param ename 修改之后的新的员工名字
* @return 对数据库数据产生影响的行数
*/
int updateEnameByEmpno(@Param("empno") int empno,@Param("ename") String ename);
/**
* 根据员工编号删除员工信息
* @param empno 要删除的员工编号
* @return 对数据库数据产生影响的行数
*/
int deleteByEmpno(int empno);
EmpMapper映射 文件
<!--int addEmp(Emp emp);-->
<insert id="addEmp" >
insert into emp values(DEFAULT ,#{ename},#{job},#{mgr},#{hiredate},#{sal},#{comm},#{deptno})
</insert>
<!--int updateEnameByEmpno(@Param("empno") int empno,@Param("ename") String ename);-->
<update id="updateEnameByEmpno" >
update emp set ename =#{ename} where empno =#{empno}
</update>
<!--int deleteByEmpno(int empno);-->
<update id="deleteByEmpno" >
delete from emp where empno =#{empno}
</update>
测试代码
package com.msb.test;
import com.msb.mapper.DeptMapper;
import com.msb.mapper.EmpMapper;
import com.msb.pojo.Dept;
import com.msb.pojo.Emp;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
/**
* @Author: Ma HaiYang
* @Description: MircoMessage:Mark_7001
*/
public class Test3 {
private SqlSession sqlSession;
@Before
public void init(){
SqlSessionFactoryBuilder ssfb =new SqlSessionFactoryBuilder();
InputStream resourceAsStream = null;
try {
resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory factory=ssfb.build(resourceAsStream) ;
sqlSession=factory.openSession();
}
@Test
public void testAddEmp(){
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
mapper.addEmp(new Emp(null, "TOM", "SALESMAN", 7521, new Date(), 2314.0, 100.0, 10));
sqlSession.commit();
}
@Test
public void testUpdateEnameByEmpno(){
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
mapper.updateEnameByEmpno(7938, "TOM");
sqlSession.commit();
}
@Test
public void testDeletByEmpno(){
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
mapper.deleteByEmpno(7938);
sqlSession.commit();
}
@After
public void release(){
// 关闭SQLSession
sqlSession.close();
}
}