Mybatis是一個優秀持久層框架,提供了對數據庫的一系列操做(增刪改查)。Mybatis能夠避免重複的寫JDBC代碼,讓咱們以較少的代碼實現對數據庫的操做,從而提升開發效率。Mybatis的特色是持久層(Dao)零實現,即只須要寫接口,不須要寫實現類。java
Resources:資源類,用於讀取總配置文件
SqlSessionFactoryBuilder:會話工廠構造類,經過讀取的總配置文件構建會話工廠
SqlSessionFactory:會話工廠
SqlSession:會話,就是操做數據庫的操做類mysql
--得到數據庫鏈接
第一步:導入jar包
第二步:建立主配置文件(文件名推薦寫爲:mybatis-config.xml)
第三步:建立一個MybatisUtils工具類,(得到操做對象)
--需求:插入數據到數據庫
第四步:建立一個映射接口
第五步:建立一個映射文件(.xml。文件名以接口名一致)
第六步:在主配置文件加載映射文件。
第七步:編寫測試插入數據代碼git
下載地址:https://github.com/mybatis/mybatis-3github
<?xml version="1.0" encoding="UTF-8" ?> <!-- dtd約束 --> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <!-- 根元素: 用於配置mybatis --> <configuration> <!-- 配置mybatis的運行環境 ,能夠配置多個環境,可是一次只能使用一個 default屬性 : 當前使用的環境 ,使用下面環境的id 便可 --> <environments default="mysql"> <!-- 環境配置 id 屬性,就是當前環境的表示 --> <environment id="mysql"> <!-- 配置MyBatis事務管理器 type屬性 : 事物類型 JDBC 使用事務(正常提交commit,異常回滾事務 rollback) 默認 MANAGED : 不使用事務 --> <transactionManager type="JDBC"/> <!-- 配置MyBatis的數據源 type : 配置鏈接池 POOLED :mybatis內置的一個鏈接池(默認) 後期都交給spring管理了,配置 dbcp鏈接池,阿里巴巴的 druid鏈接池 --> <dataSource type="POOLED"> <!-- 鏈接數據庫的操做 --> <!-- 數據庫驅動 --> <property name="driver" value="com.mysql.jdbc.Driver"/> <!-- 鏈接數據庫的url --> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> <!-- 鏈接數據庫帳號 --> <property name="username" value="root"/> <!-- 鏈接數據庫密碼 --> <property name="password" value="1234"/> </dataSource> </environment> </environments> <!-- 配置映射文件 --> <mappers> <!-- 配置包掃描映射文件 --> <!-- <package name=""/> --> <!-- 配置單個映射文件 --> <mapper resource="org/mybatis/example/BlogMapper.xml"/> </mappers> </configuration>
import java.io.InputStream; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class MyBatisUtil { private MyBatisUtil() { } //SqlSessionFactory 會話工廠對象 private static SqlSessionFactory factory; //類加載到JVM中就立馬執行static代碼塊,而且只會執行一次 static { //資源文件 String resource = "mybatis-config.xml"; //jdk1.7之後在try的圓括號內部建立的資源可以被自動釋放/關閉 try(InputStream inputStream = Resources.getResourceAsStream(resource)) { //建立SqlSessionFactory 對象 factory = new SqlSessionFactoryBuilder().build(inputStream); } catch (Exception e) { e.printStackTrace(); } } /** * 建立SqlSession對象 * @return SqlSession對象 */ public static SqlSession openSession() { //建立Session對象 SqlSession session = factory.openSession(); return session; } }
public class User { private Integer id; private String name; private String password; private Integer age; public User() { super(); } public User(Integer id, String name, String password, Integer age) { super(); this.id = id; this.name = name; this.password = password; this.age = age; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", password=" + password + ", age=" + age + "]"; } }
package cn.mybatis.mapper; import cn.mybatis.pojo.User; /* * 使用MyBatis的動態代理開發編寫代碼遵循四個原則 * 1.映射文件的namespace命名空間的值必須是對應接口的全限定名(包名+類名) 2.映射文件的對應功能 id值必須等於映射接口中方法的名稱 3.映射文件的參數類型必須和接口中方法的參數類型一致 4.映射文件查詢的返回結果類型必須和接口的方法的返回數據類型一致, DML操做返回的受影響的行數,除外 */ public interface UserMapper { int insertUserInfo(User u); }
<?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"> <!-- 配置映射 namespace : 命名空間(和對應映射的接口的 全限定名同樣) 通俗的講就是給當前映射文件的惟一標識:起一個惟一的名字 --> <mapper namespace="cn.mybatis.pojo.UserMapper"> <!-- 新增操做 id: 當前功能的惟一標識,和接口方法同名 parameterType : 參數的類型 useGeneratedKeys:是否返回數據庫生成的主鍵。默認爲false keyProperty : 數據庫主鍵對應java的pojo對象的屬性 keyColumn : 數據表的主鍵列名 --> <insert id="insertUserInfo" parameterType="User" useGeneratedKeys="true" keyProperty="id" keyColumn="id" ></insert> </mapper>
@Test public void testInsert() throws Exception { //1.建立SqlSession操做對象 SqlSession session = MyBatisUtil.openSession(); //2.建立UserMapper接口的代理對象 UserMapper userMapper = session.getMapper(UserMapper.class); //3.建立用戶對象 User user = new User(null, "喬峯", "qf", 30); //4.執行UserMapper的插入操做 userMapper.insertUserInfo(user); //5.提交事務 session.commit(); //6.關閉session session.close(); }
MyBatis的配置文件使用dtd約束,若是在沒有聯網的狀況想,默認開發者在使用時沒有提示,這樣不方便開發者編寫代碼。經過配置約束文件可以讓xml文件編寫代碼有提示
1.聯網
2.手動管理DTD約束文件spring
log4j是一個日誌輸出框架,就是用於輸出日誌的。Mybatis的日誌輸出是經過Log4J輸出的。主流框架大部分都是Log4j輸出的。Spring框架也能夠經過Log4j輸出日誌!
Log4j提供了強大的日誌輸出的自定義功能。
1.經過級別輸出日誌 (調試、信息、警告、錯誤、致命異常)
2.能夠指定輸出到控制檯,以及輸出到文件。
3.能夠設置輸出的日誌格式
因此學習LOG4J.須要學會自定義配置LOG4J的輸出格式以及輸出等級 sql
下載地址:http://logging.apache.org/log4j/1.2/數據庫
導入jar包而後在src下建立一個log4j.propertis文件(文件名必須爲log4j.propertis)apache
# Global logging configuration log4j.rootLogger=ERROR, stdout # MyBatis logging configuration... # log4j.logger.org.mybatis.example.BlogMapper=TRACE # 前綴(log4j.logger)+點(.)須要記錄日誌的命名空間 = 日誌級別 log4j.logger.cn.mybatis.mapper=TRACE # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
<!-- 單行查詢 resultType : 查詢結果對應的封裝的返回類型 --> <select id="selectByUserId" parameterType="integer" resultType="cn.mybatis.pojo.User"> select * from user where id = #{id} </select>
@Test public void testFindById() throws Exception { //1.建立SqlSession操做對象 SqlSession session = MyBatisUtil.openSession(); //2.建立UserMapper接口的代理對象 UserMapper userMapper = session.getMapper(UserMapper.class); //3.執行單行查詢操做 User user = userMapper.selectByPrimaryKey(1); System.out.println(user); // 4.關閉session session.close(); }
<!-- 多行查詢 resultType : 不管是多行查詢仍是單行查詢,返回的結果類型都是對應的JavaBean的類型 --> <select id="selectAll" resultType="cn.mybatis.pojo.User"> select * from user </select>
@Test public void testFindAll() throws Exception { SqlSession session = MyBatisUtil.openSession(); // 建立UserMaper的代理對象 UserMapper mapper = session.getMapper(UserMapper.class); // 3.執行多行查詢 List<User> users = mapper.selectAll(); for (User user : users) { System.out.println(user); } // 4.關閉session session.close(); }
<!-- 刪除操做 --> <delete id="deleteById" parameterType="integer"> delete from user where id = #{id} </delete>
// 刪除操做 @Test public void testDelete() throws Exception { // 1.建立SqlSession操做對象 SqlSession session = MyBatisUtil.openSession(); // 2.建立UserMapper接口的代理對象 UserMapper userMapper = session.getMapper(UserMapper.class); // 3.執行UserMapper的插入操做 userMapper.deleteById(3); // 4.提交事務 session.commit(); // 5.關閉session session.close(); }
<!-- 修改操做 --> <update id="updateByUserId" parameterType="cn.mybatis.pojo.User"> update user set name = #{name},password = #{password},age = #{age} where id = #{id} </update>
// 修改操做 @Test public void testUpdate() throws Exception { // 1.建立SqlSession操做對象 SqlSession session = MyBatisUtil.openSession(); // 2.建立UserMapper接口的代理對象 UserMapper userMapper = session.getMapper(UserMapper.class); // 3.建立用戶對象 User user = new User(2, "李四", "dy", 25); // 4.執行UserMapper的插入操做 userMapper.updateUserInfo(user); // 5.提交事務 session.commit(); // 6.關閉session session.close(); }
MyBatis的查詢結果集都是自動映射封裝的,單行查詢將數據庫一條數據封裝成對應的Java對象。多行查詢,先將每一行封裝成對象,再將每一個對象添加到集合中,最後返回一個List集合對象。可是這必須保證查詢結果集和pojo對象的屬性名相同,不然沒法自動封裝。那麼如何實現查詢結果集名稱和pojo對象屬性不一樣的映射封裝?
方法:使用手動映射封裝 <ResultMap>標籤安全
<?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"> <!-- 映射配置 namespace : 命名空間,通俗講,每一個映射文件惟一的標識名稱 --> <mapper namespace="cn.mybatis.mapper.UserMapper"> <!-- resultType : 自動映射 resultMap : 手動映射,值 自定義對應手動映射標籤的 id的值 注意:自動映射和手動映射二選一,不能同時使用 --> <select id="findByUserId" parameterType="Integer" resultMap="user_map"> <!-- #{} OGNL表達式語言 --> select id u_id,name u_name,password u_password ,age u_age from user where id = #{id} </select> <!-- 手動映射 type :須要手動映射的數據類型 id :惟一標識 --> <resultMap type="User" id="user_map"> <!-- 主鍵列映射 <id column="" property="" javaType="" jdbcType=""/> column :結果的列名 property:domain對象的對應的屬性名 javaType :domian對象的屬性的類型(可選,默認自動關聯) jdbcType :結果集列類型(可選,默認自動關聯) --> <id column="u_id" property="id" javaType="Integer" jdbcType="INTEGER"/> <!-- 非主鍵列映射 <result column="" property="" javaType="" jdbcType=""/> column :結果的列名 property:domain對象的對應的屬性名 javaType :domian對象的屬性的類型(可選,默認自動關聯) jdbcType :結果集列類型(可選,默認自動關聯) --> <result column="u_name" property="name"/> <result column="u_age" property="age"/> <result column="u_password" property="password"/> </resultMap> </mapper>
<environments>:環境集標籤,就是用於配置數據庫的鏈接信息的
<environment>:用於配置具體環境參數
<transactionManager>:配置使用的事務類型,JDBC
<dataSource>:配置數據源的參數,POOLED
具體參數參看PooledDataSource的set方法
<property>:配置屬性session
<mappers>:配置映射文件信息的
<mapper class|resource>:配置具體指定的mapper文件
class:配置使用註解時指定有註解的映射接口
resource:指定映射文件
<properties>:mybatis對propertis文件的支持
<typeAliases>:用於配置別名
<typeHandlers>:用於配置自定義類型處理器.
<settings>:配置Mybatis的默認設置的.
<!ELEMENT configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)>
以上是configuration 標籤下的標籤的順序以及標籤出現的個數的聲明
根據這個聲明能夠看到順序爲:
1.properties
2.settings
3.typeAliases
4.typeHandlers
5.objectFactory
6.objectWrapperFactory
7.reflectorFactory
8.plugins
9.environments
10.databaseIdProvider
11.mappers
DTD規則文件標籤的出現的次數說明
若是聲明的標籤後?:表示出現0-1次
若是聲明的標籤後*:表示出現0-N次
若是聲明的標籤後+:表示出現1-N次
若是聲明的標籤後什麼都沒有:表示出現1次
配置了別名以後可使用別名代替限定名
MyBatis框架中有兩種別名機制,一種是自定義別名,一種是內置別名
自定義別名
<!-- 別名設置 -->
<typeAliases>
<!-- 設置單個類的別名
type :要設置別名的全限定名
alias :別名 (通常設成簡單類名)
-->
<typeAlias type="cn.mybatis.pojo.User" alias="User"/>
</typeAliases>
內置別名,即MyBatis框架自帶別名
通常開發會將單獨的數據庫鏈接字符串配置到一個獨立的 以 .properties 的配置文件中。
Mybaits框架中配置文件 的 <properties>標籤能夠讀取配置文件中的內容。並可使用${}的語法設置給框架的數據庫鏈接操做代碼。
1.在src下面建立一個db.properties數據庫鏈接配置文件
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis jdbc.username=root jdbc.password=1234
2.在mybatis-config.xml主配置文件中配置<properties>標籤讀取配置文件
<!-- 讀取db.properties數據庫配置文件,讀取之後再下面連接數據庫的配置中就可使用
${配置文件key} 獲取對應的數據庫鏈接相關信息
-->
<properties resource="db.properties"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
Mybatis默認設置了不少默認配置.有時候,咱們需求與默認的配置的參數不同,咱們就須要修改這些默認配置的參數.
經常使用的如:Mybatis已經對駱駝命名法的支持(數據庫字段名單詞間通常用_分隔,java用駝峯,開啓以後能夠自動轉換),默認是不開啓的.能夠經過mapUnderscoreToCamelCase參數設置爲true支持
<!-- 配置默認的參數 --> <settings> <!-- 默認支持駱駝命名法 --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
MyBatis的映射配置除了使用xml配置之外,還支持註解配置sql語句。MyBatis的註解開發更簡潔,只須要將對應的SQL語句的註解標註對應的功能方法上便可,直接連XxxMapper.xml映射文件均可以省略。
MyBatis提供了下面註解進行映射文件配置
@Select 查詢數據註解
@Insert 插入數據註解
@Delete 刪除數據註解
@Update 修改數據註解
@Options 選項配置
@Results 手動映射配置
@Result : @results中的具體的某一列的映射信息配置
使用註解開發要先在主配置文件中指定使用註解的接口
<!-- 映射文件的配置 -->
<mappers>
<!-- 直接配置Mapper接口,映射接口的全限定名 -->
<mapper class="cn.mybatis.mapper.UserMapper"/>
</mappers>
Mybatis默認狀況下是不支持傳入多個參數的.只能傳入一個參數.
方案1:將這些參數封裝到一個對象裏面(JavaBean/Map),再傳入.
方案2:給參數設置一個@Param註解支持,並且多參數的類型要統一
User login1(User user); User login2(Map<String, Object> map); User login3(@Param("username")String name,@Param("pwd")String password);
#{}基於JDBC的PreparedStatement類,SQL語句參數使用 ?佔位符,在運行階段動態設置參數,可是 ?不能做爲表名.
預編譯語句對象的SQL語句只能 操做 DML和DQL 語句,不能操做DDL語句
1.#{}表示設置預編譯的參數,就是?的參數,因此若是要不固定的表名不能使用#{},只能使用${}
2.${}直接把參數拼接到SQL語句中.而#{]是使用?來代替. 因此${}是不安全的.
3.${}只能得到參數池的值,而#{}能夠得到方法的參數值,也能夠得到參數池的值,若是使用${}得到參數的值,這個參數必需要加上@Param
注:若是非必要狀況,不要使用${}( ?不能做爲表名,因此若是操做的涉及表名這些非參數的 數據時,須要使用${})