Mybatis-詳解3

14、動態SQL語句

15、mybatis緩存

16、緩存的使用順序說明

17mybatis 逆向工程


14、動態SQL語句

實體類:


public class User {
	private int id;
	private String lastName;
	private int sex;

14.1if 語句

說明: if語句,可以動態的根據你的值來決定,是否需要動態的添加查詢條件。

 

代碼:

public List<User> queryUsersByNameAndSex(String name, int sex);

配置:

<!-- 	public List<User> queryUsersByNameAndSex(String name, int sex);	 -->
	<select id="queryUsersByNameAndSex" resultType="com.tcent.pojo.User">
		select id,last_name lastName,sex from t_user 
		where 
		<if test="param1 != null">
			last_name like concat('%',#{param1},'%')
		</if>
		<if test="param2 == 1 || param2 == 0">
		 	and sex = #{param2}
		</if>
	</select>

測試:

@Test
	public void testQueryUsersByNameAndSex() throws Exception {
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(Resources.getResourceAsStream("mybatis-config.xml"));

		SqlSession session = sqlSessionFactory.openSession();
		try {
			UserMapper userMapper = session.getMapper(UserMapper.class);
			// name的值,如果等於null ,這個時候會出現問題。
			// sex 性別 。1是男,0是女	如果出現0或1之外的值。也是非法值。
			System.out.println( userMapper.queryUsersByNameAndSex("bbb", 10) );
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();
		}
	}

14.2where 語句

說明: where語句,可以幫我們在多個動態語句中,有效的去掉前面的多餘的and  or 之類的多餘關鍵字

where標籤,還只可以動態的判斷中間是否包含查詢條件。如果沒有連where關鍵字也不會出現。

<select id="queryUsersByNameAndSex" resultType="com.tcent.pojo.User">
		select id,last_name lastName,sex from t_user 
		<where>
			<if test="param1 != null">
				last_name like concat('%',#{param1},'%')
			</if>
			<if test="param2 == 1 || param2 == 0">
			 	and sex = #{param2}
			</if>
		</where> 
	</select>

14.3trim語句

說明:trim 可以動態在包含的語句前面和後面添加內容。也可以去掉前面或者後面給定的內容

  • prefix 前面添加內容
  • suffix 後面添加內容
  • suffixOverrides 去掉的後面內容
  • prefixOverrides 去掉的前面內容
<select id="queryUsersByNameAndSexTrim" resultType="com.tcent.pojo.User">
		select id,last_name lastName,sex from t_user 
		<where>
			<!-- 
				prefix 前面添加內容
				suffix 後面添加內容
				suffixOverrides 去掉的後面內容
				prefixOverrides 去掉的前面內容
			 -->
			<trim prefixOverrides="and" suffixOverrides="and">
				<if test="param1 != null">
					last_name like concat('%',#{param1},'%') and
				</if>
				<if test="param2 == 1 || param2 == 0">
				 	sex = #{param2}
				</if>
			</trim>
		</where> 
	</select>

14.4choosewhen , otherwise )語句

說明:choose when otherwise 可以執行多路選擇判斷,但是隻會有一個分支會被執行。

類似switch case 語句

方法代碼:

public List<User> queryUsersByNameAndSexChoose(String name, int sex);

xml中的配置:

<select id="queryUsersByNameAndSexChoose" resultType="com.tcent.pojo.User">
		select id,last_name lastName,sex from t_user 
		<where>	
			<!-- 我們希望,如果name的值非空,只查詢name
				如果name的值非法,而sex的值合法。只查詢sex
				如果兩個都不合法,都不要(或者你可以自己加一些查詢條件)
			 -->
			 <choose>
			 	<when test="param1 != null">
			 		last_name like concat('%',#{param1},'%')
			 	</when>
			 	<when test="param2 == 1 || param2 == 0">
			 		sex = #{param2}
			 	</when>
			 	<otherwise>
			 		sex = 0
			 	</otherwise>
			 </choose>
		</where> 
	</select>

測試代碼:

@Test
	public void testQueryUsersByNameAndSexChoose() throws Exception {
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
		.build(Resources.getResourceAsStream("mybatis-config.xml"));
		
		SqlSession session = sqlSessionFactory.openSession();
		try {
			UserMapper userMapper = session.getMapper(UserMapper.class);
			// name的值,如果等於null ,這個時候會出現問題。
			// sex 性別 。1是男,0是女	如果出現0或1之外的值。也是非法值。
			System.out.println( userMapper.queryUsersByNameAndSexChoose(null, 1) );
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();
		}
	}

14.4set語句

刪除條件後的逗號

 

代碼:

public int updateUser(User user);

xml中的配置:

<update id="updateUser" parameterType="com.tcent.pojo.User">
		update t_user 
		<set>
			last_name = #{lastName} ,
			<!-- 我們希望可以動態的判斷,如果sex非法,不更新sex的值。 -->
			<if test="sex == 1 || sex == 0">
				sex = #{sex}
			</if> 
		</set> 
		where id = #{id}
	</update>

測試的代碼:

@Test
	public void testUpdateUser() throws Exception {
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
		.build(Resources.getResourceAsStream("mybatis-config.xml"));
		
		SqlSession session = sqlSessionFactory.openSession();
		try {
			UserMapper userMapper = session.getMapper(UserMapper.class);
			// name的值,如果等於null ,這個時候會出現問題。
			// sex 性別 。1是男,0是女	如果出現0或1之外的值。也是非法值。
			userMapper.updateUser(new User(5, "bbb", 10));
session.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();
		}
	}

14.5foreach語句

 

代碼:

	/**
	 * select * from t_user where id in(1,2,3,4,5)
	 */
	public List<User> queryUsersByIds(List<Integer> ids);

xml中的配置:

<!-- 	public List<User> queryUsersByIds(List<Integer> ids); -->
	<select id="queryUsersByIds" resultType="com.tcent.pojo.User">
		select id,last_name lastName,sex from t_user 
		<where>
			id in 
			<!-- 
				foreach標籤用來遍歷集合
					collection遍歷的數據源
					open屬性設置遍歷的開始內容
					close屬性設置遍歷的結束內容
					item屬性是當前遍歷到的數據
					separator屬性設置遍歷的每個元素之間的間隔符
			 -->
			<foreach collection="list" open="(" close=")" item="i" separator=",">
				#{i}
			</foreach>
		</where>
	</select>

測試代碼:

@Test
	public void testQueryUsersByIds() throws Exception {
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
		.build(Resources.getResourceAsStream("mybatis-config.xml"));
		
		SqlSession session = sqlSessionFactory.openSession();
		try {
			UserMapper userMapper = session.getMapper(UserMapper.class);
			List<Integer> ids = new ArrayList<Integer>();
			ids.add(1);
			ids.add(2);
			ids.add(5);
			ids.add(6);
			System.out.println( userMapper.queryUsersByIds( ids ) );
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();
		}
	}

15mybatis緩存

緩存:緩存指的是將經常訪問的數據保存到一個高速的數據存儲區。緩存的目的就是爲了快速訪問

一級緩存: 指的是將數據保存一SqlSession中(同一個SqlSession)

二級緩存: 指的是將數據保存一mapper中(同一個sqlSessionFactory)

 

準備一個UserMapper

public interface UserMapper {

	public User queryUserById(int id);

	public int updateUser(User user);
}

UserMapper.xml中的配置:

<mapper namespace="com.atguigu.dao.UserMapper">
<!-- 	public User queryUserById(int id); -->
	<select id="queryUserById" resultType="com.tcent.pojo.User">
		select id,last_name lastName,sex from t_user where id = #{id}
	</select>
	
<!-- 	public User updateUser(User user); -->
	<update id="updateUser" parameterType="com.tcent.pojo.User" >
		update t_user set last_name = #{lastName},sex = #{sex} where id = #{id}
	</update>
</mapper>

15.1mybatis的一級緩存的示例

@Test
	public void testQueryUserById() throws Exception {
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(Resources.getResourceAsStream("mybatis-config.xml"));
		SqlSession session = sqlSessionFactory.openSession();

		UserMapper mapper = session.getMapper(UserMapper.class);
		User user = mapper.queryUserById(1);
		System.out.println(user);
		user = mapper.queryUserById(1);
		System.out.println(user);
		session.close();
	}

15.1.2、一級緩存的管理

緩存失效的四種情況:

1.不在同一個SqlSession對象中

// 1.不在同一個SqlSession對象中
	@Test
	public void testQueryUserByIdFail1() throws Exception {
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(Resources.getResourceAsStream("mybatis-config.xml"));
		SqlSession session = sqlSessionFactory.openSession();
		UserMapper mapper = session.getMapper(UserMapper.class);
		User user = mapper.queryUserById(1);
		System.out.println(user);
		session.close();

		SqlSession session2 = sqlSessionFactory.openSession();
		UserMapper userMapper2 = session2.getMapper(UserMapper.class);
		User user2 = userMapper2.queryUserById(1);
		System.out.println(user2);
		session2.close();
	}

2.執行語句的參數不同。緩存中也不存在數據。

	// 2.執行語句的參數不同。緩存中也不存在數據。
	public void testQueryUserByIdFail2() throws Exception {
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(Resources.getResourceAsStream("mybatis-config.xml"));
		SqlSession session = sqlSessionFactory.openSession();

		UserMapper mapper = session.getMapper(UserMapper.class);
		User user = mapper.queryUserById(1);
		System.out.println(user);
		user = mapper.queryUserById(2);
		System.out.println(user);
		session.close();
	}

3.執行增,刪,改,語句,會清空掉緩存

@Test
	// 3.執行增,刪,改,語句,會清空掉緩存
	public void testQueryUserByIdFail3() throws Exception {
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(Resources.getResourceAsStream("mybatis-config.xml"));
		SqlSession session = sqlSessionFactory.openSession();

		UserMapper mapper = session.getMapper(UserMapper.class);
		User user = mapper.queryUserById(1);
		System.out.println(user);
		////////////////////////////////////////////
		mapper.updateUser(new User(5, "cccc", 1));
		session.commit();
		
		///////////////////////////////////////////
		user = mapper.queryUserById(1);
		System.out.println(user);
		session.close();
	}

4.手動清空緩存數據

@Test
	// 4.手動清空緩存數據
	public void testQueryUserByIdFail4() throws Exception {
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(Resources.getResourceAsStream("mybatis-config.xml"));
		SqlSession session = sqlSessionFactory.openSession();

		UserMapper mapper = session.getMapper(UserMapper.class);
		User user = mapper.queryUserById(1);
		System.out.println(user);
		session.clearCache();
		user = mapper.queryUserById(1);
		System.out.println(user);
		session.close();
	}

四種效果圖都一樣


15.2mybatis的二級緩存

 

二級緩存的圖解示


二級緩存的使用:

myBatis的二級緩存默認是不開啓的。我們需要在mybatis的核心配置文件中配置setting選項 和 在Mapper的配置文件中加入cache標籤。並且需要被二級緩存的對象必須要實現java的序列化接口。

 

二級緩存的使用步驟:

1、在mybatis-config.xml中配置選項

<settings>

<!-- 開啓二級緩存 -->

<setting name="cacheEnabled" value="true"/>

</settings>

2、在Mapper.xml中去添加一個cache<>cache</>空標籤即可

3、對象必須要實現java的序列化接口。implements Serializable


15.2.1、二級緩存的演示

@Test
	public void testCacheLevel2() throws IOException {
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(Resources.getResourceAsStream("mybatis-config.xml"));
		SqlSession session = sqlSessionFactory.openSession();
		UserMapper mapper = session.getMapper(UserMapper.class);
		User user = mapper.queryUserById(1);
		System.out.println(user);
		session.close();

		SqlSession session2 = sqlSessionFactory.openSession();
		UserMapper userMapper2 = session2.getMapper(UserMapper.class);
		User user2 = userMapper2.queryUserById(1);
		System.out.println(user2);
		session2.close();
	}


16、緩存的使用順序說明:


1、當我們執行一個查詢語句的時候。mybatis會先去二級緩存中查詢數據。如果二級緩存中沒有。就到一級緩存中查找。

2、如果二級緩存和一級緩存都沒有。就發sql語句到數據庫中去查詢。

3、查詢出來之後馬上把數據保存到一級緩存中。

4、當SqlSession關閉的時候,會把一級緩存中的數據保存到二級緩存中。

17mybatis 逆向工程

MyBatis逆向工程,簡稱MBG。是一個專門爲MyBatis框架使用者定製的代碼生成器。可以快速的根據表生成對應的映射文件,接口,以及Bean類對象。

Mybatis中,有一個可以自動對單表生成的增,刪,改,查代碼的插件。

 

mybatis-generator-core-1.3.2

 

它可以幫我們對比數據庫表之後,生成大量的這個基礎代碼。

這些基礎代碼有:

1、數據庫表對應的javaBean對象

2、這些javaBean對象對應的Mapper接口

3、這些Mapper接口對應的配置文件

	<!-- 去掉全部的註釋 -->
	<commentGenerator>
        <property name="suppressAllComments" value="true" />
    </commentGenerator>

創建一個Java工程


log4j-1.2.17.jar

mybatis-3.4.1.jar

mybatis-generator-core-1.3.2.jar

mysql-connector-java-5.1.7-bin.jar

生成代碼:

public class Runner {

	public static void main(String[] args) throws Exception {
		List<String> warnings = new ArrayList<String>();
		boolean overwrite = true;
		File configFile = new File("mbg.xml");
		ConfigurationParser cp = new ConfigurationParser(warnings);
		Configuration config = cp.parseConfiguration(configFile);
		DefaultShellCallback callback = new DefaultShellCallback(overwrite);
		MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
				callback, warnings);
		myBatisGenerator.generate(null);
	}

}

附一張mybatis的組成圖


四個jar包下載

 Mybatis-詳解2






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章