myBatis
MyBatis 是一款優秀的持久層框架,它支持定製化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可以使用簡單的 XML 或註解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。上面一段是 mybatis 官方文檔的解釋
其實我自己覺得,看這麼多挺累的
mybatis 就是一個半自動化持久層的框架(全自動hibernate),重點是很火
優點:易學,靈活,解除sql與程序之間的耦合,提供xml 支持寫動態sql
缺點:編寫SQL語句時工作量很大,尤其是字段多、關聯表多時,更是如此。SQL語句依賴於數據庫,導致數據庫移植性差,不能更換數據庫。
下面就創建一個 最簡單的 mybatis 的項目 那個附加的東西后面再提
- mybatis需要的jar包
- 搭建全局的 mybatis-config 文件
- 配置mapper
- 配置註解
- xml 和 註解 一起配置
- xml 和 註解 配置完成後的使用方法
在操作之前得先把需要的數據庫給弄好
// 數據庫
DROP TABLE IF EXISTS `stu`;
CREATE TABLE `stu` (
`stu_id` int(11) NOT NULL AUTO_INCREMENT,
`stu_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`stu_age` int(255) NULL DEFAULT NULL,
`stu_sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`stu_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
// 實體類
package com.kz.po;
public class Stu {
private int stu_id;
private String stu_name;
private int stu_age;
private String stu_sex;
public Stu(int stu_id, String stu_name, int stu_age, String stu_sex) {
this.stu_id = stu_id;
this.stu_name = stu_name;
this.stu_age = stu_age;
this.stu_sex = stu_sex;
}
public Stu() {
}
public void setStu_id(int stu_id) {
this.stu_id = stu_id;
}
public void setStu_name(String stu_name) {
this.stu_name = stu_name;
}
public void setStu_age(int stu_age) {
this.stu_age = stu_age;
}
public void setStu_sex(String stu_sex) {
this.stu_sex = stu_sex;
}
public int getStu_id() {
return stu_id;
}
public String getStu_name() {
return stu_name;
}
public int getStu_age() {
return stu_age;
}
public String getStu_sex() {
return stu_sex;
}
@Override
public String toString() {
return "Stu{" +
"stu_id=" + stu_id +
", stu_name='" + stu_name + '\'' +
", stu_age=" + stu_age +
", stu_sex='" + stu_sex + '\'' +
'}';
}
}
- mybatis需要的jar包
mybatis-x.x.x.jar
mysql-connector-java-x.x.x.jar
- 配置全局 config
首先在mian下創建一個 resource 文件夾(並且設置文件夾爲source文件夾)
在resource文件夾下創建 mybatis-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">
<configuration>
<!-- 配置環境:可以配置多個環境,
default:配置某一個環境的唯一標識,表示默認使用哪個環境 -->
<environments default="development">
<environment id="development">
<!-- 事務的類型:jdbc -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/student?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="yjy" />
</dataSource>
</environment>
</environments>
</configuration>
- 配置Mapper
在resource 目錄下創建一個mappers文件夾,以後所有的mapper.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:命名空間,隨便寫,一般保證命名空間唯一 -->
<mapper namespace="stuMapper" >
<!-- statement,內容:sql語句。id:唯一標識,隨便寫,在同一個命名空間下保持唯一
resultType:sql語句查詢結果集的封裝類型,stu即爲數據庫中的表
-->
<select id="selectUser" resultType="com.kz.po.Stu">
select * from stu
</select>
<insert id="addUser" parameterType="com.kz.po.Stu">
insert into stu values(null,#{stu_name},#{stu_age},#{stu_sex})
<!-- 我覺得仔細讀的話應該會發現
#{ } 這裏面的值只需要放 實體類裏面的屬性就好
-->
</insert>
<update id="updateUser" parameterType="com.kz.po.Stu">
update stu set stu_name = #{stu_name} where stu_id = #{stu_id}
</update>
<delete id="delUser" parameterType="int">
delete from stu where stu_id = #{int}
</delete>
</mapper>
最後還需要 把 mapper.xml 註冊到 mybatis-config.xml 裏
<!-- 映射文件:用來配置sql語句和結果集類型等 -->
<mappers>
<mapper resource="mappers/StuMapper.xml" /> // resource的值就是mapper的位置
</mappers>
- 配置註解
首先創建一個dao層的接口
package com.kz.dao;
import com.kz.po.Stu;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
public interface StuDao {
@Select("select * from stu where stu_id = #{id} ")
public Stu stuSelectById(int id);
@Insert("insert into stu values(null,#{stu_name},#{stu_age},#{stu_sex})")
public int addStu(Stu stu);
}
// 這個註解的方式是不是感覺看了一遍就陶醉了,
// 其實xml是可以編寫動態sql 的 但這個就不行,不過方便啊
// 一會我們就來試倆個同時使用
// 穿參數魚xml方式幾乎類似
這裏和上面 xml 一樣需要在全局config裏面註冊
<!-- 映射文件:用來配置sql語句和結果集類型等 -->
<mappers>
<mapper class="com.kz.dao.StuDao" /> // class的值就是類的位置
</mappers>
這裏不需要寫 xml 是不是感覺特別爽
- 倆個一起配
首先創建 一個StuDao 接口
package com.kz.dao;
import com.kz.po.Stu;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
public interface StuDao {
@Select("select * from stu where stu_id = #{id} ")
public Stu stuSelectById(int id);
@Insert("insert into stu values(null,#{stu_name},#{stu_age},#{stu_sex})")
public int addStu(Stu stu);
public int delUser(int id);
public int updateUser(Stu stu);
// 這裏應該會發現 delUser和updateUser沒有寫註解
}
再創建一個 StuMapper.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.kz.dao.StuDao" >
<!-- namespace這裏面寫 StuDao 的接口路徑的話 那麼 這裏面就相當於 StuDao 的實現類
myBatis 會看 StuDao裏面的方法是不是有和這裏面id名字一樣的如果有就 實現,
沒有的可以自己寫註解或者加上啊,
當然也許有人會想到,如果xml裏面有addUser 那麼 StuDao 裏面也配置了註解那到
底誰的優先級大呢,,,這就不多bb了,註解的優先級大,一會可以直接去試一試
-->
<select id="selectUser" resultType="com.kz.po.Stu">
select * from stu
</select>
<insert id="addUser" parameterType="com.kz.po.Stu">
insert into stu values(null,#{stu_name},#{stu_age},#{stu_sex})
</insert>
<update id="updateUser" parameterType="com.kz.po.Stu">
update stu set stu_name = #{stu_name} where stu_id = #{stu_id}
</update>
<delete id="delUser" parameterType="int">
delete from stu where stu_id = #{int}
</delete>
</mapper>
這裏同上也是需要在全局裏面註冊的
那麼這裏註冊的時候到底是寫xml的還是dao 的呢
e...不是在xml的mapper 標籤裏面的屬性namespace設置了namespace嘛所以只需要設置xml的
<!-- 映射文件:用來配置sql語句和結果集類型等 -->
<mappers>
<mapper resource="mappers/StuMapper.xml" />
</mappers>
好啦什麼七七八八的配置就弄完了 現在 我們只需要操作就好啦
我這裏使用了單元測試 不懂的就直接在面方法裏面寫也是一樣的
import com.kz.dao.StuDao;
import com.kz.po.Stu;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class stuTest {
private SqlSession sqlSession;
@Before
public void init() throws IOException { // 單元測試會先執行這裏
// 加載 mybatis 配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
// 獲得 sqlSessionFactory
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
//獲得 sqlSession
sqlSession = build.openSession();
}
@Test
public void test1() throws IOException {
// xml 的方式 stuMapper是 namespace 的名字 .selectUser 是調用裏面id爲 namespace的實現方法
Stu stu1 = sqlSession.selectOne("stuMapper.selectUser"); // 只會返回一個數據
Stu stu2 = sqlSession.selectOne("stuMapper.selectUser",1);// 帶參數
List<Stu> stuAll = sqlSession.selectOne("stuMapper.selectUser");// 返回一個結果集
sqlSession.close();
}
@Test
public void test2() throws IOException {
// 註解的方式 註解與xml同時配置的情況下也是用這種方式
StuDao mapper = sqlSession.getMapper(StuDao.class);
int stu = mapper.addStu(new Stu(0, "小13", 18, "女"));
System.out.println(stu);
sqlSession.commit(); // 只要是關係到操作數據庫的 都需要提交數據
sqlSession.close();
}
@Test
public void test3() throws IOException{
int insert = sqlSession.insert("com.kz.dao.StuDao.addUser", new Stu(0, "小白", 18, "女"));
System.out.println(insert);
sqlSession.commit();
sqlSession.close();
}
}
好啦現在大功告成