MyBatis基于传统DAO模式开发
4.1mybatis查询的三种方式
准备SqlSessionUtil 便于我们获得sqlSession对象
public class SqlSessionUtil {
private static SqlSessionFactory factory;
static {
InputStream ins = null;
try {
ins = Resources.getResourceAsStream("mybatis.xml");
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
factory = builder.build(ins);
}
public static SqlSession getSqlSession(){
SqlSession sqlSession = factory.openSession();
return sqlSession;
}
}
1返回单个对象
2返回对象List集合
3返回对象Map集合
Mapper 映射文件
<mapper namespace="com.bjsxt.mapper.EmpMapper">
<!--查询单个对象 根据员工编号查询员工信息-->
<select id="findOne" resultType="emp" >
select * from emp where empno = 7566
</select>
<!--查询多个对象的List集合
resultType 写的是集合中每个元素的数据类型
-->
<select id="findAll" resultType="emp">
select * from emp
</select>
<!--查询多个对象的map集合-->
<select id="findEmpMap" resultType="map">
select * from emp
</select>
</mapper>
测试 代码
package com.bjsxt.testDemo;
import com.bjsxt.pojo.Emp;
import com.bjsxt.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Test1 {
public static void main(String[] args) throws IOException {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
// 查询单个对象
Emp emp = sqlSession.selectOne("findOne");
System.out.println(emp);
// 查询多个对象的List集合
List<Emp> emps = sqlSession.selectList("findAll");
for(Emp em:emps){
System.out.println(em);
}
// 查询多个对象的map集合 sql语句的id map集合中键的名称
/*
* 键 值
* 值的某个属性 emp对象
* 值的某个属性 emp对象
* */
Map<Integer, Emp> empMap = sqlSession.selectMap("findEmpMap", "EMPNO");
Set<Integer> empnos = empMap.keySet();
for (Integer empno: empnos) {
System.out.println(empno+":"+empMap.get(empno));
}
sqlSession.close();
}
}
4.2mybatis参数传递的三种方式
1 单个基础数据类型作为参数
2 多个基础数据类型的map 集合作为参数
3 引用类型作为参数
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.bjsxt.mapper.EmpMapper2">
<!--
问题1:parameterType 用于标记参数的数据类型的,要和实际传入的参数的数据类型保持一致
parameterType 可以省略不写 但是如果写了,就要写对
问题2:在sql语句上可以使用两个符号接受参数
${} 代表Mybatis底层使用 Statement语句对象处理参数 参数采用字符串拼接方式放入sql语句中
#{} 代表Mybatis底层使用 预编译语句对象处理参数 参数采用?作为占位符,sql语句进行预处理后执行
-->
<!--单个基础数据类型作为参数 根据员工编号查询单个员工信息
单个基本数据类型作为sql语句参数 $ # 后面的大括号里面可以随便写
Emp findEmpByEmpno (int empno){} 好比参数列表中的参数名是可以随意定义
-->
<select id="findEmpByEmpno" resultType="emp" parameterType="int">
select * from emp where empno = ${empno}
</select>
<!--多个基础数据类型的Map集合作为参数 查询指定部门的 高于指定薪资的员工信息
sql语句中如何放入参数 大括号中方的是参数的键
-->
<select id="findEmpByDeptnoAndSal" resultType="emp" parameterType="map">
select * from emp where deptno = #{a} and sal >#{b}
</select>
<!--单个引用类型作为参数
大括号中应该写参数的属性名
-->
<select id="findEmpByDeptnoAndSal2" resultType="emp" parameterType="emp">
select * from emp where deptno = #{deptno} and sal >#{sal}
</select>
</mapper>
测试代码
package com.bjsxt.testDemo;
import com.bjsxt.pojo.Emp;
import com.bjsxt.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test2 {
public static void main(String[] args) {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
/*1单个基本数据类型作为方法参数*/
Emp emp = sqlSession.selectOne("findEmpByEmpno", 7566);
System.out.println(emp);
/*2多个基本数据类型map集合作为方法参数
*将参数放入一个map集合
*将集合作为参数传递给sql色素四栋
* */
Map<String,Object> params=new HashMap<String,Object>();
params.put("a",10);
params.put("b",1500);
List<Emp> emps = sqlSession.selectList("findEmpByDeptnoAndSal", params);
for(Emp em:emps){
System.out.println(em);
}
/*3单个引用类型作为方法参数*/
Emp param2=new Emp();
param2.setDeptno(10);
param2.setSal(1500.0);
List<Emp> emps2 = sqlSession.selectList("findEmpByDeptnoAndSal2", param2);
for(Emp em:emps2){
System.out.println(em);
}
sqlSession.close();
}
}
4.3mybatis完成DML全部操作和事务控制
SqlSessionUtil修改
package com.bjsxt.util;
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 java.io.IOException;
import java.io.InputStream;
public class SqlSessionUtil {
private static SqlSessionFactory factory;
static {
InputStream ins = null;
try {
ins = Resources.getResourceAsStream("mybatis.xml");
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
factory = builder.build(ins);
}
public static SqlSession getSqlSession(boolean autoCommit){
/*
* factory.openSession(true) 事务自动提交
* 如果不传入 true 默认为false
* */
SqlSession sqlSession = factory.openSession(autoCommit);
return sqlSession;
}
}
Mapper映射文件
<mapper namespace="com.bjsxt.mapper.EmpMapper3">
<!--
增删改语句返回都是int
所以 insert delete update标签没有 resultType属性
-->
<!--
向emp表中增加一条数据
-->
<insert id="addEmp" parameterType="emp" >
insert into emp (empno,ename,job,sal) values (null,#{ename},#{job},#{sal})
</insert>
<!--
修改一条数据 根据员工编号修改员工姓名
-->
<update id="updateEmp" parameterType="map">
update emp set ename =#{ename} where empno =#{empno}
</update>
<!--
删除数据 根据员工编号删除员工信息
-->
<delete id="deleteEmp" parameterType="int">
delete from emp where empno = #{empno}
</delete>
</mapper>
测试代码
package com.bjsxt.testDemo;
import com.bjsxt.pojo.Emp;
import com.bjsxt.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.omg.CORBA.OBJECT_NOT_EXIST;
import java.util.HashMap;
import java.util.Map;
/*
* sqlsession默认事务是自动打开的,增删改需要调用commit方法才能提交
* 可以设置mybatis事务自动提交
* factory.openSession(true);
*
* */
public class Test3 {
public static void main(String[] args) {
SqlSession sqlSession = SqlSessionUtil.getSqlSession(false);
Emp emp =new Emp();
emp.setSal(2000.0);
emp.setJob("SALESMAN");
emp.setEname("放开啦小猪");
/* 增加数据*/
//int rows = sqlSession.insert("addEmp", emp);
//System.out.println(rows);
/* 修改数据 */
/* Map<String, Object> params=new HashMap<String,Object>();
params.put("ename","Mark");
params.put("empno",7939);
int rows = sqlSession.update("updateEmp", params);*/
/*删除数据*/
int rows = sqlSession.delete("deleteEmp", 7939);
System.out.println(rows);
// 手动提交事务
sqlSession.commit();
sqlSession.close();
}
}
mybatis如何手动控制事务的提交和回滚呢?
4.4Mybatis关于事务的控制
准备表格:
准备实体类
public class Account implements Serializable {
private Integer aid;
private String username;
private String password;
private Integer money;
通过转账测试事务
mapper映射文件
<mapper namespace="com.bjsxt.mapper.AccountMapper">
<update id="updateAccount" parameterType="account">
update account set money =money + #{money} where aid =#{aid}
</update>
</mapper>
测试代码
package com.bjsxt.testDemo;
import com.bjsxt.pojo.Account;
import com.bjsxt.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
public class Test4 {
public static void main(String[] args) {
// 让事务手动提交 不要自动提交factory.openSession(false)
SqlSession sqlSession = SqlSessionUtil.getSqlSession(false);
try {
// 张三转出100
Account moneyOut=new Account();
moneyOut.setAid(1);
moneyOut.setMoney(-100);
sqlSession.update("updateAccount",moneyOut);
// 发生异常
int i =1/0;
// 李四转入100
Account moneyIn=new Account();
moneyIn.setAid(2);
moneyIn.setMoney(100);
sqlSession.update("updateAccount",moneyIn);
} catch (Exception e) {
// 捕获异常 事务回滚
sqlSession.rollback();
} finally {
// 提交事务
sqlSession.commit();
// 关闭sqlsession
sqlSession.close();
}
}
}
作业
1.将我们之前做的EmployeeSystem改为Mybatis基于传统DAO模式实现