MyBatis框架介紹以及快速入門
MyBatis框架
今日學習內容目標
- 能夠了解什麼是框架
- 理解自定義Mybatis框架
- 掌握Mybatis框架開發快速入門
第一節 認識框架
1.介紹
框架就是一個架子,表演節目,舞臺已經搭建好,表演什麼節目,看自己的需求了。
框架是一個半成品,對於Java語言來說,框架就是封裝了別人的程式碼。在框架的基礎上我們在進一步開發,拿來用。
2.解決的問題
解決的是技術整合問題。軟體開發環境和規模都很大,不可能任何一個專案的程式碼都從零開始,此時就需要一個非常優秀的框架把基礎技術整合完畢,我們在他的基礎上進一步開發。提高效能,易擴充套件,易維護,最終提高整個團隊的開發效率。
3.使用框架
企業級大型專案開發用框架,避免大炮打蚊子。
Java的框架是具有一些共性
- 匯入jar包
- 框架執行細節定義,也就是編寫配置檔案(xml)
- 呼叫框架中的api
第二節 原生JDBC案例
- 查詢user表
- 以List集合形式返回
- 編寫pojo類 (User)
- domain,pojo本質都是相同的
1.JdbcDemo類
/** * 原始的JDBC,對資料表user查詢,結果集儲存List集合 * */ public class JdbcDemo { public static void main(String[] args) throws Exception { // 註冊驅動 Class.forName("com.mysql.jdbc.Driver"); // 獲取連線 Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis","root","root"); // SQL語句執行物件 PreparedStatement pst = con.prepareStatement("select * from user"); // 執行查詢,返回結果集 ResultSet rs = pst.executeQuery(); List<User> userList = new ArrayList<User>(); while (rs.next()){ User user = new User(); // 取出表中資料,rs物件的方法getXXX() user.setId(rs.getInt("id")); user.setUsername(rs.getString("username")); user.setSex(rs.getString("sex")); user.setBirthday(rs.getDate("birthday")); user.setAddress(rs.getString("address")); userList.add(user); } for (User user : userList){ System.out.println(user); } rs.close(); pst.close(); con.close(); } }
2.User類
// 和資料庫中的鍵對照 public class User { private int id; private String username; private String sex; private Date birthday; private String address; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", sex='" + sex + '\'' + ", birthday=" + birthday + ", address='" + address + '\'' + '}'; } }
3.原始的JDBC的缺陷
原始程式問題:維護性差,擴充套件性差,出現問題,修改原始碼,程式碼量大
- 頻繁連線,釋放資料庫資源,降低系統性能
- 解決辦法:連線池
- 資料庫驅動類,連線四大資訊
- 解決辦法:寫配置檔案,讀取
- SQL語句硬編碼,SQL語句寫死了 SQL語句中的 ? 佔位符
- 解決辦法:寫配置檔案,讀取
- 封裝資料表結果集程式碼,硬編碼
- 引出連線池,Apache DBUtils
4.框架
框架:最基本的程式碼,整合起來
連線資料庫,執行SQL語句,封裝結果集整合
只要提供:SQL語句,寫xml中
第三節 MyBatis框架
1.歷史
Mybatis原本是Apache軟體基金會的一個開源專案叫做iBatis,2010年這個專案由Apache遷移到了google code管理才改名為Mybatis,2013年又遷移到了GitHub。
2.介紹
Mybatis是一個優秀的持久層框架(Dao層框架),它是對JDBC的封裝,使得開發者只需要關注Sql語句(業務)本身即可,無需開發者處理載驅動、獲取連線、建立Statement等繁瑣的過程。
3.原理
Mybatis最大的特點是把Sql語句寫在XML配置檔案當中。而且Mybatis執行完Sql語句之後可以以物件形式返回(POJO/POJO集合等)。
思想
Mybatis是一個實現了ORM思想的持久層框架。
ORM:Object/Relation Mapping 物件/關係對映。
ORM思想:將資料庫中的關係資料表對映為JAVA中的物件,把對資料表的操作轉換為對物件的操作,實現面向物件程式設計。因此ORM的目的是使得開發人員以面向物件的思想來操作資料庫。
比如:原來insert使用的是insert into…,如果使用實現了ORM思想的持久層框架,就可以在Java程式中直接呼叫api,比如insert(User),達到操作物件即操作資料庫的效果。Hibernate框架是一個全自動的ORM持久層框架,只需要編寫POJO,在xml中定義好Pojo屬性和資料表字段的對映/對應關係,就可以在java中實現類似 insert(User)的操作。Sql語句都不用寫。但是因為效能等問題,市場佔有率越來越低
4.半自動ORM持久層框架
Mybatis框架是一個半自動的ORM持久層框架,也可以在Java中實現類似 insert(User)的操作最終操作資料庫,但是需要我們自己寫Sql語句。Mybatis是目前比較流行的Dao層框架。
第四節 自定義MyBatis框架
1.目的
-
感受一個框架的生產過程,通過這個過程幫助我們瞭解底層的一些東西,提高競爭力(軟實力)
-
注意
- 完整性和嚴謹性不能和真實的相比
- 今天的課程依然有難度
- 不影響真正Mybatis框架的使用
-
所有的Dao層框架都是以介面的形式給我們提供增刪改查的API
-
我們今天自定義Mybatis框架只完成一個API介面:selectList
2.流程
MyBatis框架的使用流程
3.快速入門
需求:查詢user表,資料儲存到List集合
4.實現步驟
-
建立物件 SqlSessionFactoryBuilder (SQL會話工廠建設者) 讀取配置檔案SqlSessionFactory
方法build(輸入流) 只需要繫結主文配置檔案
工廠的構造者物件,作用建立SQLSession物件工廠的
-
SqlSessionFactory 工廠建立
創SqlSession介面實現類物件
-
SqlSession介面實現類物件
方法,執行SQL語句
呼叫方法 select 查詢資料表
-
輸出查詢結果集
-
釋放資源
示例程式碼
步驟:
- 匯入MyBatis框架jar包
- 配置檔案
- SqlSessionFactoryBuilder,傳入位元組輸入流,構建工廠
- SqlSessionFactory,建立SqlSession
- SqlSession執行selectList方法查詢資料
匯入jar包和SqlMapConfig.xml以及UserMapper.xml配置檔案
建立pojo資料夾 放user類
public class User {
private int id;
private String username;
private String sex;
private Date birthday;
private String address;
// getXXX和SetXXX以及toString方法省略
}
建QuickStart類
public void MyBatisQuickStart(){
// 1.建立物件 SqlSessionFactory
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 使用SQLSessionFactoryBuilder方法 build(),創建出SqlSessionFactory物件
// build方法,讀取配置檔案,返回SqlSessionFactory物件,需要傳遞流物件,流物件繫結資料庫配置檔案
InputStream inputStream = QuickStart.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
// 2.SqlSessionFactory 工廠建立
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
// 工廠物件,獲取SqlSession介面實現類物件,工廠物件的方法openSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.SqlSession介面實現類物件,呼叫方法select 查詢資料表
// selectList方法引數不是SQL語句, namespace+"."+id 鎖定SQL語句 test.queryList 在SqlMapConfig.xml配置檔案中
List<User> userList = sqlSession.selectList("test.queryList");
for (User user :userList){
System.out.println(user);
}
sqlSession.close();
}
第五節 Java中的日誌元件
#log4j日誌級別如下:
#A:off 最高等級,用於關閉所有日誌記錄。
#B:fatal 指出每個嚴重的錯誤事件將會導致應用程式的退出。
#C:error 指出雖然發生錯誤事件,但仍然不影響系統的繼續執行。
#D:warn 表明會出現潛在的錯誤情形。
#E:info 一般和在粗粒度級別上,強調應用程式的執行全程。
#F:debug 一般用於細粒度級別上,對除錯應用程式非常有幫助。
#G:all 最低等級,用於開啟所有日誌記錄。
#但log4j只建議使用4個級別,優先順序從高到低分別是:
#error>warn>info>debug
log4j.rootLogger =debug,systemOut,logFile
#輸出到控制檯
log4j.appender.systemOut = org.apache.log4j.ConsoleAppender
log4j.appender.systemOut.layout = org.apache.log4j.PatternLayout
log4j.appender.systemOut.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n
log4j.appender.systemOut.Target = System.out
#輸出到檔案
log4j.appender.logFile = org.apache.log4j.FileAppender
log4j.appender.logFile.layout = org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n
log4j.appender.logFile.File = E:/log/log4j.log
log4j.appender.logFile.Encoding = UTF-8
#將日誌輸記錄到MySQL資料庫
#log4j.appender.logDB = org.apache.log4j.jdbc.JDBCAppender
#log4j.appender.logDB.layout = org.apache.log4j.PatternLayout
#log4j.appender.logDB.Driver = com.mysql.jdbc.Driver
#log4j.appender.logDB.URL = jdbc:mysql://localhost:3306/log4j?characterEncoding=utf-8
#log4j.appender.logDB.User = root
#log4j.appender.logDB.Password = root
#log4j.appender.logDB.Sql = INSERT INTO t_log4j(project_name,create_date,level,category,file_name,thread_name,line,all_category,message)values('mybatis','%d{yyyy-MM-ddHH:mm:ss}','%p','%c','%F','%t','%L','%l','%m')
第六節 MyBatis配置檔案詳解
1.SqlMapperConfig.xml
enviroments配置資料來源環境 執行環境 可配置多個
default = "development" 預設,值 = development 開發環境
-
default資料來源開關
-
environment具體資料來源環境,可以配置多個
id 不同作用不同
- id = "development" id 唯一的屬性 值=id = "development" 開發環境
- id = "product" 生產環境 互動給使用者使用
- id = "test" 測試環境 例如測試員測試
-
transactionManager事務管理器
-
datasource資料來源
<!--配置-->
<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://127.0.0.1:3306/test?characterEncoding=utf8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
<!--測試環境資料來源 -->
<environment id="test">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
<!-- 生產環境資料來源-->
<environment id="produce">
<!--
事務管理器
type="JDBC" 當前MyBatis事務管理,使用的是JDBC的事務
Connection介面方法 commit rollback
type="MANAGERED" 不管理事務,交給其他框架管理
-->
<transactionManager type="JDBC" />
<!--
資料來源
type="POOLED" 使用資料庫連線池
type="UNPOOLED" 不使用連線池
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="UserMapper.xml" />
</mappers>
</configuration>
2.MyBatis框架的CRUD
1.根據id查詢使用者
- SqlMapperConfig.xml
<mappers>
<!-- 配置User表SQL語句 -->
<mapper resource="sqlmapper/UserMapper.xml" />
</mappers>
- UserMapper.xml配置
<mapper namespace="test">
<!--
test+.+id 鎖定唯一SQL語句
resultType 結果集封裝型別
parameterType 引數的資料型別
SQL語句中的取引數語法 #{基本型別 任意命名}
-->
<select id="queryUserById" parameterType="Integer" resultType="com.itheima.pojo.User">
select * from user where id=#{id}
</select>
</mapper>
-
實現步驟
- Resources獲取位元組輸入流,繫結配置檔案
- SqlSessionFactoryBuilder構建工廠
- SqlSessionFactory建立SqlSession物件
- SqlSession物件方法selectOne執行查詢
public class MyBatisCRUD {
/**
* 框架:查詢資料表user,根據主鍵查詢
* */
public static void main(String[] args) throws IOException {
testQueryUserById();
}
public static void testQueryUserById() throws IOException {
// 1.SqlSessionFactoryBuilder
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// MyBatis框架提供類,Resource靜態方法 getResourceAsStream() 底層封裝的就是載入器,中的流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
// 2.建立SqlSession介面的實現類物件
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.方法,執行SQL語句
// selectOne(namespace +"."+id 鎖定唯一SQL)方法,查詢結果一個物件
User user = sqlSession.selectOne("test.queryUserById",3);
System.out.println(user);
sqlSession.close();
}
}
配置UserMapper.xml
<!--
配置,主鍵查詢的SQL語句,標籤 select
id具有唯一性
查詢是有結果集
標籤中屬性 resultType:配置結果集的型別
SQL語句有引數的
標籤中屬性 parameterType:SQL語句的引數型別
-->
<select id="queryUserById" resultType="com.zhuxu.pojo.User" parameterType="Integer">
<!--
SQL語句
MyBatis配置SQL語句,引數不能寫問好
取引數 #{引數名}
引數名,如果只有一個引數,基本型別及其包裝類和String,任意
-->
select * from user where id = #{id}
</select>
2.根據使用者名稱模糊查詢
框架:查詢資料表user,根據使用者名稱模糊查詢
大量的重複性程式碼:程式碼壞味道
共性抽取:
目的:SqlSession介面,執行SQL語句
每個功能不同的,SqlSession介面不能抽取
讀取配置檔案可以抽取
SqlSessionFactory sqlSessionFactory 建立SqlSession介面物件,可以抽取
工廠物件,提升為成員變數
public class MyBatisCRUD {
/**
* 框架:查詢資料表user,根據使用者名稱模糊查詢
* 大量的重複性程式碼:程式碼壞味道
* 共性抽取:
* 目的:SqlSession介面,執行SQL語句
* 每個功能不同的,SqlSession介面不能抽取
*
* 讀取配置檔案可以抽取
* SqlSessionFactory sqlSessionFactory 建立SqlSession介面物件,可以抽取
* 工廠物件,提升為成員變數
* */
private SqlSessionFactory sqlSessionFactory;
@Before
public void before() throws IOException {
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
}
// 框架:查詢資料表user,根據使用者名稱模糊查詢
@Test
public void testQueryUsername() throws IOException{
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> userList = sqlSession.selectList("test.queryUserByUsername", "'%王%'");
for (User user : userList){
System.out.println(user);
}
sqlSession.close();
}
/**
* 框架:查詢資料表user,根據主鍵查詢
* */
@Test
public void testQueryUserById() throws IOException {
/*// 1.SqlSessionFactoryBuilder
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// MyBatis框架提供類,Resource靜態方法 getResourceAsStream() 底層封裝的就是載入器,中的流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);*/
// 2.建立SqlSession介面的實現類物件
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.方法,執行SQL語句
// selectOne(namespace +"."+id 鎖定唯一SQL)方法,查詢結果一個物件
User user = sqlSession.selectOne("test.queryUserById",3);
System.out.println(user);
sqlSession.close();
}
}
UserMapper.xml配置檔案
<mapper namespace="test">
<!--
配置,資料表user模糊查詢
使用者名稱模糊查詢
SQL語句引數
${引數名} 寫引數名字固定寫為value
-->
<select id="queryUserByUsername" resultType="com.zhuxu.pojo.User" parameterType="String">
select * from user where username like ${value}
</select>
3.#{}和${} 獲取引數的區別
能用#{}不用${}
使用#的原理是 引數編譯為 ? 佔位符,更快更高效,框架底層使用的是JDBC中的介面 PreparedStatement
$的原理是拼接方式
select * from user where username like #{value}
--運算時為
select * from user where username like ? '%王%'
select * from user where username like ${value}
--運算時為
select * from user where username like '%王%'
4.新增使用者
使用
selectKey 標籤體中會在執行一次SQL語句
新增操作:insert標籤中,子標籤
屬性:
order = "after或者before" 獲取主鍵,是在SQL語句之前,還是之後執行
resultType 獲取逐漸的結果資料型別
keyProperty 屬性,查詢後的值放在哪裡 pojo物件的屬性中
<selectKey order="AFTER" resultType="Integer" keyProperty="id">
<!--新增資料獲取最新的主鍵-->
select last_insert_id ()
</selectKey>
5.修改和刪除使用者
修改
實現步驟
- Resources獲取位元組輸入流,繫結配置檔案
- SqlSessionFactoryBuilder構建工廠
- SqlSessionFactory建立SqlSession物件
- SqlSession物件方法update | delete 更新資料
- 提交事務
UserMapper.xml配置檔案中
<!--
配置更新資料,標籤update 修改資料
-->
<update id="updateUserById" parameterType="com.zhuxu.pojo.User">
update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address} where id = #{id}
</update>
<!--
配置刪除資料
-->
<delete id="deleteUserById" parameterType="Integer">
delete from user where id = #{id}
</delete>
java類
private SqlSessionFactory sqlSessionFactory;
@Before
public void before() throws IOException {
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
}
@Test
/*實現更新資料*/
public void testUpdateUserById(){
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setId(7);// 要修改的主鍵
user.setUsername("大橋");
user.setSex("女");
user.setBirthday(new Date(0));
user.setAddress("益州");
int row = sqlSession.update("test.updateUserById", user);
sqlSession.commit();
System.out.println(row);
sqlSession.close();
}
// 刪除資料
@Test
public void testDeleteUserById(){
SqlSession sqlSession = sqlSessionFactory.openSession();
int row = sqlSession.delete("test.deleteUserById", 7);
sqlSession.commit();
sqlSession.close();
System.out.println(row);
}
6.原始dao層開發方式
- 實現步驟
- 定義dao層介面
- 定義dao層介面實現類
public interface UserDao {
User queryUserById(Integer id);
}
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User queryUserById(Integer id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.queryUserById", id);
sqlSession.close();
return user;
}
}
@Test
public void userTest() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
User user = userDao.queryUserById(1);
System.out.println(user);
}
7.動態代理技術
原理:
利用反射技術
不修改原始碼的情況下,增強功能
java.lang.reflect.Proxy 動態代理類
定義一個Mapper介面,這個介面其實和我們UserDao介面是一樣的,從Mybatis框架中拿到一個代理物件(代理的是這個Mapper介面),通過代理物件呼叫介面當中的方法完成業務。
傳統dao開發方式中的實現類其實起了一個連線、承上啟下的作用,連線了介面和xml對映檔案,效果就是呼叫介面方法時能夠找到xml對映檔案。
- Mapper動態代理開發遵從的規範
- sql對映檔案的namespace必須和mapper介面的全限定類名保持一致
- mapper介面的介面方法名必須和xml中的sql語句id保持一致
- mapper介面的介面方法形參型別必須和sql語句的輸入引數型別保持一致
- mapper介面的介面方法返回型別必須和sql語句的resultType保持一致
小結
MyBatis動態代理開發(以後都是用的方式)簡化開發
限制:
-
dao層包名,修改為mapper
定義介面 UserMapper,查詢所有資料的方法(抽象)
MyBatis框架,自動為我們生成介面實現類物件
-
UserMa.xml配置檔案,配置的是user表下的SQL語句
配置檔案,必須和介面在同一目錄下
-
配置檔案中的屬性 namespace的屬性值必須和介面的全類名一致
-
介面中的方法名,必須和SQL語句標籤的id值相同
引數和返回值都必須相同
-
XXXMapper.xml配置檔案的路徑不要寫錯
示例程式碼:
SqlMapConfig.xml配置檔案
<mappers>
<!--
路徑寫法:動態代理開發
配置檔案xml和介面在一個目錄下
-->
<mapper resource="com/zhuxu/mapper/UserMapper.xml" />
</mappers>
UserMapper.xml配置檔案
<mapper namespace="com.zhuxu.mapper.UserMapper">
<!--配置查詢所有的user表資料-->
<select id="queryUser" resultType="com.zhuxu.pojo.User">
select * from user
</select>
</mapper>
UserMapper介面
public interface UserMaper{
/**
* 查詢所有資料表user的介面
* */
List<User> queryUser();
}
實現類
public class MyBatisProxy {
private SqlSessionFactory sqlSessionFactory;
@Before
public void before() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
}
@Test
/*
* 動態代理方式,代理的是mapper包下的介面
* */
public void testQueryUser(){
SqlSession sqlSession = sqlSessionFactory.openSession();
// SqlSession介面的方法 getMapper()
/*
* 引數是代理的介面的class檔案物件
* 返回值就是代理介面的實現類物件
*
* UserMapper介面的實現類
* */
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.queryUser();
for (User user:userList){
System.out.println(user);
}
sqlSession.close();
}
}
1.主鍵查詢
UserMapper.xml配置檔案
<!--配置主鍵查詢-->
<select id="queryUserById" parameterType="Integer" resultType="com.zhuxu.pojo.User">
select * from user where id = #{id}
</select>
UserMapper介面
public interface UserMaper{
/**
* 根據主鍵查詢
* */
User queryUserById(Integer id);
}
實現類
/**
* 動態代理方式,代理mapper包下的介面
* 主鍵查詢
* */
@Test
public void testQueryById(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.queryUserById(6);
System.out.println(user);
sqlSession.close();
}
2.新增資料
注意 使用註解開發不需要寫UserMapper.xml配置檔案
UserMapper.xml配置檔案
<!--配置新增-->
<insert id="saveUser" parameterType="com.zhuxu.pojo.User">
insert into user values (null ,#{username},#{sex},#{birthday},#{address})
</insert>
UserMapper介面
public interface UserMaper{
/**
* 新增資料
* */
// 註解開發
// @Insert("insert into user values (#{id} ,#{username},#{sex},#{birthday},#{address})")
int saveUser(User user);
}
實現類
/**
* 動態代理方式,代理mapper包下的介面
* 新增資料
* */
@Test
public void testSaveUser(){
User user = new User();
user.setId(7);
user.setUsername("安琪拉");
user.setSex("女");
user.setAddress("中國");
user.setBirthday(new Date());
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int row = userMapper.saveUser(user);
sqlSession.commit();
System.out.println(row);
sqlSession.close();
}
7.全域性properties配置
配置標籤,引用外部的properties檔案
實用價值不大
db.properties配置檔案
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
SqlMapConfig.xml配置檔案
<environment id="development">
<transactionManager type="JDBC" />
<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>
8.全域性typeAliases配置
別名 | 對映的型別 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
map | Map |
結果集資料型別定義別名,別名不區分大小寫
<typeAliases>
<!-- 為pojo物件定義別名-->
<typeAlias type="com.itheima.pojo.User" alias="user"></typeAlias>
</typeAliases>
<!-- 使用別名即可-->
<select id="queryUserById" parameterType="int" resultType="User">
select * from user where id=#{id}
</select>
掃描所有pojo包下的類。注意:不可以出現相同的類名
<typeAliases>
<!--<typeAlias type="com.itheima.pojo.User" alias="user"></typeAlias>-->
<!-- 自動掃描pojo包下的全部類-->
<package name="com.itheima.pojo" ></package>
</typeAliases>
9.全域性配置檔案mappers
- mappers註冊sql對映檔案的
- resource屬性載入sql對映檔案,萬能型選手(crud、原始dao、mapper動態代理)
- 針對Mapper動態代理進行一個增強(增強兩種用法)
- mapper class 單個註冊
- package 批量掃描註冊
- 以上兩種方式有規範要求
<mappers>
<!--
路徑寫法:動態代理開發
配置檔案xml和介面在一個目錄下
-->
<!--
自動掃描配置
mapper配置的xml檔案的路徑(SQL語句配置檔案)
一個數據表對應一個xml
mapper標籤的屬性 resource="xml路徑"
package標籤的屬性 name= “包名”
<package name="com.zhuxu.mapper"></package>
框架自動掃描配置包下的xml檔案
-->
<package name="com.zhuxu.mapper"></package>
<!--<mapper resource="com/zhuxu/mapper/UserMapper.xml" />-->
</mappers>
10.MyBatis輸入引數型別
pojo包裝型別,一個pojo類中,包含了另一個pojo類。
public class QueryVo {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
public interface UserMapper {
User queryUserById(Integer id);
List<User> queryUserByQueryVo(QueryVo queryVo);
}
@Test
public void userMapperQueryVo(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
QueryVo queryVo = new QueryVo();
User user = new User();
user.setUsername("%王%");
queryVo.setUser(user);
List<User> list = mapper.queryUserByQueryVo(queryVo);
for(User u :list){
System.out.println(u);
}
sqlSession.close();
}
<select id="queryUserByQueryVo" resultType="user" parameterType="queryvo">
select * from user where username like #{user.username}
</select>
11.MyBatis手動對映
OrdersMapper介面
public interface OrdersMapper {
/**
* 查詢訂單的全部資料
*/
List<Orders> queryOrders();
}
配置檔案
<!--屬性值,必須和介面的全類名一致-->
<mapper namespace="com.zhuxu.mapper.OrdersMapper">
<!--
配置查詢所有訂單的SQL
查詢需要使用自己配置的對映
select 標籤屬性resultMap,屬性值,請寫手動對映標籤resultMap的id值
-->
<select id="queryOrders" resultType="orders" resultMap="ordersResultMap">
select * from orders
</select>
<!--
手動對映,手動配置pojo物件的屬性名和資料表的列名resultMap
屬性:id=“” 唯一性
type 結果型別,pojo物件
-->
<resultMap id="ordersResultMap" type="orders">
<!--配置的就是資料表的列和pojo物件成員變數的對應關係-->
<!--
id配置的是主鍵
columns列名
property pojo 物件屬性名
-->
<id column="id" property="id"></id>
<!--配置其他列-->
<result column="user_Id" property="userId"></result>
<result column="number" property="number"></result>
<result column="createrime" property="createtime"></result>
<result column="note" property="note"></result>
</resultMap>
</mapper>
實現類
/**
* 動態代理,代理的介面是一個OrdersMapper介面
*/
@Test
public void testQueryOrders(){
SqlSession sqlSession = sqlSessionFactory.openSession();
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
List<Orders> ordersList = ordersMapper.queryOrders();
for (int i = 0; i < ordersList.size(); i++) {
Orders orders = ordersList.get(i);
System.out.println(orders);
}
}