<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
資料庫:mysql5.7
jdk:15
<!--引入依賴--> <dependencies> <!--mybatis座標--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <!--mysql驅動座標--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> <scope>runtime</scope> </dependency> <!--單元測試座標--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.22</version> </dependency> </dependencies>
User實體
@Data public class User { private Integer id; private String username; }
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1/zdy_mybatis jdbc.username=root jdbc.password=root
<?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檔案--> <properties resource="jdbc.properties"></properties> <!--給實體類的全限定類名給別名--> <typeAliases> <!--給單獨的實體起別名--> <!-- <typeAlias type="com.yun.pojo.User" alias="user"></typeAlias>--> <!--批次起別名:該包下所有的類的本身的類名:別名還不區分大小寫--> <package name="com.yun.pojo"/> </typeAliases> <!--environments:執行環境--> <environments default="development"> <environment id="development"> <!--當前事務交由JDBC進行管理--> <transactionManager type="JDBC"></transactionManager> <!--當前使用mybatis提供的連線池--> <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> <!--引入對映組態檔--> <mappers> <mapper resource="UserMapper.xml"></mapper> </mappers> </configuration>
UserMapper.xml
<mapper namespace="user"> <!--select--> <select id="findAll" resultType="com.yun.pojo.User"> select * from user </select> </mapper>
@Test public void test1() throws IOException { //1.Resources工具類,組態檔的載入,把組態檔載入成位元組輸入流 InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml"); //2.解析了組態檔,並建立了sqlSessionFactory工廠 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //3.生產sqlSession // 預設開啟一個事務,但是該事務不會自動提交 //在進行增刪改操作時,要手動提交事務 SqlSession sqlSession = sqlSessionFactory.openSession(); //4.sqlSession呼叫方法:查詢所有selectList 查詢單個:selectOne 新增:insert 修改:update 刪除:delete List<User> users = sqlSession.selectList("user.findAll"); users.forEach(item ->{ System.out.println(item); }); sqlSession.close(); }
輸出結果
User(id=1, username=Tom)
User(id=2, username=Jerry)
UserMapper.xml
<!--parameterType:引數型別--> <insert id="saveUser" parameterType="com.yun.pojo.User"> insert into user Values (#{id},#{username}) </insert>
@Test public void test2() throws IOException { InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); User user = new User(); user.setId(3); user.setUsername("jack"); sqlSession.insert("user.saveUser",user); sqlSession.commit(); sqlSession.close(); }
資料庫結果:
UserMapper.xml
<update id="updateUser" parameterType="com.yun.pojo.User"> update user set username = #{username} where id = #{id} </update>
@Test public void test3() throws IOException { InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); User user = new User(); user.setId(3); user.setUsername("rose"); sqlSession.update("user.updateUser",user); sqlSession.commit(); sqlSession.close(); }
資料庫結果:
UserMapper.xml
<delete id="deleteUser" parameterType="java.lang.Integer"> delete from user where id =#{id} </delete>
@Test public void test4() throws IOException { InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); User user = new User(); user.setId(3); sqlSession.delete("user.deleteUser",3); sqlSession.commit(); sqlSession.close(); }
資料庫結果:
public interface IUserDao { //查詢所有使用者 List<User> findAll() throws IOException; }
UserDaoImpl
public class UserDaoImpl implements IUserDao { @Override public List<User> findAll() throws IOException { InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); List<User> users = sqlSession.selectList("user.findAll"); sqlSession.close(); return users; } }
@Test public void test5() throws IOException { UserDaoImpl dao = new UserDaoImpl(); List<User> users = dao.findAll(); System.out.println(users); }
列印結果:
[User(id=1, username=Tom), User(id=2, username=Jerry)]
Mapper介面開發需要遵行以下規範:
mapper.xml檔案中的namespace與mapper介面的全限定名相同;
2. mapper介面方法名和mapper.xml中定義的每個statement的id相同
3. mapper介面方法的輸入引數型別和mapper.xml中定義的每個sql的parameterType的型別相同
4. mapper介面方法的輸出引數型別和mapper.xml中定義的每個sql的resultType的型別相同
根據上述的規範修改UserMapper.xml
<mapper namespace="com.yun.dao.IUserDao"> <!--select--> <select id="findAll" resultType="com.yun.pojo.User"> select * from user </select> </mapper>
public interface IUserDao { //查詢所有使用者 List<User> findAll() throws IOException; }
@Test public void test6() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); IUserDao mapper = sqlSession.getMapper(IUserDao.class); List<User> all = mapper.findAll(); all.forEach(item ->{ System.out.println(all); }); }
輸出結果:
User(id=1, username=Tom)
User(id=2, username=Jerry)
public interface IUserDao { //多條件組合查詢:演示if public List<User> findByCondition(User user); }
<!--抽取sql片段--> <sql id="selectUser"> select * from user </sql> <!--多條件組合查詢:演示if--> <select id="findByCondition" parameterType="user" resultType="user"> <include refid="selectUser"></include> <where> <if test="id !=null"> and id = #{id} </if> <if test="username !=null"> and username = #{username} </if> </where> </select>
@Test public void test7() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); IUserDao mapper = sqlSession.getMapper(IUserDao.class); User user1 = new User(); user1.setId(1); user1.setUsername("Tom"); List<User> all = mapper.findByCondition(user1); for (User user : all) { System.out.println(user); } }
輸出結果:
User(id=1, username=Tom)
動態sql語句 foreach標籤
public interface IUserDao { //多值查詢:演示foreach public List<User> findByIds(int[] ids); }
<!--多值查詢:演示foreach--> <select id="findByIds" parameterType="list" resultType="user"> <include refid="selectUser"></include> <where> <foreach collection="array" open="id in (" close=")" item="id" separator=","> #{id} </foreach> </where> </select>
@Test public void test8() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); IUserDao mapper = sqlSession.getMapper(IUserDao.class); int[] arr = {1,2}; List<User> all = mapper.findByIds(arr); for (User user : all) { System.out.println(user); } }
輸出結果:
User(id=1, username=Tom)
User(id=2, username=Jerry)
User實體
@Data public class User { private Integer id; private String username; //該使用者所具有的訂單資訊 private List<Order> orders; //該使用者所具有的角色資訊 private List<Role> roles; }
Order實體
@Data public class Order { private Integer id; private String orderTime; private BigDecimal total; //表明該訂單屬於哪個使用者 private User user; }
Role實體
@Data public class Role { private Integer id; private String roleName; }
public interface IOrderMapper { /** * 查詢訂單的同時還查詢該訂單所屬的使用者 * @return */ public List<Order> findOrderAndUser(); }
<resultMap id="orderMap" type="com.yun.pojo.Order"> <result property="id" column="id"></result> <result property="orderTime" column="order_time"></result> <result property="total" column="total"></result> <association property="user" javaType="com.yun.pojo.User"> <result property="id" column="uid"></result> <result property="username" column="username"></result> </association> </resultMap> <!--resultMap:手動來設定實體屬性與表欄位的對映關係--> <select id="findOrderAndUser" resultMap="orderMap"> select * from orders o,user u where o.uid = u.id </select>
@Test public void test1() throws IOException { //1.Resources工具類,組態檔的載入,把組態檔載入成位元組輸入流 InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml"); //2.解析了組態檔,並建立了sqlSessionFactory工廠 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //3.生產sqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); IOrderMapper mapper = sqlSession.getMapper(IOrderMapper.class); List<Order> orderAndUser = mapper.findOrderAndUser(); orderAndUser.forEach(order -> { System.out.println(order); }); }
執行結果:
Order(id=1, orderTime=2022-05-01, total=1000.00, user=User(id=1, username=Tom, orders=null, roles=null))
Order(id=2, orderTime=2022-05-10, total=2000.00, user=User(id=2, username=Jerry, orders=null, roles=null))
Order(id=3, orderTime=2022-05-20, total=3000.00, user=User(id=2, username=Jerry, orders=null, roles=null))
public interface IUserMapper { /** * 查詢所有使用者資訊,同時查詢出每個使用者關聯的訂單資訊 * @return */ public List<User> findAll(); }
<resultMap id="userMap" type="com.yun.pojo.User"> <id property="id" column="id"></id> <result property="username" column="username"></result> <collection property="orders" ofType="com.yun.pojo.Order"> <id property="id" column="oid"></id> <result property="orderTime" column="order_time"></result> <result property="total" column="total"></result> </collection> </resultMap> <!--resultMap:手動來設定實體屬性與表欄位的對映關係--> <select id="findAll" resultMap="userMap"> select u.*,o.id oid,o.order_time,o.total,o.uid from user u left join orders o on u.id = o.uid </select>
@Test public void test2() throws IOException { //1.Resources工具類,組態檔的載入,把組態檔載入成位元組輸入流 InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml"); //2.解析了組態檔,並建立了sqlSessionFactory工廠 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //3.生產sqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); IUserMapper mapper = sqlSession.getMapper(IUserMapper.class); List<User> users = mapper.findAll(); users.forEach(user -> { System.out.println(user.getUsername()); System.out.println(user.getOrders()); }); }
執行結果:
Tom
[Order(id=1, orderTime=2022-05-01, total=1000.00, user=null)]
Jerry
[Order(id=2, orderTime=2022-05-10, total=2000.00, user=null), Order(id=3, orderTime=2022-05-20, total=3000.00, user=null)]
public interface IUserMapper { /** * 查詢所有使用者資訊,同事查詢出每個使用者關聯的角色資訊 * @return */ public List<User> findUserAndRole(); }
<resultMap id="userAndRoleMap" type="com.yun.pojo.User"> <result property="id" column="userId"></result> <result property="username" column="username"></result> <collection property="roles" ofType="com.yun.pojo.Role"> <result property="id" column="roleId"></result> <result property="roleName" column="rolename"></result> </collection> </resultMap> <select id="findUserAndRole" resultMap="userAndRoleMap"> SELECT * FROM USER u LEFT JOIN sys_user_role sur ON u.id = sur.user_id LEFT JOIN sys_role sr ON sur.role_id = sr.id </select>
@Test public void test3() throws IOException { //1.Resources工具類,組態檔的載入,把組態檔載入成位元組輸入流 InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml"); //2.解析了組態檔,並建立了sqlSessionFactory工廠 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //3.生產sqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); IUserMapper mapper = sqlSession.getMapper(IUserMapper.class); List<User> users = mapper.findUserAndRole(); users.forEach(user -> { System.out.println(user.getUsername()); System.out.println(user.getRoles()); }); }
執行結果:
Tom
[Role(id=null, roleName=董事長), Role(id=null, roleName=經理)]
Jerry
[Role(id=null, roleName=董事長), Role(id=null, roleName=經理)]
@Insert: 實現新增 @Update: 實現更新 @Delete: 實現刪除 @Select: 實現查詢 @Result: 實現結果集封裝;他代替的是標籤<resultMap>,該註解中可以使用單個@Result註解,也可以使用@Result集合, 使用格式:@Results({@Result(),@Result()}) 或 @Results(@Result()) @Results: 可以與@Result一起使用,封裝多個結果集 @One: 實現一對一結果集封裝 @Many: 實現一對多結果集封裝
測試案例
public interface IUserMapper { //新增使用者 @Insert("insert into user values(#{id},#{username})") public void addUser(User user); //更新使用者 @Update("update user set username = #{} where id = #{id}") public void updateUser(User user); //查詢使用者 @Select("select * from user") public List<User> getAllUser(); //刪除使用者 @Delete("delete from user where id=#{id}") public void delUser(Integer id); }
private IUserMapper mapper; @Before public void before() throws IOException { //1.Resources工具類,組態檔的載入,把組態檔載入成位元組輸入流 InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml"); //2.解析了組態檔,並建立了sqlSessionFactory工廠 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //3.生產sqlSession true:事務自動提交 SqlSession sqlSession = sqlSessionFactory.openSession(true); mapper = sqlSession.getMapper(IUserMapper.class); } @Test public void addUser(){ User user = new User(); user.setId(3); user.setUsername("jack"); mapper.addUser(user); } @Test public void updateUser(){ User user = new User(); user.setId(3); user.setUsername("rose"); mapper.updateUser(user); } @Test public void getAllUser(){ List<User> userList = mapper.getAllUser(); userList.forEach(item -> { System.out.println(item); }); } @Test public void delUser(){ mapper.delUser(3); }
執行結果:
一對一
public interface IOrderMapper { /** * 查詢訂單的同時還查詢該訂單所屬的使用者 * @return */ @Results({ @Result(property = "id",column = "id"), @Result(property = "orderTime",column = "order_time"), @Result(property = "total",column = "total"), @Result(property = "user",column = "uid",javaType = User.class, one = @One(select = "com.yun.mapper.IUserMapper.getUserById")), }) @Select("select * from orders") public List<Order> findOrderAndUser(); } public interface IUserMapper { @Select("select * from user where id = #{id}") public User getUserById(Integer id); }
@Test public void oneToOne(){ List<Order> orderAndUser = orderMapper.findOrderAndUser(); orderAndUser.forEach(item -> { System.out.println(item); }); }
執行結果:
Order(id=1, orderTime=2022-05-01, total=1000.00, user=User(id=1, username=Tom, orders=null, roles=null))
Order(id=2, orderTime=2022-05-10, total=2000.00, user=User(id=2, username=Jerry, orders=null, roles=null))
Order(id=3, orderTime=2022-05-20, total=3000.00, user=User(id=2, username=Jerry, orders=null, roles=null))
一對多
public interface IUserMapper { /** * 查詢所有使用者資訊,同時查詢出每個使用者關聯的訂單資訊 * @return */ @Select("select * from user") @Results({ @Result(property = "id",column = "id"), @Result(property = "username",column = "username"), @Result(property = "orders",column = "id",javaType = List.class, many = @Many(select = "com.yun.mapper.IOrderMapper.getOrderByUid")) }) public List<User> findAll(); } public interface IOrderMapper { @Select("select * from orders where uid = #{uid}") public List<Order> getOrderByUid(Integer uid); }
@Test public void oneToMore(){ List<User> users = mapper.findAll(); users.forEach(item -> { System.out.println(item); }); }
執行結果:
User(id=1, username=Tom, orders=[Order(id=1, orderTime=null, total=1000.00, user=null)], roles=null)
User(id=2, username=Jerry, orders=[Order(id=2, orderTime=null, total=2000.00, user=null), Order(id=3, orderTime=null, total=3000.00, user=null)], roles=null)
多對多
public interface IUserMapper { /** * 查詢所有使用者資訊,同事查詢出每個使用者關聯的角色資訊 * @return */ @Select("select * from user") @Results({ @Result(property = "id",column = "id"), @Result(property = "username",column = "username"), @Result(property = "roles",column = "id",javaType = List.class, many = @Many(select ="com.yun.mapper.IRoleMapper.getAll")) }) public List<User> findUserAndRole(); } public interface IRoleMapper { @Select("select * from sys_role sr,sys_user_role sur where sr.id = sur.role_id and sur.user_id = #{uid}") public List<Role> getAll(Integer uid); }
@Test public void moreToMore(){ List<User> users = mapper.findUserAndRole(); users.forEach(item -> { System.out.println(item); }); }
執行結果:
User(id=1, username=Tom, orders=null, roles=[Role(id=1, roleName=董事長), Role(id=2, roleName=經理)])
User(id=2, username=Jerry, orders=null, roles=[Role(id=1, roleName=董事長), Role(id=2, roleName=經理)])
快取就是記憶體中的資料,常常來自對資料庫查詢結果的儲存,使用快取,我們可以避免頻繁的與資料庫進行互動,進而提高響應速度.
一級快取是SqlSession,在運算元據庫時需要構造sqlSession物件,在物件中有一個資料結構(HashMap)用於儲存快取資料.不同的sqlSession之間互不影響.
二級快取是mapper級別的快取,多個sqlSession去操作同一個mapper的sql語句,多個sqlSession可以共用二級快取,二級快取是跨sqlSession的.
demo
public class CacheTest { private IUserMapper mapper; private SqlSession sqlSession; @Before public void before() throws IOException { //1.Resources工具類,組態檔的載入,把組態檔載入成位元組輸入流 InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml"); //2.解析了組態檔,並建立了sqlSessionFactory工廠 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //3.生產sqlSession true:事務自動提交 sqlSession = sqlSessionFactory.openSession(true); mapper = sqlSession.getMapper(IUserMapper.class); } @Test public void test1() { //第一次查詢id為1的使用者 User user1 = mapper.getUserById(1); //第二次查詢id為1的使用者 User user2 = mapper.getUserById(1); System.out.println(user1 == user2); } }
現在我們變換一下上面的demo
public class CacheTest { private IUserMapper mapper; private SqlSession sqlSession; @Before public void before() throws IOException { //1.Resources工具類,組態檔的載入,把組態檔載入成位元組輸入流 InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml"); //2.解析了組態檔,並建立了sqlSessionFactory工廠 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //3.生產sqlSession true:事務自動提交 sqlSession = sqlSessionFactory.openSession(); mapper = sqlSession.getMapper(IUserMapper.class); } @Test public void test1() { //第一次查詢id為1的使用者 User user1 = mapper.getUserById(1); User user = new User(); user.setId(1); user.setUsername("Lucy"); mapper.updateUser(user); sqlSession.commit(); //第二次查詢id為1的使用者 User user2 = mapper.getUserById(1); System.out.println(user1 == user2); } }
結論:做增刪改操作,並進行了事物的提交,就會重新整理以及快取;或者還可以通過 sqlSession.clearCache()清楚快取;這樣做的目的就是為了讓快取中儲存的是最新的資訊,避免髒讀;
二級快取的原理和一級快取原理一樣,第一次查詢會將資料放入快取中,然後第二次查詢則會直接從快取中獲取,但是一級快取是基於sqlSession的,而二級快取是基於mapper檔案的namespace,也就是說,多個sqlSession可以共用一個mapper中的二級快取,並且如果兩個mapper的namespace相同,即使是兩個mapper,那麼這兩個mapper執行sql查詢到的資料也將存在相同的二級快取區域中.
首先在全域性組態檔sqlMapconfig.xml檔案加入如下程式碼
<settings> <setting name="cacheEnabled" value="true"/> </settings>
注意,該設定需要放在properties標籤下,具體順序,可百度瞭解
其次,在xxxMapper.xml檔案中開啟快取(如果當前操作時基於註解開發的話,使用註解@CacheNamespace)
<cache></cache>
demo2
public class CacheTest { private IUserMapper mapper; private SqlSession sqlSession; private SqlSessionFactory sqlSessionFactory; @Before public void before() throws IOException { //1.Resources工具類,組態檔的載入,把組態檔載入成位元組輸入流 InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml"); //2.解析了組態檔,並建立了sqlSessionFactory工廠 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //3.生產sqlSession sqlSession = sqlSessionFactory.openSession(); mapper = sqlSession.getMapper(IUserMapper.class); } @Test public void test2() { SqlSession sqlSession1 = sqlSessionFactory.openSession(); SqlSession sqlSession2 = sqlSessionFactory.openSession(); SqlSession sqlSession3 = sqlSessionFactory.openSession(); IUserMapper mapper1 = sqlSession1.getMapper(IUserMapper.class); IUserMapper mapper2 = sqlSession2.getMapper(IUserMapper.class); IUserMapper mapper3 = sqlSession3.getMapper(IUserMapper.class); User user1 = mapper1.getUserById(1); //清空一級快取 sqlSession1.close(); User user2 = mapper2.getUserById(1); System.out.println(user1 == user2); } }
執行結果為 false
結論:通過debug斷點顯示,實際上,第二次查詢則會直接從快取中獲取使用者資訊了,不過二級快取快取的不是物件,而是快取的物件中的資料,所以查詢結果為false;
注意,二級快取底層還是HashMap結構,所以 po類需要實現序列化介面 ;因為二級快取資料儲存媒介多種多樣,不一定只存在記憶體中,有可能存在硬碟中,如果我們要在取這個快取的話,就需要反序列化了,所以mybatis中的pojo都去實現Serializable介面;
變換一下demo2
@Test public void test2() { SqlSession sqlSession1 = sqlSessionFactory.openSession(); SqlSession sqlSession2 = sqlSessionFactory.openSession(); SqlSession sqlSession3 = sqlSessionFactory.openSession(); IUserMapper mapper1 = sqlSession1.getMapper(IUserMapper.class); IUserMapper mapper2 = sqlSession2.getMapper(IUserMapper.class); IUserMapper mapper3 = sqlSession3.getMapper(IUserMapper.class); User user1 = mapper1.getUserById(1); //清空一級快取 sqlSession1.close(); User user = new User(); user.setId(1); user.setUsername("Tom"); mapper3.updateUser(user); sqlSession3.commit(); User user2 = mapper2.getUserById(1); System.out.println(user1 == user2); }
結論:做增刪改操作,並進行了事物的提交,就會重新整理以及快取;這樣做的目的就是為了讓快取中儲存的是最新的資訊,避免髒讀;
此外mybatis中還可以設定useCache和flushCache等設定項;
useCache
是用來設定是否禁用二級快取的,在statement中設定useCache=false可以禁用當前select語句的二級快取,即每次查詢都會會發出sql去查詢,預設情況是true,即該sql使用二級快取,例如
<select id="findAll" useCache = "false" resultMap="userMap"> select u.*,o.id oid,o.order_time,o.total,o.uid from user u left join orders o on u.id = o.uid </select>
使用sql註解方式可以使用@Options(useCache = false)的方式
flushCache
在mapper的同一個namespace中,如果有其他的insert,update,delete運算元據後需要重新整理快取,如果不執行重新整理快取會出現髒讀,設定statememt設定中的
flushCache = "true"屬性,預設情況下為true,即重新整理快取,如果改成false則不會重新整理,使用快取時如果手動修改資料庫表中的查詢資料會出現髒讀 例如
<select id="findAll" flushCache = "true" useCache = "false" resultMap="userMap"> select u.*,o.id oid,o.order_time,o.total,o.uid from user u left join orders o on u.id = o.uid </select>
一般下執行完commit操作都需要重新整理快取,flushCache=true表示重新整理快取,這樣可以避免資料庫髒讀,所以我們不用設定,預設即可
至此,mybatis基礎概念及應用回顧完成!
到此這篇關於Mybatis基礎回顧與高階應用的文章就介紹到這了,更多相關Mybatis高階應用內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45