14、動態SQL語句
15、mybatis緩存
16、緩存的使用順序說明
17、mybatis 逆向工程
14、動態SQL語句
實體類:
public class User {
private int id;
private String lastName;
private int sex;
14.1、if 語句
說明: 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.2、where 語句
說明: 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.3、trim語句
說明: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.4、choose( when , 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.4、set語句
刪除條件後的逗號
代碼:
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.5、foreach語句
代碼:
/**
* 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();
}
}
15、mybatis緩存
緩存:緩存指的是將經常訪問的數據保存到一個高速的數據存儲區。緩存的目的就是爲了快速訪問
一級緩存: 指的是將數據保存一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.1、mybatis的一級緩存的示例
@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.2、mybatis的二級緩存
二級緩存的圖解示
二級緩存的使用:
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關閉的時候,會把一級緩存中的數據保存到二級緩存中。
17、mybatis 逆向工程
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的組成圖