Mybatis映射文件简介
1) MyBatis 的真正强大在于它的映射语句。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。
2) SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):
cache – 给定命名空间的缓存配置。
cache-ref – 其他命名空间缓存配置的引用。
resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语
例如:EmpMapper.java接口
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.atguigu.mapper; import java.util.List; import com.atguigu.bean.Emp; public interface EmpMapper { //根据eid查询一个员工信息 Emp getEmpByEid(String eid); //获取所有的员工信息 List<Emp> getAllEmp(); //添加员工信息 void addEmp(Emp emp); //修改员工信息 void updateEmp(Emp emp); //删除员工信息 Boolean deleteEmp(String eid); }
数据bean,注意在mybatis-config.xml中,typeAliases配置起别名,默认为类名称
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.atguigu.bean; public class Emp { private Integer eid; private String ename; private Integer age; private String sex; private Dept dept; public Dept getDept() { return dept; } public void setDept(Dept dept) { this.dept = dept; } public Integer getEid() { return eid; } public void setEid(Integer eid) { this.eid = eid; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "Emp [eid=" + eid + ", ename=" + ename + ", age=" + age + ", sex=" + sex + ", dept=" + dept + "]"; } public Emp(Integer eid, String ename, Integer age, String sex) { super(); this.eid = eid; this.ename = ename; this.age = age; this.sex = sex; } public Emp() { super(); // TODO Auto-generated constructor stub } }
映射文件EmpMapper.xml
<?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.mapper.EmpMapper"> <!-- Emp getEmpByEid(String eid); --> <select id="getEmpByEid" resultType="Emp"> select eid,ename,age,sex from emp where eid = #{eid} </select> <!-- List<Emp> getAllEmp(); --> <select id="getAllEmp" resultType="Emp"> select eid,ename,age,sex from emp </select> <!-- void addEmp(Emp emp); --> <insert id="addEmp"> insert into emp values(null,#{ename},#{age},#{sex}) </insert> <!-- void updateEmp(Emp emp); --> <update id="updateEmp"> update emp set ename = #{ename}, age = #{age}, sex = #{sex} where eid = #{eid} </update> <!-- void deleteEmp(String eid); --> <delete id="deleteEmp"> delete from emp where eid = #{eid} </delete> </mapper>
同时需要记得在mybatis-config.xml文件中进行配置映射文件位置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- <properties>:设置或引入资源文件 resource:在类路径下访问资源文件 url:在网络路径或磁盘路径下访问资源文件 --> <properties resource="jdbc.properties"></properties> <settings> <!-- 将下划线映射成驼峰,user_name映射为userName --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 开启延迟加载 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 是否查询所有数据 --> <setting name="aggressiveLazyLoading" value="false"/> </settings> <typeAliases> <!-- 为类型设置类型别名 type:Java 类型,若只设置type,默认的别名就是类型,且不区分大小写 --> <!-- <typeAlias type="com.atguigu.bean.User" alias="u"/> --> <package name="com.atguigu.bean"/> </typeAliases> <!-- <environments>:设置连接数据库的环境 default:设置默认使用的数据库环境 --> <environments default="mysql"> <!-- <environment>:设置某个具体的数据库的环境 id:数据库环境的唯一标示 --> <environment id="mysql"> <!-- type="JDBC|MANAGED",JDBC:使用JDBC原生的事务管理方式,即提交和回滚都需要手动处理 --> <transactionManager type="JDBC" /> <!-- type="POOLED|UNPOOLED|JNDI" --> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> <environment id="oracle"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/ssm" /> <property name="username" value="root" /> <property name="password" value="123456" /> </dataSource> </environment> </environments> <!-- 引入映射文件 --> <mappers> <!-- <mapper resource="EmpMapper.xml" /> <mapper resource="DeptMapper.xml" /> --> <!-- 此种写法要求mapper接口和mapper映射文件必须在同一个包下,可以设置相同的包名 --> <package name="com.atguigu.mapper"/> </mappers> </configuration>
创建测试类TestCRUD:
package com.atguigu.test; import java.io.IOException; import java.io.InputStream; import java.util.List; 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.Test; import com.atguigu.bean.Emp; import com.atguigu.mapper.EmpMapper; public class TestCRUD { @Test public void testCRUD() throws IOException { InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //SqlSession sqlSession = sqlSessionFactory.openSession();//需要手动处理事务 SqlSession sqlSession = sqlSessionFactory.openSession(true);//自动处理事务 EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class); //测试:根据eid获取员工信息 /*Emp emp = empMapper.getEmpByEid("3"); System.out.println(emp);*/ //测试:获取所有的员工信息 /*List<Emp> list = empMapper.getAllEmp(); System.out.println(list);*/ //测试:添加员工信息 /*empMapper.addEmp(new Emp(null, "admin", 23, "女")); sqlSession.commit();//提交事务*/ //测试:修改员工信息 empMapper.updateEmp(new Emp(6, "张二", 33, "女")); //测试:删除员工信息 /*Boolean i = empMapper.deleteEmp("2"); System.out.println("result:"+i);*/ //select 字段名 from 表名 where 条件 group by 字段名 having 条件 order by 字段名 desc/asc limit index,pageSize } }
需要注意的问题:
①关于事务管理
SqlSession sqlSession = sqlSessionFactory.openSession();//这种方法创建下需要手动处理事务
<!-- type="JDBC|MANAGED",JDBC:使用JDBC原生的事务管理方式,即提交和回滚都需要手动处理 -->
<transactionManager type="JDBC" />
而下面这种创建就会自动提交
SqlSession sqlSession = sqlSessionFactory.openSession(true);//自动处理事务
②对于返回值
增删改:可以在接口中直接指明返回值类型:Interger(返回修改作用的行数),Boolean(是否发生修改)
查:直接写相应的查询返回类型即可。
例如:查询单个员工对象:Emp getEmpByEid(String eid);
查询多个员工对象:List<Emp> getAllEmp();
但是resultType 都是Emp对象类型,mybatis会很智能的对返回结果进行处理,只需要指明正确的查询返回类型。
③关于映射文件的配置
当通过包的方式引入映射文件时,但要求mapper接口和mapper映射文件必须在同一个包下,可以设置相同的包名。
<mappers> <!-- <mapper resource="EmpMapper.xml" /> <mapper resource="DeptMapper.xml" /> --> <!-- 此种写法要求mapper接口和mapper映射文件必须在同一个包下,可以设置相同的包名 --> <package name="com.atguigu.mapper"/> </mappers>
④SQL语句中获取参数的两种方式
1) #{key}:获取参数的值,预编译到SQL中。安全。相当于PrepareStatement,利用通配符.
2) ${key}:获取参数的值,拼接到SQL中。有SQL注入问题。相当于Statement,涉及到字符串的拼接,字符串部分一定要注意单引号问题。select eid,ename,age,sex from emp where eid = ${eid} and ename = '${ename}'
3) 建议:大部分情况下使用 #{},在特殊情况下:①批量删除;②模糊查询,需要使用 ${}