文章目录
基础代码
减少重复代码量,在Test方法前后加@Before
@After
注解方法,对资源进行创建和释放。
private InputStream is = null;
private EmployeeMapper mapper = null;
private SqlSession sqlSession;
@Before //测试方法执行之前运行
public void init() throws IOException {
//1 读取配置文件
is = Resources.getResourceAsStream("SqlMapConfig.xml");
//2 创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(is);
//3 使用工厂生产SqlSession对象
sqlSession = factory.openSession();
//4 使用SqlSession创建Mapper接口的代理对象
mapper = sqlSession.getMapper(EmployeeMapper.class);
}
@After //测试方法之后释放资源
public void closeAll() throws IOException {
//提交事务
sqlSession.commit();
//6 释放资源
sqlSession.close();
is.close();
}
增加Create
增加员工信息
本案例使用员工对象,对员工数据库table进行操作。
在EmployeeMapper
接口中写入增加方法:
修改对应的映射文件:
注意使用insert
标签
其中Employee
对象通过idea自动生成get
set
方法在传入变量时可以直接使用变量名。传入格式使用mybatis格式#{变量名}
,而不是使用?
。
参数配置上parameterType
使用对象的全限定类名。
获取当前自增主键
selectKey
将SELECT LAST_INSERT_ID()的结果传入到最新主键中keyProperty
对应的主键属性名order
AFTER
表示在INSERT
操作执行之后执行SELECT LAST_INSERT_ID(),多用于自增主键
BEFORE
表示在INSERT
之前执行,这样就拿不到最新主键,适合于主键不是自增的类型。resultType
主键类型
<!-- 插入员工信息 -->
<insert id="saveEmployee" parameterType="objects.Employee">
<!-- 配置插入操作后,获取插入数据的id -->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into einfo values(#{id},#{name},#{sex},#{tel},#{addr},#{salary});
</insert>
查询Retrieve
根据id查员工
模糊查询
修改Update
修改员工信息
修改映射配置文件:
注意使用update
标签
加入修改方法:
测试方法:
直接使用mapper
即可,配置与释放默认执行
@Test
public void testUpdate() {
Employee ee = new Employee(10008, "l", "女", "9876", "HongKong", 2000.1);
mapper.updateEmployee(ee);
}
删除Delete
根据di删除员工
删除方法类似,增加删除方法,方法可以随便修改传入参数,在mapper调用方法时,对应传入即可。
增加配置文件
这里要注意如果只有一个变量,配置文件对应位置的#{变量名}
可以随意改变。对应的parameterType
也要进行修改
mapper调用方法传入的参数,就是配置文件中对应的#{变量名}
。
参数深入
parameterType(输入类型)
传递简单参数
传递Employee
对象,进行参数查询,或者使用int
,String
等基本类型
传递pojo包装对象
OGNL(对象导航图语言):通过对象的取值方法来获取数据。在写法上省略get
方法。例如获取用户名:类中写法:employee.getName()
;OGNL中写法:employee.name
。
常用语实际开发中,由多个对象组成一个查询条件。
Mybatis使用OGNL表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名。
创建QueryVo对象
使用该对象对Employee对象进行封装
public class QueryVo {
private Employee e;
public Employee getE() {
return e;
}
public void setE(Employee e) {
this.e = e;
}
}
修改配置文件
其中parameterType 传入QueryVo
对象,#{}中传入QueryVo
对象中的Employee
对象变量名e
,并获取变量信息e.addr
<!-- 使用QueryVo进行模糊查询 -->
<select id="selectByVo" parameterType="objects.QueryVo" resultType="objects.Employee">
select * from einfo where addr like #{e.addr}
</select>
接口中方法
测试方法
//测试pojo 模糊查询
@Test
public void testSelectByVo(){
QueryVo vo = new QueryVo();
Employee e = new Employee();
e.setAddr("北京%");
vo.setE(e);
List<Employee> employees = mapper.selectByVo(vo);
for (Employee ee : employees) {
System.out.println(ee);
}
}
结果类型封装ResultType
输出类型和输入类型相同,可以传入基本数据类型和对象类型。但是存在一个问题:当数据库的属性名和java程序中对象类中的对象变量名不同时,从数据库中读取到的数据就存入不到对象中。
存在实体类属性名不同的问题
查询语句:
对象类属性名:
数据库中属性名:
读取结果:
此时id 和 name 两个属性名不同,可以看出前两列数据没有赋值成功。
解决方法
改变select语句
这种方式也是最高效的方式,但是多条语句修改量过大。
select e_id as id,e_name as name,sex,tel,addr,salary from einfo;
使用resultMap
这种方法多解析一个XML标签,在执行上没有上一种方法高效,但是能很大提高开发效率。
对属性名进行配置,主键和非主键部分分开配置,property
表示对象类的属性名,column
表示数据库对应属性名。
在进行查询配置时,将原本的resultType
改为resultMap
对数据进行匹配
即可获得正确数据