Mybatis 環境搭建以實現功能,Mybatis配置內容
搭建mybatis 開發環境
1. 引入jar包
Mybatis 3.2.2.jar ojdbc5.jar log4j-1.2.17.jar(列印日誌,可以看到mybatis的具體實現)
2. 為mybatis 設定執行環境(通過配置檔案)
mybatis-config.xml
<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE
configurationPUBLIC
"-//mybatis.org//DTDConfig 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd"
<!--mybatis 的所有配置都必須定義在configureation標籤裡 -->
<configuration>
<!-- 配置mybatis執行環境。如果需要連線多個數據庫,則需要多個environments -->
<environments default="development">
<!-- 配置一個mybatis的執行環境,id屬性是這個環境的唯一標識 -->
<environment id="development">
<!-- 設定一個mybatis完成資料庫操作是事物的提交策略,
<transactionManager type="JDBC"></transactionManager>
<!-- 配置資料庫連線,type為“POOLED” 表示使用mybatis內建連線池-->
<dataSource type="POOLED">
<property name="driver"value="com.mysql.jdbc.Driver"/>
<property
name="url"value="jdbc:mysql://localhost:3306/telbook"
<property name="username"value="root"/>
<property name="password"value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 將Mybatis的配置檔案註冊在內,可以有多個 -->
<mappers>
<mapper resource="com/nyist/dao/mapper/UserDaoMapper.xml"/>
</mappers>
</configuration>
3. Mybatis 的核心類
SqlSessionFactoryBuilder : 負責載入mybatis-config.xml
SQLSessionFactory 負責構建SQLSession
SqlSession: “一次資料庫會話”,包含了多次資料庫訪問操作,相當於jdbc裡的connection
4 第一個mybatis程式
1、 新建表和實體類
2、 定義dao介面
3、 通過對映表和對映檔案實現dao介面
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTDMapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="first.MessageDao">
<!-- namespace="first.MessageDao"表示實現那個介面 -->
<insert id="insertMessage" parameterType="first.Message">
<!--id="insertMessage"實現那個方法 parameterType="first.Message" 所帶的引數是那個型別的 -->
<!-- 注意插入動作時,物件的主鍵必須得寫,但是沒有賦予,我們需要從資料庫中得到關聯的主鍵然後進行賦值 -->
<!-- <selectKeyresultType="java.lang.Integer" keyProperty="物件的主鍵(id)屬性名" order="BEFORE"></selectKey>
查詢主鍵 resultType 主鍵型別 order="BEFORE" 表示在插入資料之前進行查詢
-->
insert into Message(id,command,description,content)values(#{id},#{command},#{description},#{content})
<!-- SQL語句賦值採用#{屬性名} -->
</insert>
</mapper>
4.將對映檔案配置到mybatis-config.xml檔案中(通知mybatis,有這個檔案)
<mappers>
<mapper resource="first/MessageDaoImpl.xml"/>
<!-- 通知mybatis從src進行寫 -->
</mappers>
4. 編寫測試類
(1) 首先讀取mybatis配置檔案
Reader reader=null;
try {
reader = Resources.getResourceAsReader("mybatis-config.xml");
} catch (IOException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
(2) 然後使用讀取到的配置檔案構建會話工廠
SqlSessionFactoryBuilder ssfb=new SqlSessionFactoryBuilder();
SqlSessionFactory sf =ssfb.build(reader);
(3) 開啟一個會話
SqlSession session = sf.openSession();
(4) 得到mybatis為我們建立的介面的實現類,這樣我們就可以操作實現類完成目標
MessageDao dao = session.getMapper(MessageDao.class);
(5) 呼叫實現類的方法進行實現
最後事物提交事物關閉session.commit();
session.close();
5、
查詢功能
<select id=”介面定義的方法名” paramaterType=”方法引數的型別” resuType=”方法返回值型別,要用全類名”>
</select>
注意:mybatis 會自動將結果集中的資料封裝成指定返回值型別的物件。封裝是,將結果的欄位值設定到物件的相應屬性裡,要求結果欄位名和物件的屬性名保持一致
注意:如果我們查詢的結果不是隻有一個型別的時候,我們定義結果的時候需要使用ResultMap,具體使用如下:
如果假設現在有班級和學生,一個學生屬於一個班級,班級時學生的屬性
<!—告訴Mybatis查詢結果集合實體的對映關係(以學生為主)-->
<resultMap id=”stu” parameterTypr=”Student的全限定民”>
<!-- property=”sid” 表示的是實體類的主屬性,column=”sid”表示的是對應的Student表的sid主鍵-->
<idproperty=”sid” column=”sid”>
<result property=”sname” column=”sname”>
<!—普通屬性的設定-->
<result property=”sage” column=”sage”>
。。。。。。。
<associationproperty=”greade” javaType=”gread的全限定名”>
<idproperty=”gid” column=”gid”>
<resultproperty=”gname” column=”gname”>
</ association>
</resultMap>
6、更新操作 --mapper檔案寫法
Dao中的介面是 public voidupdataMessage(Message m)
<update id="updateMessage" parameterType="first.Message">
update message setcommand=#{command},description=#{description},content=#{content} where id=#{id}
</update>
注意:update和insert ,delete操作完成後要進行提交 session.commit()然後在進行關閉操做session.close()
6、刪除操作
Dao中的介面是 public voiddeleteMessage(int id)
7、詢表中所有的元素
Dao中的介面是public List<Message> queryMessage();
<!-- 查詢所有返回List集合 id 為方法名, resultType="first.Message"集合中一個元素的全限定名-->
<select id="queryMessage" resultType="first.Message">
select * from message
</select>
8、使用兩個引數進行對資料的查詢
<!-- 使用兩個關鍵字進行資料的查詢在宣告介面時我們需要這樣設定
public MessagequeryMessageByCommend(@Param(value="command")Stringcommand,@Param(value="description")String description);
使用@Param(value="command")進行對後面的形參進行定義,從而可以使得下面的select 語句
command=#{command} anddescription=#{description}
如果不是這樣的話那麼無法識別報錯
-->
<select id="queryMessageByCommend" parameterType="java.lang.String" resultType="first.Message">
select * from message where command=#{command} anddescription=#{description}
</select>
9、
} 如果在sql中包含> <,sql解析時,特殊符號會發生轉義。
} 解決方案1:使用<![CDATA[….]]> 塊
}
} 解決方案2 :使用轉義字元 > 代替> < 代替 <
}
MyBatisUtil工具類的封裝
1. InputStreamis = Resources.getResourceAsStream("mybatis-config.xml");
為了程式的效率 靜態程式碼塊當中
2.SqlSessionFactory :建立sqlsession
SqlSessionFactory: 重量級資源(功能強大、記憶體佔用多) 每一個應用只建立一個物件 執行緒安全
靜態程式碼塊中
3. SqlSsession
3.1openSqlSession() 執行緒繫結 close remove
3.2 控制事務 commit|rollback
3.3 建立DAO介面實現
mybatis-config 補充:
1. 配置內容引數化 (將配置檔案中經常修改的內容 再次提取)
<properties resource="jdbc.properties"></properties>
<propertyname="driver" value="${driver}"/>
<propertyname="url" value="${url}"/>
<propertyname="username" value="${username}"/>
<propertyname="password" value="${password}"/>
2. 起別名
<typeAliases>
<typeAliasalias="User" type="com.mybatis.User"/>
</typeAliases>
resultMap 查詢結果對映對應關係
資料庫和Entity 之間 屬性對應關係 對應關係取決於需求 resultMap
<resultMaptype="User" id="User1">
<idproperty="id" column="id"/>
<resultproperty="username" column="name"/>
<resultproperty="password" column="password"/>
</resultMap>
<selectid="queryUser" parameterType="int"resultMap="User1">
select* from t_user1 where id = #{id}
</select>
---------------------------------------------------------------------------------------------------------------
動態SQL
1.SQL片段
解決sql語句的冗餘程式碼問題
<sqlid="SELECT_T_USER1">
selectid,name,password
</sql>
<select id="queryUserById"parameterType="int" resultType="User">
<includerefid="SELECT_T_USER1"></include>
fromt_user1 where id = #{1}
</select>
2.where字句的處理
概念:在where子句中引入條件判斷,從而動態的生成where子句
<select id="queryUser"resultType="User">
<includerefid="SELECT_T_USER1"></include>
fromt_user1
<where>
<iftest="id!=null">
id=#{id}
</if>
<iftest="name!=null">
andname=#{name}
</if>
<iftest="password!=null">
andpassword=#{password}
</if>
</where>
</select>
第二種where動態sql的寫法
<trimprefix="where" prefixOverrides="and/or">
<iftest="id!=null">
id=#{id}
</if>
<iftest="name!=null">
and name=#{name}
</if>
<iftest="password!=null">
and password=#{password}
</if>
</trim>
3.修改
<update id="update"parameterType="User">
update t_user1
<set>
<iftest="name!=null">
name=#{name},
</if>
<iftest="password!=null">
password=#{password}
</if>
</set>
where id =#{id}
</update>
4.批量
<deleteid="delete">
deletefrom t_user where id in
<foreachcollection="list" open="(" item="item"separator="," close=")">
#{item}
</foreach>
</delete>
MyBatis快取(Cache)【重要】
什麼是快取
a) 啟用MyBatis的全域性快取
mybatis-config.xml額外的配置
<settings>
<settingname="cacheEnabled" value="true"></setting>
</settings>
b) 配置具體需要快取的資料
對應的Mapper檔案 加入<cache標籤
c) 實體類要做特殊處理
implementsSerializable
d) 注意:
1 只有在SqlSession關閉的時候,MyBatis才會把查詢的資料放置快取中。
2 髒資料問題 SqlSession會在事務提交的時候,自動清空快取
最佳實踐:
查詢方法 需要在呼叫完成後 關閉SqlSession 確保查詢的資料可以進行全域性快取
增刪改操作:呼叫完成後 進行事務的提交
例項搭建:
目錄:
實體:User.java
package com.nyist.entity;
public class User {
private int id;
private String username;
private String password;
public User() {
//super();
// TODO Auto-generated constructor stub
}
public User(int id, String username, String password) {
//super();
this.id = id;
this.username = username;
this.password = password;
}
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 getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
}
}
介面:
package com.nyist.dao;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.nyist.entity.User;
public interface UserDao {
public void insert(User user);
public void delete(int id);
public void update(User user);
public List<User> queryAll();
public User queryOne(int id);
//當傳遞多個引數的時候,使用@Param("") 進行標示然後使用標示在Mapper檔案中使用
public User queryByUsernameAndPassword(@Param("username")String username,@Param("password") String password);
}
jdbc.properties:資料庫配置檔案
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/telbook
jdbc.username=root
jdbc.password=123456
mybatis-config.xml Mybatis的配置檔案
<?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 的所有配置都必須定義在configureation 標籤裡 -->
<configuration>
<!-- 載入資料庫資訊 -->
<properties resource="jdbc.properties"></properties>
<!-- 配置mybatis 執行環境。如果需要連線多個數據庫,則需要多個environments -->
<environments default="development">
<!-- 配置一個mybatis的執行環境,id屬性是這個環境的唯一標識 -->
<environment id="development">
<!-- 設定一個mybatis完成資料庫操作是事物的提交策略,type屬性值為JDBC表示用JDBC的方式進行提交 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置資料庫連線,type為“POOLED” 表示使用mybatis內建連線池-->
<dataSource type="POOLED">
<!--
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/telbook"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
-->
<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>
<!-- 將Mybatis的配置檔案註冊在內,可以有多個 -->
<mappers>
<mapper resource="com/nyist/dao/mapper/UserDaoMapper.xml"/>
</mappers>
</configuration>
UserDaoMapper.xml Mapper檔案
<?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.nyist.dao.UserDao">
<!-- namespace 代表的是本檔案所實現的那個介面 -->
<insert id="insert" parameterType="com.nyist.entity.User">
<!-- insert標籤代表著插入 id 是你實現的那個介面的函式名 ,parameterType 代表的是你id 中的函式中所需要的引數,要寫全限定名 -->
<!-- <![CDATA[SQL 語句]]> 可以阻止SQL語句中的特殊字元發生轉義 -->
<![CDATA[
insert into User(id,username,password) values(#{id},#{username},#{password})
]]>
<!-- 在進行賦值的時候 #{屬性名/介面函式所帶的引數} -->
</insert>
<!-- 刪除 -->
<delete id="delete" parameterType="int">
<![CDATA[
delete from User where id = #{id}
]]>
</delete>
<!-- 修改操作 -->
<update id="update" parameterType="com.nyist.entity.User">
<![CDATA[
update User set username = #{username},password = #{password} where id = #{id}
]]>
</update>
<select id="queryAll" resultType="com.nyist.entity.User">
<![CDATA[
select id,username,password from User
]]>
</select>
<select id="queryOne" parameterType="int" resultType="com.nyist.entity.User">
<![CDATA[
select id,username,password from User where id = #{id}
]]>
</select>
<select id="queryByUsernameAndPassword" parameterType="String" resultType="com.nyist.entity.User">
<![CDATA[
select id,username,password from User where username = #{username} and password = #{password}
]]>
</select>
</mapper>
測試類:
package com.nyist.test;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
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.Test;
import com.nyist.dao.UserDao;
import com.nyist.entity.User;
public class UserTest {
private static Reader reader = null;
private static SqlSessionFactory factory = null;
static{
try {
// 讀取Mybatis 的配置檔案 mybatis-config.xml 由於是在src直接目錄中,所以沒有其他子目錄
reader = Resources.getResourceAsReader("mybatis-config.xml");
// 使用讀到的配置檔案 建立SqlSessionFactory
factory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 增加資料
*/
@Test
public void test1(){
//使用工廠 開啟會話
SqlSession session = factory.openSession();
UserDao userDao = session.getMapper(UserDao.class);
User user = new User();
user.setUsername("lisi");
user.setPassword("123456");
userDao.insert(user);
session.commit();
session.close();
}
/**
* 刪除資料
*/
@Test
public void test2(){
SqlSession session = factory.openSession();
UserDao userDao = session.getMapper(UserDao.class);
userDao.delete(8);
session.commit();
session.close();
}
@Test
public void test3(){
SqlSession session = factory.openSession();
UserDao userDao = session.getMapper(UserDao.class);
User user = new User();
user.setId(5);
user.setUsername("lisi");
user.setPassword("123456");
userDao.update(user);
session.commit();
session.close();
}
@Test
public void test4(){
SqlSession session = factory.openSession();
UserDao userDao = session.getMapper(UserDao.class);
List<User> users = userDao.queryAll();
for (User user : users) {
System.out.println(user);
}
}
@Test
public void test5(){
SqlSession session = factory.openSession();
UserDao userDao = session.getMapper(UserDao.class);
User user = userDao.queryOne(5);
System.out.println(user);
}
@Test
public void test6(){
SqlSession session = factory.openSession();
UserDao userDao = session.getMapper(UserDao.class);
User user = userDao.queryByUsernameAndPassword("zhang", "123456");
System.out.println(user);
}
}