MyBatis概述
三層架構
- 表現層 展示數據
- 業務層 處理業務需求
- 持久層 和數據庫交互
持久層技術解決方案
JDBC
技術:Connection、PreparedStatement、ResultSet
- Spring的
JdbcTemplate
- Apache的
DBUtils
JDBC
是規範,剩下兩個都是工具類
mybatis概述
- mybatis是一個持久層框架,它封裝了jdbc操作的很多細節,使開發者只需關注sql語句本身。它使用了ORM思想實現了結果集的封裝。
- ORM: Object Relational Mapping 對象關係映射
- 把數據庫表和實體類及實體類的屬性對應起來,讓我們可以操作實體類就操作數據庫表。
log4j 打印日誌
-
在pom.xml中導入3個座標:
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>2.0.0-alpha1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.0-alpha1</version> </dependency> <dependency> <groupId>org.bgee.log4jdbc-log4j2</groupId> <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId> <version>1.16</version> </dependency>
- 配置
jdbcConfig.properties
文件:
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
- 配置
log4j.properties
文件
### 設置Logger輸出級別和輸出目的地 ### debug更詳細,如果設爲info那麼打印出的表數據遇到字符串就不顯示,此外還有logfile log4j.rootLogger=debug,stdout ### 把日誌信息輸出到控制檯 ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender #log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout ### 把日誌信息輸出到文件:jbit.log ### #log4j.appender.logfile=org.apache.log4j.FileAppender #log4j.appender.logfile.File=jbit.log #log4j.appender.logfile.layout=org.apache.log4j.PatternLayout #log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %F %p %m%n ###顯示SQL語句部分 #log4j.logger.com.mybatis=DEBUG #log4j.logger.com.mybatis.common.jdbc.SimpleDataSource=DEBUG #log4j.logger.com.mybatis.common.jdbc.ScriptRunner=DEBUG #log4j.logger.com.mybatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG #log4j.logger.java.sql.Connection=DEBUG #log4j.logger.java.sql.Statement=DEBUG #log4j.logger.java.sql.PreparedStatement=DEBUG #log4j.logger.java.sql.ResultSet=DEBUG
- 配置
mybatis入門
-
mybatis的環境搭建
- 步驟
- 導入座標
mybatis , mysql-connector,log4j,junit
- 創建實體類和dao的接口
- 創建mybatis的主配置文件
SqlMapConfig.xml
- 創建映射配置文件
IUserDao.xml
- 導入座標
- 注意事項:
IUserDao
和IUserMapper
是一樣的- mybatis的映射配置文件位置必須和dao接口的包結構相同
- 映射配置文件mapper標籤namespace屬性的取值必須是dao接口的全限定類名。
- 映射配置文件的操作配置(select),id屬性的取值必須是dao接口的方法名。
- 當遵循了後3點後,開發中無需寫dao的實現類
- 步驟
-
mybatis的入門案例
- 讀取配置文件
- 創建
SqlSessionFactory
工廠 - 創建
SqlSession
- 創建Dao接口的代理對象
- 執行dao中的方法
- 釋放資源
-
基於xml
-
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"> <!--mybatis的主配置文件--> <configuration> <!-- 配置環境 --> <environments default="mysql"> <!--配置mysql的環境--> <environment id="mysql"> <!--配置事務的類型--> <transactionManager type="JDBC"></transactionManager> <!--配置數據源(連接池)--> <dataSource type="POOLED"> <!--配置連接數據庫的4個基本信息--> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis?serverTimezone=UTC&useSSL=false"/> <property name="username" value="root"/> <property name="password" value="070622"/> </dataSource> </environment> </environments> <!--指定映射配置文件的位置,映射配置文件是指每個dao獨立的配置文件--> <mappers > <mapper resource="com/qmh/dao/IUserDao.xml"></mapper> </mappers> </configuration>
-
映射配置文件
IUserDao.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="com.qmh.dao.IUserDao"> <!--配置查詢所有--> <select id="findAll" resultType="com.qmh.domain.User"> select * from user </select> </mapper>
-
入門案例測試代碼:
//1.讀取配置文件 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.創建SqlSessionFactory工廠 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(in); //3.使用工廠生產SqlSession對象 SqlSession session = factory.openSession(); //4.使用SqlSession創建Dao接口的代理對象 IUserDao userDao = session.getMapper(IUserDao.class); //5.使用代理對象執行方法 List<User> users = userDao.findAll(); for(User user:users){ System.out.println(user); } //6.釋放資源 session.close(); in.close();
-
-
基於註解
-
移除
IUserDao.xml
,修改Dao接口類/** * 持久層接口 */ public interface IUserDao { /** * 查詢所有 * @return */ @Select("select * from user") List<User> findAll(); }
-
修改Config配置文件的mappers
<!--指定映射配置文件的位置,映射配置文件是指每個dao獨立的配置文件 如果使用註解進行配置,此處應該使用class屬性的全限定類名--> <mappers > <mapper class="com.qmh.dao.IUserDao"></mapper> </mappers>
-
-
自己實現dao實現類時
public List<User> findAll() {
//1.使用工廠創建SqlSession對象
SqlSession session = factory.openSession();
//2.使用session執行查詢所有 這裏通過 IUserDao.xml中的namespace+id唯一定位到方法
List<User> users = session.selectList("com.qmh.dao.IUserDao.findAll");
session.close();
return users;
}
-
自定義Mybatis的分析
-
mybatis在使用代理dao的方式實現增刪改查時做的事情:
- 創建代理對象
- 在代理對象中調用
selectList
方法
-
selectList
方法分析: -
創建代理對象
-
public<T> T getMapper(Class<T> daoInterfaceClass){ /** * 類加載器:和被代理對象使用相同的類加載器 * 代理對象要實現的接口:和被代理對象實現相同的接口 * 如何代理: 增強的方法,需要自己提供,是一個InvocationHandler的接口,需要寫一個 * 該接口的實現類,在實現類中調用selectList方法 */ Proxy.newProxyInstance(ClassLoader loader,類<?>[] interfaces,InvocationHandler h) }
-
-
自定義Mybatis實現
- 步驟:
- 創建代理對象
- 在代理對象中調用
selectList
方法
- 入門案例中能看到的類:
class Resources
class SqlSessionFactoryBuilder
interface SqlSessionFactory
public interface SqlSession extends Closeable
- 代碼實現參考博客Mybatis學習筆記 - 01
Mybatis框架實現CRUD操作(CRUD—Create Read Update Delete )
-
IUserDao.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="com.qmh.dao.IUserDao"> <select id="findAll" resultType="com.qmh.domain.User"> select * from user </select> <insert id="saveUser" parameterType="com.qmh.domain.User"> <!-- 配置插入操作後,獲取插入數據的id --> <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER"> select last_insert_id() </selectKey> insert into user(username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address}) </insert> <update id="updateUser" parameterType="com.qmh.domain.User"> update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id} </update> <delete id="deleteUser" parameterType="Integer"> delete from user where id=#{uid} </delete> <select id="findById" parameterType="int" resultType="com.qmh.domain.User"> select * from user where id=#{uid} </select> <select id="findByName" parameterType="String" resultType="com.qmh.domain.User"> <!-- select * from user where username like #{uname} --> select * from user where username like '%${value}%' </select> <select id="findTotal" resultType="int"> select count(id) from user </select> </mapper>
-
添加操作之後獲取id值,配置
selectKey
標籤<insert id="saveUser" parameterType="com.qmh.domain.User"> <!-- 配置插入操作後,獲取插入數據的id --> <selectKey keyProperty="userId" keyColumn="id" resultType="int" order="AFTER"> select last_insert_id() </selectKey> insert into user(username,birthday,sex,address) values (#{userName},#{userBirthday},#{userSex},#{userAddress}) </insert>
-
OGNL表達式
-
Object Graphic Navigation Language 對象圖導航語言
- mybatis使用ognl表達式解析對象字段的值,#{} 或 ${}括號中的值作爲pojo(plain ordinary java object,簡單普通的java對象)屬性名稱
- 它是通過對象的取值方法來獲取數據,在寫法上把get給省略了。
- 舉例:
- 類中的寫法
user.getUserName()
- OGNL表達式寫法
user.username
對象.屬性
- 類中的寫法
- mybatis中的parameterType中已經提供了屬性所屬的類,所以此時不需要寫對象名。
-
當數據庫的列名和類屬性不一致時,有兩種修改方式:
-
在sql語句中使用
as
起別名。 -
在
IUserDao.xml
中創建resultMap
標籤,將resultType
修改爲resultMap="userMap"
<!-- 配置查詢結果的列名和實體類的屬性名的對應關係 --> <resultMap id="userMap" type="com.qmh.domain.User"> <!--主鍵字段的對應 --> <id property="userId" column="id"></id> <!--非主鍵字段的對應 --> <result property="userName" column="username"></result> <result property="userAddress" column="address"></result> <result property="userSex" column="sex"></result> <result property="userBirthday" column="birthday"></result> </resultMap>
-
mysql數據庫在windows下不區分大小寫,所以
userName
可以寫入,其他屬性則不行。但在linux下是嚴格區分大小寫的,故所有屬性都無法寫入。
-
-
mybatis主配置文件的
properties
標籤-
創建
jdbcConfig.properties
jdbc.driver = com.mysql.cj.jdbc.Driver jdbc.url = jdbc:mysql://localhost:3306/eesy_mybatis?serverTimezone=Hongkong jdbc.username = root jdbc.password = 070622
-
修改
SqlMapConfig.xml
<configuration> <!-- 配置properties 可以在標籤內部配置連接數據庫信息,也可以通過屬性引用外部配置文件信息 resource屬性: 用於指定配置文件的位置 --> <properties resource="jdbcConfig.properties"> </properties> <!--配置環境--> <environments default="mysql"> <environment id="mysql"> <!--配置事務--> <transactionManager type="JDBC"></transactionManager> <!--配置數據源--> <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="com/qmh/dao/IUserDao.xml"></mapper> </mappers> </configuration>
-
也可以使用url屬性定位配置文件
<!-- 配置properties 可以在標籤內部配置連接數據庫信息,也可以通過屬性引用外部配置文件信息 resource屬性: 用於指定配置文件的位置 url屬性:按照url的寫法來寫地址 它的寫法: http://localhost:8080/mybatisserver/demo1Servlet 協議 主機 端口 URI URI uniform Resource Identifier 統一資源標識符,在應用中唯一定位一個資源 --> <properties url="file:///C:\Users\qmh\IdeaProjects\MyBatis_JDBC\MyBatis\day02_eesy_01mybatisCRUD\src\main\resources\jdbcConfig.properties"> </properties>
-
配置別名
typeAliases
<typeAliases> <!--typeAlias 用於配置別名--> <!-- <typeAlias type="com.qmh.domain.User" alias="user"></typeAlias>--> <!--用於指定要配置別名的包,當指定之後,該包下的實體類都會註冊別名,並且類名就是別名--> <package name="com.qmh.domain"/> </typeAliases>
-
package
標籤<!--配置映射文件的位置--> <mappers> <!-- <mapper resource="com/qmh/dao/IUserDao.xml"></mapper>--> <!--package標籤是用於指定dao接口所在的包,當指定之後就不需要再寫mapper標籤--> <package name="com.qmh.dao"/> </mappers>
-
連接池
-
存放數據庫連接的容器,必須保證線程安全,同時滿足隊列先進先出的特點
-
mybatis中的連接池
- mybatis連接池提供了3種方式的配置
- 配置位置:主配置文件中的
dataSource
標籤,type屬性表示採用何種連接池方式。 - type屬性的取值:
POOLED
傳統的javax.sql.DataSource
規範中的連接池。UNPOOLED
採用傳統的獲取連接的方式JNDI
採用服務器提供的JNDI技術實現,來獲取DataSource
對象. 目的是模仿windows的註冊表
-
查看POOLED的實現方式
mybatis中的事務
- 通過SqlSession對象的commit方法和rollback方法實現事務的提交和回滾
mybatis中的動態sql語句
-
根據傳入的參數查詢。
IUserDao.xml
,可以做到多條件查詢,如select * from user WHERE username=? and sex=?
<select id="findUserByCondition" resultMap="userMap" parameterType="user"> select * from user <where> <if test="userName!=null"> and username=#{userName} </if> <if test="userSex!=null"> and sex=#{userSex} </if> </where> </select>
-
foreach
標籤 根據QueryVo
類中的ids集合使用in進行查詢。Preparing: select * from user WHERE id in ( ? , ? , ? )
<!--根據queryVo中的id集合實現查詢列表--> <select id="findUserInIds" resultMap="userMap" parameterType="QueryVo"> select * from user <where> <if test="ids!=null and ids.size()>0"> <foreach collection="ids" open ="and id in (" close=")" item="uid" separator="," > #{uid} </foreach> </if> </where> </select>
-
include
標籤,抽取重複的sql語句<!--抽取重複的sql語句--> <sql id="defaultUser"> select * from user </sql> <select id="findAll" resultMap="userMap"> <include refid="defaultUser"></include> </select>
mybatis中的多表查詢
-
表之間的關係:
- 一對多 用戶和訂單
- 多對一 訂單和用戶 。 mybatis中認爲每拿出一個訂單,它只屬於一個用戶,所以把多對一看作一對一
- 一對一 人和身份證號
- 多對多 老師和學生
-
mybatis中的多表查詢
- 用戶和賬戶
- 一個用戶可以有多個賬戶
- 一個賬戶只能屬於一個用戶(多個賬戶也可以屬於一個用戶)
- 步驟:
- 建立用戶表和賬戶表,其中賬戶表具有外鍵
- 建立兩個實體類:用戶類和賬戶類,讓這兩個類能體現出一對多的關係
- 建立兩個配置文件:用戶的(
IUserDao.xml
)和賬戶的(IAccountDao.xml
) - 實現配置。
- 一對一查詢
public class Account implements Serializable { private Integer id; private Integer uid; private Double money; //從表實體應該包含主表實體的一個對象引用 private User user; ... }
<!--定義封裝account和user的resultMap--> <resultMap id="accountUserMap" type="Account"> <!--配置主鍵--> <id property="id" column="aid"></id> <!--配置其他--> <result property="uid" column="uid"></result> <result property="money" column="money"></result> <!--一對一的關係映射。配置封裝User的內容--> <association property="user" column="uid" javaType="user"> <result property="id" column="id"></result> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="birthday"></result> </association> </resultMap> <select id="findAll" resultMap="accountUserMap"> select u.*,a.id as aid,a.uid,a.money from user u,account a where u.id=a.uid; </select>
- 一對多查詢
public class User implements Serializable { private Integer id; private String username; private LocalDateTime birthday; private String sex; private String address; //一對多關係映射,主表實體應該包含從表實體的集合引用 private List<Account> accounts; ... }
<!--定義User的ResultMap--> <resultMap id="userAccountMap" type="user"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="birthday"></result> <!--配置user對象中accounts集合的映射--> <collection property="accounts" ofType="account"> <id property="id" column="aid"></id> <result property="uid" column="uid"></result> <result property="money" column="money"></result> </collection> </resultMap> <select id="findAll" resultMap="userAccountMap"> select * from `user` u left outer join account a on u.id = a.uid </select>
- 用戶和賬戶
-
多對多查詢 示例:用戶和角色
-
步驟:
- 建立兩張表:用戶表、角色表
- 讓用戶表和角色表具有多對多的關係,需要使用中間表,中間表中包含各自的主鍵,在中間表中是外鍵。
- 建立兩個實體類:用戶實體類和角色實體類。 各自包含對方一個集合。
- 建立兩個配置文件
- 實現配置。
- 建立兩張表:用戶表、角色表
-
實現角色到用戶的多對多操作
sql語句:
select r.id as rid,r.role_desc ,r.role_name ,u.* from role r left outer join user_role ur on r.id =ur.rid left outer join user u on u.id = ur.uid ;
public class Role implements Serializable { private Integer roleId; private String roleName; private String roleDesc; //多對多的關係映射,一個角色可以賦予多個用戶 private List<User> users; ... }
<resultMap id="roleMap" type="role"> <id property="roleId" column="rid"></id> <result property="roleName" column="role_name"></result> <result property="roleDesc" column="role_desc"></result> <collection property="users" ofType="User"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="birthday" column="birthday"></result> <result property="sex" column="sex"></result> <result property="address" column="address"></result> </collection> </resultMap> <select id="findAll" resultMap="roleMap"> select r.id as rid,r.role_desc ,r.role_name ,u.* from `role` r left outer join user_role ur on r.id =ur.rid left outer join `user` u on u.id = ur.uid ; </select>
-
-
實現用戶到角色的多對多操作
sql語句:
select u.*,r.id as rid,r.role_desc ,r.role_name from user u left join user_role ur ON u.id = ur.uid left join role r on r.id =ur.rid ;
public class Role implements Serializable { private Integer roleId; private String roleName; private String roleDesc; //多對多的關係映射,一個角色可以賦予多個用戶 private List<User> users; ... }
<resultMap id="roleMap" type="role"> <id property="roleId" column="rid"></id> <result property="roleName" column="role_name"></result> <result property="roleDesc" column="role_desc"></result> <collection property="users" ofType="User"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="birthday" column="birthday"></result> <result property="sex" column="sex"></result> <result property="address" column="address"></result> </collection> </resultMap> <select id="findAll" resultMap="roleMap"> select r.id as rid,r.role_desc ,r.role_name ,u.* from `role` r left outer join user_role ur on r.id =ur.rid left outer join `user` u on u.id = ur.uid ; </select>
JNDI
-
創建maven的war工廠。
-
導入依賴,新增:
servlet-api
,servlet.jsp-api
-
配置context.xml
<?xml version="1.0" encoding="UTF-8"?> <Context> <!-- <Resource name="jdbc/db1" auth="Container" type="javax.sql.DataSource"--> <!-- username="db1" password="123456" driverClassName="com.mysql.jdbc.Driver"--> <!-- url="jdbc:mysql://localhost:3306/db1" maxActive="100" maxWait="50000"--> <!-- maxIdle="30" />--> <Resource name="jdbc/eesy_mybatis" type="javax.sql.DataSource" username="root" password="070622" auth="Container" driverClassName="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/eesy_mybatis?serverTimezone=UTC" maxActive="20" maxWait="1000" maxIdle="5" /> </Context>
-
剩下的內容由於沒有部署
tomcat
服務器,故放棄。
mybatis的延遲加載
-
問題:
- 在一對多中,有一個用戶有100個賬戶,在查詢用戶時,要不要把關聯的賬戶查出來?
- 在查詢賬戶時,要不要把關聯的用戶查出來?
-
分析
- 在查詢用戶時,用戶下的賬戶信息應該是什麼時候使用,什麼時候查詢的 ——延遲加載/懶加載
- 在查詢賬戶時,賬戶的所屬用戶信息應該隨賬戶查詢時一起查詢出來 —— 立即加載
- 在四種表關係中,可以分爲兩組:
- 一對多,多對多 —— 延遲加載
- 多對一,一對一。——立即加載
-
延遲加載舉例
-
在
SqlMapConfig.xml
中配置settings
標籤<!--配置參數--> <settings> <!--開啓mybatis支持延遲加載--> <setting name="lazyLoadingEnabled" value="true"/> <!--按需加載--> <setting name="aggressiveLazyLoading" value="flase"/> </settings>
-
使用collection標籤、association標籤中的
select
屬性,指定調用的方法名稱,同時column
屬性指定被用來查詢的屬性列名 -
根據
uid
查詢賬戶所屬的用戶信息<!--定義封裝account和user的resultMap--> <resultMap id="accountUserMap" type="Account"> <!--配置主鍵--> <id property="id" column="id"></id> <!--配置其他--> <result property="uid" column="uid"></result> <result property="money" column="money"></result> <!--一對一的關係映射,配置封裝user的內容 select屬性指定的內容:查詢用戶的唯一標識 column屬性指定的內容:用戶根據id查詢時,所需要的參數值 --> <association property="user" column="uid" javaType="user" select="com.qmh.dao.IUserDao.findById"></association> </resultMap> <select id="findAll" resultMap="accountUserMap"> select * from account </select>
-
根據
id
查詢用戶名下的賬戶信息<!--定義User的ResultMap--> <resultMap id="userAccountMap" type="user"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="birthday"></result> <!--配置user對象中accounts集合的映射--> <collection property="accounts" ofType="account" select="com.qmh.dao.IAccountDao.findAccountByUid" column="id" ></collection> </resultMap> <select id="findAll" resultMap="userAccountMap"> select * from `user` u </select>
-
Mybatis中的緩存
-
緩存是指存在於內存中的臨時數據。
-
減少和數據庫的交互次數,提高執行效率
-
適用於緩存:
- 經常查詢並且不經常改變的。
- 數據的正確與否對最終結果影響不大。
-
不適用於緩存:
- 經常改變的數據
- 數據的正確與否對最終結果影響很大:商品庫存,銀行匯率,股市牌價
-
Mybatis中的一級緩存和二級緩存
-
一級緩存:
-
指Mybatis中SqlSession對象的緩存,
-
當執行查詢之後,查詢結果會同時存入到sqlsession提供的一塊區域中,該區域的結構是一個Map,當再次查詢同樣的數據,mybatis會先去sqlseesion中查詢。有的話,直接拿出來用
-
當sqlsession對象消失時,mybatis的一級緩存也就消失了。
-
當調用sqlsession的CUD操作,commit(),close()等方法,就會清空一級緩存。
-
-
二級緩存
-
指Mybatis中SqlSessionFactory對象的緩存,由同一個SqlSessionFactory創建的sqlsession共享其緩存。
-
二級緩存中存放的內容是數據,而不是對象。根據數據創建一個新的對象
-
使用步驟
-
讓mybatis支持二級緩存(在
SqlMapConfig.xml
中配置)<settings> <setting name="cacheEnabled" value="true"/> </settings>
-
讓當前的映射文件支持二級緩存(在
IUserDao.xml
中配置)<!--開啓user支持二級緩存--> <cache></cache>
-
讓當前操作支持二級緩存(在
select
標籤中配置)<select id="findById" parameterType="int" resultType="user" useCache="true"> select * from user where id=#{uid} </select>
-
-
-
Mybatis中的註解開發
-
SqlMapConfig.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="jdbcConfig.properties"></properties> <!--配置別名--> <typeAliases> <package name="com.qmh.domain"/> </typeAliases> <!--配置環境--> <environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <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> <!--指定dao接口所在位置--> <mappers> <package name="com.qmh.dao"/> </mappers> </configuration>
-
IUserDao.xml
public interface IUserDao { @Select("select * from user") List<User> findAll(); @Insert("insert into user(username,address,sex,birthday) values(#{username},#{address},#{sex},#{birthday})") void saveUser(User user); @Update("update user set username=#{username},sex=#{sex},address=#{address} where id=#{id}") void updateUser(User user); @Delete("delete from user where id=#{uid}") void deleteUser(Integer userId); @Select("select * from user where id=#{uid}") User findById(Integer userId); @Select("select * from user where username like #{username}") List<User> findUserByName(String username); @Select("select count(id) from user") int findTotalUser(); }
-
多對一查詢(一對一)
public interface IAccountDao { /** * 查詢所有賬戶並帶有對應的用戶信息,多對一的情況下是立即加載 * @return */ @Select("select * from account") @Results(id="accountMap",value = { @Result(id = true,property = "id",column = "id"), @Result(property = "uid",column = "uid"), @Result(property = "money",column = "money"), @Result(property = "user", column = "uid",one =@One(select="com.qmh.dao.IUserDao.findById",fetchType= FetchType.EAGER)) }) List<Account> findAll(); }
-
一對多查詢
public interface IUserDao { /** * 查詢所有用戶,並返回用戶對應的賬戶信息, 一對多的情況下使用懶加載 * @return */ @Select("select * from user") @Results(id="userMap",value = { @Result(id=true,column = "id",property = "userId"), @Result(column = "username",property = "userName"), @Result(column = "sex",property = "userSex"), @Result(column = "address",property = "userAddress"), @Result(column = "birthday",property = "userBirthday"), @Result(property = "accounts",column = "id",many = @Many(select = "com.qmh.dao.IAccountDao.findById",fetchType = FetchType.LAZY)) }) List<User> findAll();
-
使用註解開啓二級緩存
@CacheNamespace(blocking = true)