MyBatis 的真正強大在於它的映射語句,也是它的魔力所在。因爲它的異常強大,映射器的 XML 文件就顯得相對簡單。若是拿它跟具備相同功能的 JDBC 代碼進行對比,你會當即發現省掉了將近 95% 的代碼。MyBatis 就是針對 SQL 構建的,而且比普通的方法作的更好。java
學習 MyBatis,須要瞭解 其如何對參數進行處理、如何將返回值進行映射。mysql
使用一個簡單的增刪改查小案例,快速明白 mybatis 映射文件使用的流程。sql
step1:文件結構數據庫
step2:完整代碼apache
【主要文件】 config/db.properties 用於設置數據庫的配置信息 config/EmpMapper.xml sql映射文件,用於編寫sql語句 config/mybatis-config.xml 全局配置文件 entity.Employee 實體類 mapper.EmpMapper 接口類,用於定義sql方法 test.Demo 測試類,用於測試增刪改查 【config/db.properties 】 jdbc.driver = com.mysql.cj.jdbc.Driver jdbc.url = jdbc:mysql://localhost:3306/lyh?useUnicode=true&characterEncoding=utf8 jdbc.username = root jdbc.password = 123456 【config/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="config/db.properties"></properties> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <!-- MyBatis自帶鏈接池,只需配置數據庫鏈接的一些數據便可 此處以MySql爲例。 --> <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> </environments> <!-- 加載SQL定義文件,須要修改 如有多個SQL定義文件,可使用<mapper />標籤追加。 文件路徑中存在.的話,使用/分割 --> <mappers> <mapper resource="config/EmpMapper.xml"/> </mappers> </configuration> 【entity.Employee】 package entity; import java.io.Serializable; /** * 實體類 */ public class Employee implements Serializable { private Integer id; private String name; private Double salary; private Integer age; public Employee() { } public Employee(Integer id, String name, Double salary, Integer age) { this.id = id; this.name = name; this.salary = salary; this.age = age; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Employee{" + "id=" + id + ", name='" + name + '\'' + ", salary=" + salary + ", age=" + age + '}'; } } 【mapper.EmpMapper】 package mapper; import entity.Employee; import org.apache.ibatis.annotations.Select; /** * 接口式編程,定義一系列方法,並根據方法映射到sql 的xml 文件中。 * 其中,返回值類型能夠是 Integer、Long、Boolean、void 、實體類 */ public interface EmpMapper { public Employee getEmpById(Integer id); public Long addEmp(Employee emp); public Boolean updateEmp(Employee emp); public Integer deleteEmpById(Integer id); } 【config/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="mapper.EmpMapper"> <insert id="addEmp"> INSERT INTO emp(emp.name, emp.salary, emp.age) VALUES (#{name}, #{salary}, #{age}) </insert> <delete id="deleteEmpById"> DELETE FROM emp WHERE emp.id = #{id} </delete> <update id="updateEmp"> UPDATE emp SET emp.salary = #{salary}, emp.age = #{age}, emp.name = #{name} WHERE emp.id = #{id} </update> <select id="getEmpById" resultType="entity.Employee"> SELECT * FROM emp WHERE emp.id = #{id} </select> </mapper> 【test.Demo】 package test; import entity.Employee; import mapper.EmpMapper; 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 java.io.IOException; import java.io.InputStream; public class Demo { private static SqlSessionFactory getSqlSessionFactory() throws IOException { // step1:讀取配置文件 String resource = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // step2:建立一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; } @Test public void testAddEmp() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try{ EmpMapper empMapper = session.getMapper(EmpMapper.class); Long result = empMapper.addEmp(new Employee(null,"jarry", 4000.0, 33)); System.out.println(result); // 增刪改須要 commit session.commit(); }finally { // step4:關閉 SqlSession 實例 session.close(); } } @Test public void testDeleteEmpById() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try{ EmpMapper empMapper = session.getMapper(EmpMapper.class); Integer result = empMapper.deleteEmpById(5); System.out.println(result); // 增刪改須要 commit session.commit(); }finally { // step4:關閉 SqlSession 實例 session.close(); } } @Test public void testUpdateEmp() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try{ EmpMapper empMapper = session.getMapper(EmpMapper.class); Boolean result = empMapper.updateEmp(new Employee(1,"jarry", 4000.0, 33)); System.out.println(result); // 增刪改須要 commit session.commit(); }finally { // step4:關閉 SqlSession 實例 session.close(); } } @Test public void testGetEmpById() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try{ EmpMapper empMapper = session.getMapper(EmpMapper.class); Employee result = empMapper.getEmpById(1); System.out.println(result); // 增刪改須要 commit session.commit(); }finally { // step4:關閉 SqlSession 實例 session.close(); } } }
step3:測試截圖
(1)添加一條數據編程
(2)刪除一條數據session
(3)更新一條數據mybatis
(4)查詢一條數據app
須要使用 useGeneratedKeys(默認爲false) 與 keyProperty(指定主鍵)。
mybatis 內部 會調用 getGeneratedKeys 方法並進行封裝。ide
【對 測試 代碼進行修改】
@Test
public void testAddEmp() throws IOException {
// 獲取一個 SqlSessionFactory 的對象
SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory();
// 獲取一個 SqlSession 的實例
SqlSession session = sqlSessionFactory.openSession();
try{
EmpMapper empMapper = session.getMapper(EmpMapper.class);
Employee employee = new Employee(null,"tom", 4000.0, 33);
System.out.println(employee);
Long result = empMapper.addEmp(employee);
System.out.println(employee);
System.out.println(result);
// 增刪改須要 commit
session.commit();
}finally {
// step4:關閉 SqlSession 實例
session.close();
}
}
不會自動返回主鍵。
增長 useGeneratedKeys 與 keyProperty。
【對sql映射文件進行修改】 <insert id="addEmp" useGeneratedKeys="true" keyProperty="id"> INSERT INTO emp(emp.name, emp.salary, emp.age) VALUES (#{name}, #{salary}, #{age}) </insert>
會自動映射主鍵。
使用 selectKey 標籤來指定。
建立一個表(不使用auto_increment定義自增主鍵)。
將sql映射文件的 表名 換爲 emp2。進行增長數據操做。
<insert id="addEmp"> INSERT INTO emp2(emp2.id, emp2.name, emp2.salary, emp2.age) VALUES (#{id}, #{name}, #{salary}, #{age}) </insert>
主鍵不會自動映射。
使用 selectKey ,能夠指定 主鍵。 resultType 爲返回值類型。 order 爲 BEFORE|AFTER(決定何時執行)。
<insert id="addEmp"> <selectKey keyProperty="id" order="BEFORE" resultType="Integer"> SELECT max(id) + 10 FROM emp2 </selectKey> INSERT INTO emp2(emp2.id, emp2.name, emp2.salary, emp2.age) VALUES (#{id}, #{name}, #{salary}, #{age}) </insert>
自動映射主鍵。
對於單個參數,直接使用 #{變量名} 便可獲取。
【mapper.EmpMapper】 package mapper; import entity.Employee; import org.apache.ibatis.annotations.Select; /** * 接口式編程,定義一系列方法,並根據方法映射到sql 的xml 文件中。 * 其中,返回值類型能夠是 Integer、Long、Boolean、void 、實體類 */ public interface EmpMapper { public Employee getEmpById(Integer id); } 【config/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="mapper.EmpMapper"> <select id="getEmpById" resultType="entity.Employee"> SELECT * FROM emp WHERE emp.id = #{id} </select> </mapper> 【test.Demo】 package test; import entity.Employee; import mapper.EmpMapper; 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 java.io.IOException; import java.io.InputStream; public class Demo { private static SqlSessionFactory getSqlSessionFactory() throws IOException { // step1:讀取配置文件 String resource = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // step2:建立一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; } @Test public void testGetEmpById() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try{ EmpMapper empMapper = session.getMapper(EmpMapper.class); Employee result = empMapper.getEmpById(1); System.out.println(result); // 增刪改須要 commit session.commit(); }finally { // step4:關閉 SqlSession 實例 session.close(); } } }
對於多個參數,直接使用 #{變量名} 會拋出異常(可以使用@param與之配合)。其內部會將其封裝爲一個map集合。
【mapper.EmpMapper】 package mapper; import entity.Employee; import org.apache.ibatis.annotations.Select; /** * 接口式編程,定義一系列方法,並根據方法映射到sql 的xml 文件中。 * 其中,返回值類型能夠是 Integer、Long、Boolean、void 、實體類 */ public interface EmpMapper { public Employee getEmpByIdAndName(Integer id, String name); } 【config/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="mapper.EmpMapper"> <select id="getEmpByIdAndName" resultType="entity.Employee"> SELECT * FROM emp WHERE emp.id = #{id} AND emp.name = #{name} </select> </mapper> 【test.Demo】 package test; import entity.Employee; import mapper.EmpMapper; 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 java.io.IOException; import java.io.InputStream; public class Demo { private static SqlSessionFactory getSqlSessionFactory() throws IOException { // step1:讀取配置文件 String resource = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // step2:建立一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; } @Test public void testGetEmpByIdAndName() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try{ EmpMapper empMapper = session.getMapper(EmpMapper.class); Employee result = empMapper.getEmpByIdAndName(1, "jack"); System.out.println(result); // 增刪改須要 commit session.commit(); }finally { // step4:關閉 SqlSession 實例 session.close(); } } }
參數名不對。修改以下
【config/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="mapper.EmpMapper"> <select id="getEmpByIdAndName" resultType="entity.Employee"> SELECT * FROM emp WHERE emp.id = #{param1} AND emp.name = #{param2} </select> </mapper>
若想使用 #{id} 等來獲取參數, 可使用 @param 註解並自定義名。
【mapper.EmpMapper.java】 package mapper; import entity.Employee; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; /** * 接口式編程,定義一系列方法,並根據方法映射到sql 的xml 文件中。 * 其中,返回值類型能夠是 Integer、Long、Boolean、void 、實體類 */ public interface EmpMapper { public Employee getEmpByIdAndName(@Param("id") Integer id, @Param("name") String name); } 【config/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="mapper.EmpMapper"> <select id="getEmpByIdAndName" resultType="entity.Employee"> SELECT * FROM emp WHERE emp.id = #{id} AND emp.name = #{name} </select> </mapper>
對於參數過多的時候,在方法參數中一個個定義明顯不可取。
此時能夠傳遞一個 自定義類 或者 一個map 集合。
【mapper.EmpMapper】 package mapper; import entity.Employee; import org.apache.ibatis.annotations.Param; import java.util.Map; /** * 接口式編程,定義一系列方法,並根據方法映射到sql 的xml 文件中。 * 其中,返回值類型能夠是 Integer、Long、Boolean、void 、實體類 */ public interface EmpMapper { public Employee getEmpByMap(Map<String, Object> map); } 【config/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="mapper.EmpMapper"> <select id="getEmpByMap" resultType="entity.Employee"> SELECT * FROM emp WHERE emp.id = #{id} AND emp.name = #{name} </select> </mapper> 【test.Demo】 package test; import entity.Employee; import mapper.EmpMapper; 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 java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; public class Demo { private static SqlSessionFactory getSqlSessionFactory() throws IOException { // step1:讀取配置文件 String resource = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // step2:建立一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; } @Test public void testGetEmpByMap() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try{ EmpMapper empMapper = session.getMapper(EmpMapper.class); Map<String, Object> map = new HashMap<>(); map.put("id", 1); map.put("name", "jack"); Employee result = empMapper.getEmpByMap(map); System.out.println(result); // 增刪改須要 commit session.commit(); }finally { // step4:關閉 SqlSession 實例 session.close(); } } }
可使用 #{list[0]} 或者 #{collection[0]} 等格式來·獲取參數。
【mapper.EmpMapper】 package mapper; import entity.Employee; import org.apache.ibatis.annotations.Param; import java.util.List; import java.util.Map; /** * 接口式編程,定義一系列方法,並根據方法映射到sql 的xml 文件中。 * 其中,返回值類型能夠是 Integer、Long、Boolean、void 、實體類 */ public interface EmpMapper { public Employee getEmpByList(List<Integer> list); } 【config/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="mapper.EmpMapper"> <select id="getEmpByList" resultType="entity.Employee"> SELECT * FROM emp WHERE emp.id = #{collection[0]} </select> </mapper> 【test.Demo】 package test; import entity.Employee; import mapper.EmpMapper; 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 java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; public class Demo { private static SqlSessionFactory getSqlSessionFactory() throws IOException { // step1:讀取配置文件 String resource = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // step2:建立一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; } @Test public void testGetEmpByList() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try{ EmpMapper empMapper = session.getMapper(EmpMapper.class); List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); Employee result = empMapper.getEmpByList(list); System.out.println(result); // 增刪改須要 commit session.commit(); }finally { // step4:關閉 SqlSession 實例 session.close(); } } }
【或者config/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="mapper.EmpMapper"> <select id="getEmpByList" resultType="entity.Employee"> SELECT * FROM emp WHERE emp.id = #{list[0]} </select> </mapper>
使用 #{} 或者 ${} 均可以獲取 參數的值。
可是 #{} 是以預編譯的方式, 將參數設置到 sql 語句中。 相似於 PreparedStatement。
${} 是直接將值放在sql 語句中。相似於 Statement。
<select> 標籤訂義查詢操做,
其中 id 惟一標識 sql(與接口的方法同名)。
resultType 爲返回值類型。若返回的爲List集合,則返回的爲泛型而非 list。好比 List<Employee> ,則 resultType =「Employee」, 而非 resultType =「list」。
【mapper.EmpMapper】 package mapper; import entity.Employee; import java.util.List; /** * 接口式編程,定義一系列方法,並根據方法映射到sql 的xml 文件中。 * 其中,返回值類型能夠是 Integer、Long、Boolean、void 、實體類 */ public interface EmpMapper { public List<Employee> getAllEmp(); } 【config/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="mapper.EmpMapper"> <select id="getAllEmp" resultType="entity.Employee"> SELECT * FROM emp </select> </mapper> 【test.Demo】 package test; import entity.Employee; import mapper.EmpMapper; 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 java.io.IOException; import java.io.InputStream; import java.util.List; public class Demo { private static SqlSessionFactory getSqlSessionFactory() throws IOException { // step1:讀取配置文件 String resource = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // step2:建立一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; } @Test public void testGetEmpById() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try{ EmpMapper empMapper = session.getMapper(EmpMapper.class); List<Employee> result = empMapper.getAllEmp(); for(Employee emp : result){ System.out.println(emp); } }finally { // step4:關閉 SqlSession 實例 session.close(); } } }
若將一條數據返回爲 map, 則 resultType = 「map」。
若將多條數據返回爲 map, 則 resultType = 「value的類型」(須要使用@MapKey 指定key)。
【mapper.EmpMapper】 package mapper; import entity.Employee; import org.apache.ibatis.annotations.MapKey; import java.util.Map; /** * 接口式編程,定義一系列方法,並根據方法映射到sql 的xml 文件中。 * 其中,返回值類型能夠是 Integer、Long、Boolean、void 、實體類 */ public interface EmpMapper { // 封裝多條數據,且每一個主鍵做爲key,每條數據爲 value @MapKey("id") public Map<Integer, Employee> getAllMap(); // 封裝一條數據,且每一個字段名做爲key,值爲 value。 public Map<String, Object> getEmpMap(Integer id); } 【config/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="mapper.EmpMapper"> <select id="getAllMap" resultType="entity.Employee"> SELECT * FROM emp </select> <select id="getEmpMap" resultType="map"> SELECT * FROM emp WHERE id = #{id} </select> </mapper> 【test.Demo】 package test; import entity.Employee; import mapper.EmpMapper; 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 java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; public class Demo { private static SqlSessionFactory getSqlSessionFactory() throws IOException { // step1:讀取配置文件 String resource = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // step2:建立一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; } @Test public void testGetAllMap() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try { EmpMapper empMapper = session.getMapper(EmpMapper.class); Map<Integer, Employee> result = empMapper.getAllMap(); System.out.println(result); } finally { // step4:關閉 SqlSession 實例 session.close(); } } @Test public void testGetEmpMap() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try { EmpMapper empMapper = session.getMapper(EmpMapper.class); Map<String, Object> result = empMapper.getEmpMap(1); System.out.println(result); } finally { // step4:關閉 SqlSession 實例 session.close(); } } }
使用resultMap 能夠自定義結果集映射規則。使用 resultMap 與 resultType 時只能二選一。
好比:將 emp 的name 字段 修改成 last_name(可是實體類不作修改)。
【mapper.EmpMapper】 package mapper; import entity.Employee; import java.util.Map; /** * 接口式編程,定義一系列方法,並根據方法映射到sql 的xml 文件中。 * 其中,返回值類型能夠是 Integer、Long、Boolean、void 、實體類 */ public interface EmpMapper { public Employee getEmpById(Integer id); } 【config/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="mapper.EmpMapper"> <select id="getEmpById" resultType="entity.Employee"> SELECT * FROM emp WHERE id = #{id} </select> </mapper> 【entity.Employee】 package entity; import java.io.Serializable; /** * 實體類 */ public class Employee implements Serializable { private Integer id; private String name; private Double salary; private Integer age; public Employee() { } public Employee(Integer id, String name, Double salary, Integer age) { this.id = id; this.name = name; this.salary = salary; this.age = age; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Employee{" + "id=" + id + ", name='" + name + '\'' + ", salary=" + salary + ", age=" + age + '}'; } } 【test.Demo】 package test; import entity.Employee; import mapper.EmpMapper; 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 java.io.IOException; import java.io.InputStream; public class Demo { private static SqlSessionFactory getSqlSessionFactory() throws IOException { // step1:讀取配置文件 String resource = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // step2:建立一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; } @Test public void testGetEmpByIdAndName() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try { EmpMapper empMapper = session.getMapper(EmpMapper.class); Employee result = empMapper.getEmpById(1); System.out.println(result); } finally { // step4:關閉 SqlSession 實例 session.close(); } } }
使用 resultType 映射確定會出現問題。
使用 resultMap 自定義映射規則, 將 last_name 映射到 name。
【config/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="mapper.EmpMapper"> <!-- 使用resultMap 定義一個自定義一個封裝規則。 id 用於惟一標識該規則。 type 用於指定返回值類型 --> <resultMap id="myEmp" type="entity.Employee"> <!-- 使用 id 標籤 用於指定主鍵,column 用於指定列,property 用於指定映射後的屬性名 --> <id column="id" property="id"></id> <!-- result 用於指定 普通列 --> <result column="last_name" property="name"></result> </resultMap> <select id="getEmpById" resultMap="myEmp"> SELECT * FROM emp WHERE id = #{id} </select> </mapper>
增長一個 department 表,並將其主鍵做爲 emp 表的外鍵。
CREATE TABLE department(
deptId INT(11) PRIMARY KEY AUTO_INCREMENT,
deptName VARCHAR(255)
);
ALTER TABLE emp ADD COLUMN deptId INT(11);
ALTER TABLE emp ADD CONSTRAINT fk_emp_department
FOREIGN KEY(deptId) REFERENCES department(deptId)
使用 resultMap 將 查詢的結果集 映射到 最終顯示的結果集上。即(column -》 property)。
可使用級聯屬性賦值。格式:A.B
【mapper.EmpMapper】 package mapper; import entity.Employee; /** * 接口式編程,定義一系列方法,並根據方法映射到sql 的xml 文件中。 * 其中,返回值類型能夠是 Integer、Long、Boolean、void 、實體類 */ public interface EmpMapper { public Employee getEmpAndDeptById(Integer id); } 【config/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="mapper.EmpMapper"> <resultMap id="myMap" type="entity.Employee"> <id column="e_id" property="id"></id> <result column="e_name" property="name"></result> <result column="e_salary" property="salary"></result> <result column="e_age" property="age"></result> <result column="d_id" property="department.deptId"></result> <result column="d_name" property="department.deptName"></result> </resultMap> <select id="getEmpAndDeptById" resultMap="myMap"> SELECT e.id e_id, e.last_name e_name, e.age e_age, e.salary e_salary, d.deptId d_id, d.deptName d_name FROM emp e, department d WHERE e.deptId = d.deptId AND e.id = #{id} </select> </mapper> 【entity.Employee.java】 package entity; import java.io.Serializable; /** * 實體類 */ public class Employee implements Serializable { private Integer id; private String name; private Double salary; private Integer age; private Department department; public Employee() { } public Employee(Integer id, String name, Double salary, Integer age) { this.id = id; this.name = name; this.salary = salary; this.age = age; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } @Override public String toString() { return "Employee{" + "id=" + id + ", name='" + name + '\'' + ", salary=" + salary + ", age=" + age + ", department=" + department + '}'; } } 【entity.Department.java】 package entity; public class Department { private Integer deptId; private String deptName; public Integer getDeptId() { return deptId; } public void setDeptId(Integer deptId) { this.deptId = deptId; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } @Override public String toString() { return "Department{" + "deptId=" + deptId + ", deptName='" + deptName + '\'' + '}'; } } 【test.Demo】 package test; import entity.Employee; import mapper.EmpMapper; 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 java.io.IOException; import java.io.InputStream; public class Demo { private static SqlSessionFactory getSqlSessionFactory() throws IOException { // step1:讀取配置文件 String resource = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // step2:建立一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; } @Test public void testGetEmpByIdAndName() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try { EmpMapper empMapper = session.getMapper(EmpMapper.class); Employee result = empMapper.getEmpAndDeptById(1); System.out.println(result); } finally { // step4:關閉 SqlSession 實例 session.close(); } } }
除了級聯屬性賦值,可使用 association 標籤對關聯的對象賦值。
對上例級聯屬性賦值代碼進行修改。
【config/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="mapper.EmpMapper"> <resultMap id="myMap" type="entity.Employee"> <id column="e_id" property="id"></id> <result column="e_name" property="name"></result> <result column="e_salary" property="salary"></result> <result column="e_age" property="age"></result> <!-- property 用於指定 映射的屬性 JavaType 用於指定 映射的類型 --> <association property="department" javaType="entity.Department"> <result column="d_id" property="deptId"></result> <result column="d_name" property="deptName"></result> </association> </resultMap> <select id="getEmpAndDeptById" resultMap="myMap"> SELECT e.id e_id, e.last_name e_name, e.age e_age, e.salary e_salary, d.deptId d_id, d.deptName d_name FROM emp e, department d WHERE e.deptId = d.deptId AND e.id = #{id} </select> </mapper>
接着對上例進行修改。
使用 association 的 select 屬性,能夠調用 另外的sql 語句, 從而實現分步查詢的操做。
【config/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="mapper.EmpMapper"> <resultMap id="myMap" type="entity.Employee"> <id column="id" property="id"></id> <result column="last_name" property="name"></result> <result column="salary" property="salary"></result> <result column="age" property="age"></result> <association property="department" select="getDeptById" column="deptId"> </association> </resultMap> <select id="getEmpAndDeptById" resultMap="myMap"> SELECT * FROM emp WHERE id = #{id} </select> <select id="getDeptById" resultType="entity.Department"> SELECT * FROM department WHERE deptId = #{deptId} </select> </mapper>
好比映射的對象是個 list 集合。
使用 collection 標籤訂義集合類型的封裝規則。其屬性 ofType 爲集合的泛型,property 爲映射的屬性名。
【entity.Department】 package entity; import java.util.List; public class Department { private Integer deptId; private String deptName; private List<Employee> employeeList; public Integer getDeptId() { return deptId; } public void setDeptId(Integer deptId) { this.deptId = deptId; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } public List<Employee> getEmployeeList() { return employeeList; } public void setEmployeeList(List<Employee> employeeList) { this.employeeList = employeeList; } @Override public String toString() { return "Department{" + "deptId=" + deptId + ", deptName='" + deptName + '\'' + ", employeeList=" + employeeList + '}'; } } 【mapper.EmpMapper.java】 package mapper; import entity.Department; /** * 接口式編程,定義一系列方法,並根據方法映射到sql 的xml 文件中。 * 其中,返回值類型能夠是 Integer、Long、Boolean、void 、實體類 */ public interface EmpMapper { public Department getDeptById(Integer id); } 【config/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="mapper.EmpMapper"> <resultMap id="myMap" type="entity.Department"> <id column="deptId" property="deptId"></id> <result column="deptName" property="deptName"></result> <!-- collection 標籤用於定義集合類型的封裝規則。 ofType 爲集合的泛型 property 爲映射的屬性名 --> <collection property="employeeList" ofType="entity.Employee"> <id column="e_id" property="id"></id> <result column="e_name" property="name"></result> <result column="e_salary" property="salary"></result> <result column="e_age" property="age"></result> </collection> </resultMap> <select id="getDeptById" resultMap="myMap"> SELECT d.deptId deptId, d.deptName deptName, e.id e_id, e.last_name e_name, e.age e_age, e.salary e_salary FROM department d LEFT JOIN emp e ON e.deptId = d.deptId WHERE d.deptId = #{id} </select> </mapper> 【test.Demo】 package test; import entity.Department; import entity.Employee; import mapper.EmpMapper; 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 java.io.IOException; import java.io.InputStream; public class Demo { private static SqlSessionFactory getSqlSessionFactory() throws IOException { // step1:讀取配置文件 String resource = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // step2:建立一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; } @Test public void testGetDeptById() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try { EmpMapper empMapper = session.getMapper(EmpMapper.class); Department result = empMapper.getDeptById(1); System.out.println(result); for(Employee employee : result.getEmployeeList()){ System.out.println(employee); } } finally { // step4:關閉 SqlSession 實例 session.close(); } } }
對上例代碼稍做修改。便可實現分步查詢。
【config/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="mapper.EmpMapper"> <resultMap id="myMap" type="entity.Department"> <id column="deptId" property="deptId"></id> <result column="deptName" property="deptName"></result> <collection property="employeeList" select="getEmpByDeptId" column="deptId"> <id column="e_id" property="id"></id> <result column="e_name" property="name"></result> <result column="e_salary" property="salary"></result> <result column="e_age" property="age"></result> </collection> </resultMap> <select id="getDeptById" resultMap="myMap"> SELECT * FROM department WHERE deptId = #{id} </select> <select id="getEmpByDeptId" resultType="entity.Employee"> SELECT * FROM emp WHERE deptId = #{deptId} </select> </mapper>
注:
對於 collection 與 association的分步查詢操做。
【若想傳遞多個參數,格式爲:】
column="{key1 = value1, key2 = value2}"
【使用時格式】
#{key1} 或者 #{key2}
使用鑑別器 discriminator, 能夠監控某個列的值,並根據不一樣的值執行不一樣的行爲。
以下例:對於 deptId =1 的數據,將部門名改成 1。對於 deptId =2 的數據,部門名不變。
【mapper.EmpMapper】 package mapper; import entity.Department; import java.util.List; /** * 接口式編程,定義一系列方法,並根據方法映射到sql 的xml 文件中。 * 其中,返回值類型能夠是 Integer、Long、Boolean、void 、實體類 */ public interface EmpMapper { public List<Department> getDeptById(Integer id); } 【config/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="mapper.EmpMapper"> <resultMap id="myMap" type="entity.Department"> <!-- discriminator 標籤爲鑑別器,能夠根據某列的值執行不一樣的行爲 javaType 指定某列的值的類型 column 用於指定某列 --> <discriminator javaType="Integer" column="deptId"> <case value="1" resultType="entity.Department"> <id column="deptId" property="deptId"></id> <id column="deptId" property="deptName"></id> </case> <case value="2" resultType="entity.Department"> <id column="deptId" property="deptId"></id> <result column="deptName" property="deptName"></result> </case> </discriminator> </resultMap> <select id="getDeptById" resultMap="myMap"> SELECT * FROM department </select> </mapper> 【test.Demo】 package test; import entity.Department; import entity.Employee; import mapper.EmpMapper; 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 java.io.IOException; import java.io.InputStream; import java.util.List; public class Demo { private static SqlSessionFactory getSqlSessionFactory() throws IOException { // step1:讀取配置文件 String resource = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // step2:建立一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; } @Test public void testGetDeptById() throws IOException { // 獲取一個 SqlSessionFactory 的對象 SqlSessionFactory sqlSessionFactory = Demo.getSqlSessionFactory(); // 獲取一個 SqlSession 的實例 SqlSession session = sqlSessionFactory.openSession(); try { EmpMapper empMapper = session.getMapper(EmpMapper.class); List<Department> result = empMapper.getDeptById(1); System.out.println(result); } finally { // step4:關閉 SqlSession 實例 session.close(); } } }