1. MyBatis對映器
2. MyBatis資料基本操作
示例專案結構:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>libing</groupId> <artifactId>com-helloworld-api</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>com-helloworld-api Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.43</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.0-b07</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>com-helloworld-api</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.6.2</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
<?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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/helloworld?characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="root" /> </dataSource> </environment> </environments> <mappers> <mapper resource="mappers/RoleMapper.xml" /> </mappers> </configuration>
package com.libing.helloworld.model; public class Role { private Integer id; private String roleName; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } }
<?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.libing.helloworld.dao.IRoleDao"> <resultMap id="baseResultMap" type="com.libing.helloworld.model.Role"> <id property="id" column="id" /> <result property="roleName" column="role_name" /> </resultMap> <select id="findAll" resultMap="baseResultMap"> SELECT id, role_name FROM role ORDER BY id ASC </select> <select id="findBySearchText" resultMap="baseResultMap"> SELECT id, role_name FROM role WHERE role_name LIKE CONCAT(CONCAT('%',#{searchText,jdbcType=VARCHAR}),'%') ORDER BY id ASC </select> <select id="findById" resultMap="baseResultMap"> SELECT id, role_name FROM role WHERE id = #{id} </select> <insert id="insert" useGeneratedKeys="true" keyProperty="id" parameterType="com.libing.helloworld.model.Role"> INSERT role ( role_name ) VALUES ( #{roleName} ) </insert> <update id="update" parameterType="com.libing.helloworld.model.Role"> UPDATE role SET role_name=#{roleName} WHERE id = #{id} </update> <delete id="deleteById"> DELETE FROM role WHERE id = #{id} </delete> <delete id="deleteByIds" parameterType="java.util.List"> DELETE FROM role WHERE id IN <foreach collection="list" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </delete> </mapper>
package com.libing.helloworld.test; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.libing.helloworld.dao.IRoleDao; import com.libing.helloworld.model.Role; public class RoleTest { SqlSession sqlSession = null; @Before public void init() { String resource = "mybatis-config.xml"; InputStream inputStream = RoleTest.class.getClassLoader().getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); sqlSession = sqlSessionFactory.openSession(); } @Test public void findAll() { try { IRoleDao roleDao = sqlSession.getMapper(IRoleDao.class); List<Role> roles = roleDao.findAll(); Assert.assertNotNull(roles); Assert.assertTrue(roles.size() > 0); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.close(); } } @Test public void findById() { try { IRoleDao roleDao = sqlSession.getMapper(IRoleDao.class); Role role = roleDao.findById(1); Assert.assertNotNull(role); Assert.assertNotNull(role.getRoleName()); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.close(); } } @Test public void insert() { try { IRoleDao roleDao = sqlSession.getMapper(IRoleDao.class); Role role = new Role(); role.setRoleName("測試"); int result = roleDao.insert(role); // 只插入一條記錄 Assert.assertEquals(1, result); // id不為null Assert.assertNotNull(role.getId()); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.rollback(); sqlSession.close(); } } public void Update() { try { IRoleDao roleDao = sqlSession.getMapper(IRoleDao.class); Role role = roleDao.findById(1); Assert.assertNotNull(role); role.setRoleName("測試"); int result = roleDao.update(role); // 只修改一條記錄 Assert.assertEquals(1, result); // 修改後的值 Assert.assertEquals("測試", roleDao.findById(1).getRoleName()); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.rollback(); sqlSession.close(); } } @Test public void deleteById() { try { IRoleDao roleDao = sqlSession.getMapper(IRoleDao.class); Assert.assertNotNull(roleDao.findById(1)); // 呼叫刪除方法 Assert.assertEquals(1, roleDao.deleteById(1)); // 再次查詢,判斷是否為null Assert.assertNull(roleDao.findById(1)); } catch (Exception e) { e.printStackTrace(); } finally { // 由於sqlSessionFactory.openSession()是不自動提交的,不手動執行sqlSession.commit()不會提交到資料庫 sqlSession.rollback(); sqlSession.close(); } } @Test public void deleteByIds() { try { List<Integer> ids = new ArrayList<Integer>(); ids.add(1); ids.add(2); IRoleDao roleDao = sqlSession.getMapper(IRoleDao.class); int result = roleDao.deleteByIds(ids); Assert.assertTrue(result > 0); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.rollback(); sqlSession.close(); } } }
package com.libing.helloworld.dao; import java.util.List; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Options; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.SelectKey; import org.apache.ibatis.annotations.Update; import com.libing.helloworld.model.Role; public interface IRoleDao { @Select("SELECT id,role_name FROM role") @Results( value = { @Result(id = true, property = "id", column = "id"), @Result(property="roleName", column="role_name") }) List<Role> findAll(); @Select("SELECT id,role_name FROM role WHERE role_name LIKE CONCAT(CONCAT('%',#{searchText}),'%')") @Results( value = { @Result(id = true, property = "id", column = "id"), @Result(property="roleName", column="role_name") }) List<Role> findBySearchText(@Param("searchText") String searchText); @Select("SELECT id,role_name FROM role WHERE id = #{id}") @Results( value = { @Result(id = true, property = "id", column = "id"), @Result(property="roleName", column="role_name") }) Role findById(Integer id); @Insert({ "INSERT INTO role(id,role_name)", " VALUES ", "(#{id}, #{roleName})" }) @Options(useGeneratedKeys = true, keyProperty = "id") @SelectKey(statement="select last_insert_id()", keyProperty = "id", before = false, resultType = int.class) int insert(Role role); @Update({ "UPDATE role SET ", "role_name = #{roleName} ", "WHERE id = #{id}" }) int update(Role role); @Delete("DELETE FROM role WHERE id = #{id}") int deleteById(Integer id); int deleteByIds(List<Integer> ids); }
2.1 select
基於XML方式:
<resultMap id="baseResultMap" type="com.libing.helloworld.model.Role"> <id property="id" column="id" /> <result property="roleName" column="role_name" /> </resultMap> <select id="findAll" resultMap="baseResultMap"> SELECT id, role_name FROM role ORDER BY id ASC </select>
基於註解方式:
@Select("SELECT id,role_name FROM role") @Results( value = { @Result(id = true, property = "id", column = "id"), @Result(property="roleName", column="role_name") }) List<Role> findAll();
單元測試:
@Test public void findAll() { try { IRoleDao roleDao = sqlSession.getMapper(IRoleDao.class); List<Role> roles = roleDao.findAll(); Assert.assertNotNull(roles); Assert.assertTrue(roles.size() > 0); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.close(); } }
XML中大於符號與小於符號轉義:
> >
< <
或使用 <![CDATA[ ]]>
<select id="findAll" resultMap="baseResultMap"> SELECT id, role_name FROM role WHERE id >= 10 ORDER BY id ASC </select>
<select id="findAll" resultMap="baseResultMap"> SELECT id, role_name FROM role WHERE id <![CDATA[>=]]> 10 ORDER BY id ASC </select>
Role findById(Integer id);
<select id="findById" resultMap="baseResultMap"> SELECT id, role_name FROM role WHERE id = #{id} </select>
@Test public void findById() { try { IRoleDao roleDao = sqlSession.getMapper(IRoleDao.class); Role role = roleDao.findById(1); Assert.assertNotNull(role); Assert.assertNotNull(role.getRoleName()); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.close(); } }
@Select("SELECT id,role_name FROM role WHERE id = #{id}") @Results( value = { @Result(id = true, property = "id", column = "id"), @Result(property="roleName", column="role_name") }) Role findById(Integer id);
傳遞多個引數:
1>. 使用Map傳遞引數
List<Role> findByMap(Map<String, String> params);
<select id="findByMap" parameterType="map" resultMap="baseResultMap"> SELECT id, role_name FROM role WHERE id != #{id} AND role_name = #{roleName} </select>
@Test public void findByMap() { try { Map<String, String> params = new HashMap<String, String>(); params.put("id", "1"); params.put("roleName", "管理員"); IRoleDao roleDao = sqlSession.getMapper(IRoleDao.class); List<Role> roles = roleDao.findByMap(params); Assert.assertNotNull(roles); Assert.assertTrue(roles.size() > 0); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.close(); } }
2>. 使用註解方式傳遞引數
import org.apache.ibatis.annotations.Param;
List<Role> findByAnnotation(@Param("id") Integer id, @Param("roleName") String roleName);
<select id="findByAnnotation" resultMap="baseResultMap"> SELECT id, role_name FROM role WHERE id != #{id} AND role_name = #{roleName} </select>
3>. 使用JavaBean傳遞引數
package com.libing.helloworld.params; public class RoleParam { private Integer id; private String roleName; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } }
List<Role> findByRoleParam(RoleParam params);
<select id="findByRoleParam" parameterType="com.libing.helloworld.params.RoleParam" resultMap="baseResultMap"> SELECT id, role_name FROM role WHERE id != #{id} AND role_name = #{roleName} </select>
傳遞多個引數總結:
◊ 使用Map方式:Map擴充套件和維護困難,在實際應用中廢棄這種傳遞引數方式。
◊ 使用@Param註解方式:引數個數<=5時是最佳的傳參方式。
◊ JavaBean方式:當引數個數大於5個時,建議使用JavaBean方式。
2.2 insert
MyBatis在執行Insert語句之後返回一個整數,表示插入的記錄數。
int insert(Role role);
<insert id="insert" useGeneratedKeys="true" keyProperty="id" parameterType="com.libing.helloworld.model.Role"> INSERT role ( role_name ) VALUES ( #{roleName} ) </insert>
其中,useGeneratedKeys:配置MyBatis使用JDBC的getGeneratedKeys()來獲取由資料庫內部生成的主鍵值,keyProperty:指定主鍵欄位。
@Test public void insert() { try { IRoleDao roleDao = sqlSession.getMapper(IRoleDao.class); Role role = new Role(); role.setRoleName("測試"); int result = roleDao.insert(role); // 只插入一條記錄 Assert.assertEquals(1, result); // id不為null Assert.assertNotNull(role.getId()); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.rollback(); sqlSession.close(); } }
@Insert({ "INSERT INTO role(id,role_name)", " VALUES ", "(#{id}, #{roleName})" }) @Options(useGeneratedKeys = true, keyProperty = "id") @SelectKey(statement="select last_insert_id()", keyProperty = "id", before = false, resultType = int.class) int insert(Role role);
2.3 update
MyBatis在執行update語句之後返回一個整數,表示更新的記錄數。
int update(Role role);
<update id="update" parameterType="com.libing.helloworld.model.Role"> UPDATE role SET role_name = #{roleName} WHERE id = #{id} </update>
@Test public void Update() { try { IRoleDao roleDao = sqlSession.getMapper(IRoleDao.class); Role role = roleDao.findById(1); Assert.assertNotNull(role); role.setRoleName("測試"); int result = roleDao.update(role); // 只修改一條記錄 Assert.assertEquals(1, result); // 修改後的值 Assert.assertEquals("測試", roleDao.findById(1).getRoleName()); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.rollback(); sqlSession.close(); } }
@Update({ "UPDATE role SET ", "role_name = #{roleName} ", "WHERE id = #{id}" }) int update(Role role);
2.4 delete
MyBatis在執行delete語句之後返回一個整數,表示刪除的記錄數。
int deleteById(Integer id);
<delete id="deleteById"> DELETE FROM role WHERE id = #{id} </delete>
@Test public void deleteById() { try { IRoleDao roleDao = sqlSession.getMapper(IRoleDao.class); Assert.assertNotNull(roleDao.findById(1)); // 呼叫刪除方法 Assert.assertEquals(1, roleDao.deleteById(1)); // 再次查詢,判斷是否為null Assert.assertNull(roleDao.findById(1)); } catch (Exception e) { e.printStackTrace(); } finally { // 由於sqlSessionFactory.openSession()是不自動提交的,不手動執行sqlSession.commit()不會提交到資料庫 sqlSession.rollback(); sqlSession.close(); } }
@Delete("DELETE FROM role WHERE id = #{id}") int deleteById(Integer id);
刪除多條記錄:
int deleteByIds(List<Integer> ids);
<delete id="deleteByIds" parameterType="java.util.List"> DELETE FROM role WHERE id IN <foreach collection="list" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </delete>
@Test public void deleteByIds() { try { List<Integer> ids = new ArrayList<Integer>(); ids.add(1); ids.add(2); IRoleDao roleDao = sqlSession.getMapper(IRoleDao.class); int result = roleDao.deleteByIds(ids); Assert.assertTrue(result > 0); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.rollback(); sqlSession.close(); } }