如下內容是本身在看本書時以爲重要的地方記錄下來,一方面本身作個筆記也但願對其餘同行有幫助java
mybatis
: 是一個簡化和實現了Java數據持久層的開源框架愛,抽象和大量的jdbc冗餘代碼,提供簡單的API和數據庫加護mysql
消除大量的JDBC冗餘代碼算法
低的學習曲線spring
很好的域傳統數據庫協做sql
接收SQL語句數據庫
提供Spring框架集成apache
提供第三方緩存類庫集成緩存
引入更好的性能安全
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"> <configuration> <typeAliases> <typeAlias alias="Student" type="com.mybatis3.domain.Student" /> </typeAliases> <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://localhost:3306/test" /> <property name="username" value="root" /> <property name="password" value="admin" /> </dataSource> </environment> </environments> <mappers> <mapper resource="com/mybatis3/mappers/StudentMapper.xml" /> </mappers> </configuration>
0.1. 建立session Factory 類
package com.mybatis3.util; import java.io.*; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.*; public class MyBatisSqlSessionFactory { private static SqlSessionFactory sqlSessionFactory; public static SqlSessionFactory getSqlSessionFactory() { if(sqlSessionFactory == null) { InputStream inputStream; try { inputStream = Resources. getResourceAsStream("mybatis-config.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { throw new RuntimeException(e.getCause()); } } return sqlSessionFactory; } public static SqlSession openSession() { return getSqlSessionFactory().openSession(); } }
建立xml映射
<select id="findStudentById" parameterType="int" resultType="Student"> SELECT STUD_ID AS studId, NAME, EMAIL, DOB FROM STUDENTS WHERE STUD_ID=#{Id} </select> <insert id="insertStudent" parameterType="Student"> INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,DOB) VALUES(#{studId},#{name},#{email},#{dob}) </insert>
建立mapper接口
public interface StudentMapper { Student findStudentById(Integer id); void insertStudent(Student student); }
建立會話使用接口
SqlSession session = getSqlSessionFactory().openSession(); StudentMapper mapper = session.getMapper(StudentMapper.class); // Select Student by Id Student student = mapper.selectStudentById(1); //To insert a Student record mapper.insertStudent(student);
<?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文件 <properties resource="application.properties"> <property name="username" value="db_user" /> <property name="password" value="verysecurepwd" /> </properties> //開啓緩存 <settings> <setting name="cacheEnabled" value="true" /> </settings> //別名 <typeAliases> <typeAlias alias="Tutor" type="com.mybatis3.domain.Tutor" /> <package name="com.mybatis3.domain" /> </typeAliases> //類型處理器,註冊自定義類型 <typeHandlers> <typeHandler handler="com.mybatis3.typehandlers.PhoneTypeHandler" /> <package name="com.mybatis3.typehandlers" /> </typeHandlers> //支持配置多個數據源,設置默認環境爲開發環境 <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <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> </environment> <environment id="production"> <transactionManager type="MANAGED" /> <dataSource type="JNDI"> <property name="data_source" value="java:comp/jdbc/MyBatisDemoDS" /> </dataSource> </environment> </environments> <mappers> <mapper resource="com/mybatis3/mappers/StudentMapper.xml" /> <mapper url="file:///D:/mybatisdemo/mappers/TutorMapper.xml" /> <mapper class="com.mybatis3.mappers.TutorMapper" /> </mappers> </configuration>
以上是一個簡單的基於XML的配置
經過以上XML能夠到全部的配置:
加載properties 文件
直接默認值
<properties resource="application.properties"> <property name="jdbc.username" value="db_user" /> <property name="jdbc.password" value="verysecurepwd" /> </properties>
若是文件中定義了jdbc.username
,以上配置中的默認值會被覆蓋掉
經過佔位符
<property name="driver" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" />
開啓緩存
配置environments default="development"
實現默認環境 ,能夠配置不一樣環境
配置多數據庫實現
針對不一樣的數據庫建立不一樣sessionFactory
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory defaultSqlSessionFactory = new SqlSessionFactoryBuilder(). build(inputStream); SqlSessionFactory cartSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStre am, "shoppingcart"); reportSqlSessionFactory = new SqlSessionFactoryBuilder(). build(inputStream, "reports");
若是不指定環境id,則使用默認的環境建立
數據庫類型配置
UNPOOLED
mybatis會爲每一個數據庫建立錯誤一個新的鏈接,並關閉它。__只適用於小閨蜜數據併發__
POOLED
mybatis建立一個數據庫鏈接池,__開發環境常用__ 默認的數據庫鏈接池實現是經過`org.apache.ibatis.datasource.pooled.PooledDataSource`
JNDI
mybatis從應用服務器配置好的JNDI數據源獲取數據庫鏈接
事務管理
JDBC
是由JDBC事務管理器管理事務。 內部將經過JDBCTransactionFactory建立事務管理
MANAGED
應用服務器負責管理數據庫鏈接生命週期使用。內部使用`ManagedTranscationFactory`類來建立事務管理器
設置別名
因爲在* mapper.xml
文件中resultType
和parameterType
屬性設置要使用全限定名,可使用別名的形式簡化
<typeAliases> <typeAlias alias="Student" type="com.mybatis3.domain.Student" /> <typeAlias alias="Tutor" type="com.mybatis3.domain.Tutor" /> <package name="com.mybatis3.domain" /> </typeAliases>
也能夠不用直接設定別名,能夠設定包,而後系統自動掃描設置一個以類首字母小寫的別名
經過實體類添加註解形式實現
@Alias("") public class Student{ }
類型處理器
mubatis對一下類型實現內建處理器 :
全部基本數據類型
基本類型的包裹類型(裝箱操做對象類型)
byte[]
java.util.Date
java.sql.Date
java.sql.Time
java.sql.Timestamp
java枚舉類型
建立自定義的類型處理器,處理自定義類型
//PhoneNumber 自定義的類 public class PhoneTypeHandler extends BaseTypeHandler<PhoneNumber> { @Override public void setNonNullParameter(PreparedStatement ps, int i, PhoneNumber parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter.getAsString()); } public PhoneNumber getNullableResult(ResultSet rs, String columnName) throws SQLException { return new PhoneNumber(rs.getString(columnName)); } public PhoneNumber getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return new PhoneNumber(rs.getString(columnIndex)); } }
別忘了註冊
全局參數設定(一下是默認的,)
<settings> <setting name="cacheEnabled" value="true" /> <setting name="lazyLoadingEnabled" value="true" /> <setting name="multipleResultSetsEnabled" value="true" /> <setting name="useColumnLabel" value="true" /> <setting name="useGeneratedKeys" value="false" /> <setting name="autoMappingBehavior" value="PARTIAL" /> <setting name="defaultExecutorType" value="SIMPLE" /> <setting name="defaultStatementTimeout" value="25000" /> <setting name="safeRowBoundsEnabled" value="false" /> <setting name="mapUnderscoreToCamelCase" value="false" /> <setting name="localCacheScope" value="SESSION" /> <setting name="jdbcTypeForNull" value="OTHER" /> <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode ,toString" /> </settings>
配置mappers映射xml文件路徑
多種配置形式
<mappers> <mapper resource="com/mybatis3/mappers/StudentMapper.xml" /> <mapper url="file:///D:/mybatisdemo/app/mappers/TutorMapper.xml" /> <mapper class="com.mybatis3.mappers.TutorMapper" /> <package name="com.mybatis3.mappers" /> </mappers>
經過XML配置形式瞭解了mybatis中的各個配置屬性, 經過Java API 的配置形式也能夠實現
public class MybatisConfig{ public static SqlSessionFactory getSqlSessionFactory() { SqlSessionFactory sqlSessionFactory = null; try { DataSource dataSource = DataSourceFactory.getDataSource(); TransactionFactory transactionFactory = new JdbcTransactionFactory(); Environment environment = new Environment("development", transactionFactory, dataSource); Configuration configuration = new Configuration(environment); configuration.getTypeAliasRegistry().registerAlias("student", Student.class); configuration.getTypeHandlerRegistry().register(PhoneNumber. class, PhoneTypeHandler.class); configuration.addMapper(StudentMapper.class); //建立 sqlSessionFactory = new SqlSessionFactoryBuilder(). build(configuration); } catch (Exception e) { throw new RuntimeException(e); } return sqlSessionFactory; } }
建立datasource
public class DataSourceFactory { public static DataSource getDataSource(){ String driver = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql://localhost:3306/mybatisdemo"; String username = "root"; String password = "admin"; PooledDataSource dataSource = new PooledDataSource(driver, url, username, password); return dataSource; } //經過JNDI建立 public static DataSource getDataSource(){ String jndiName = "java:comp/env/jdbc/MyBatisDemoDS"; try{ InitialContext ctx = new InitialContext(); DataSource dataSource = (DataSource) ctx.lookup(jndiName); return dataSource; }catch(NamingException e){ throw new RuntimeException(e); } } }
mybatis中針對日誌支持的優先級:
SLF4J
Apache Commons Logging
Log4j 2
Log4j
JDK logging
調用一下方式實現
org.apache.ibatis.logging.LogFactory.useSlf4jLogging(); org.apache.ibatis.logging.LogFactory.useLog4JLogging(); org.apache.ibatis.logging.LogFactory.useLog4J2Logging(); org.apache.ibatis.logging.LogFactory.useJdkLogging(); org.apache.ibatis.logging.LogFactory.useCommonsLogging(); org.apache.ibatis.logging.LogFactory.useStdOutLogging();
經過xml的形式映射有兩種形式:
只有XML映射
定義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.mybatis3.mappers.StudentMapper"> <select id="findStudentById" parameterType="int" resultType="Student"> select stud_id as studId, name, email, dob from Students where stud_id=#{studId} </select> </mapper>
調用
public Student = findStudentById(Integer id){ SqlSession session = MybatisUtil.geSqlSession(); try{ //經過字符串的形式調用 Student student = sqlSession.selectOne("com.mybatis3.mappers.StudentMapper.findStudentById",id); } }
帶有mapper接口類形式
須要注意的點: __其名空間namespace 應該跟StudentMapper接口的徹底限定名保持一至__, __ id,parameterType,returnType 應該分別和 StudentMapper 接口中的方法名, 參數類型,返回值相對應__
mybatis 提供多種不一樣的映射語句:
INSERT
useGeneratedKeys
: 設置自增加
keyProperty
: 主鍵屬性
SELECT
UPDATE
DELETE
INSERT
經過自增加設置主鍵
<insert id="insertStudent" parameterType="Student" useGeneratedKeys="true" keyProperty="studId"> INSERT INTO STUDENTS(NAME, EMAIL, PHONE) VALUES(#{name},#{email},#{phone}) </insert>
針對支持序列生成主鍵值
<insert id="insertStudent" parameterType="Student"> <selectKey keyProperty="studId" resultType="int" order="BEFORE"> SELECT ELEARNING.STUD_ID_SEQ.NEXTVAL FROM DUAL </selectKey> INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL, PHONE) VALUES(#{studId},#{name},#{email},#{phone}) </insert> //使用觸發器 <insert id="insertStudent" parameterType="Student"> INSERT INTO STUDENTS(NAME,EMAIL, PHONE) VALUES(#{name},#{email},#{phone}) <selectKey keyProperty="studId" resultType="int" order="AFTER"> SELECT ELEARNING.STUD_ID_SEQ.CURRVAL FROM DUAL </selectKey> </insert>
對於 List, Collection, Iterable類型,返回 java.util.ArrayList
對於Map 類型,返回 java.util.HashMap
對於Set 類型: 返回 java.util.HashSet
對於SortedSet類型: 返回java.util.TreeSet
方式1: 使用點語法進行映射
public class Student { private Integer studId; private String name; private String email; private Address address; //一個地址對象, 每一個學生對應一個地址 } <resultMap type="Student" id="StudentWithAddressResult"> <id property="studId" column="stud_id" /> <result property="name" column="name" /> <result property="email" column="email" /> <result property="phone" column="phone" /> <result property="address.addrId" column="addr_id" /> <result property="address.street" column="street" /> <result property="address.city" column="city" /> <result property="address.state" column="state" /> <result property="address.zip" column="zip" /> <result property="address.country" column="country" /> </resultMap> <select id="selectStudentWithAddress" parameterType="int" resultMap="StudentWithAddressResult"> SELECT STUD_ID, NAME, EMAIL, A.ADDR_ID, STREET, CITY, STATE, ZIP, COUNTRY FROM STUDENTS S LEFT OUTER JOIN ADDRESSES A ON S.ADDR_ID=A.ADDR_ID WHERE STUD_ID=#{studId} </select> //使用了左外鏈接來查詢
方式2: 使用嵌套結果 ResultMap
進行映射
引入其餘文件定義的ResultMap
__使用標籤`association` 引入__
<resultMap type="Address" id="AddressResult"> <id property="addrId" column="addr_id" /> <result property="street" column="street" /> <result property="city" column="city" /> </resultMap> <resultMap type="Student" id="StudentWithAddressResult"> <id property="studId" column="stud_id" /> <result property="name" column="name" /> <result property="email" column="email" /> <association property="address" resultMap="AddressResult" /> </resultMap>
查詢語句
<select id="findStudentWithAddress" parameterType="int" resultMap="StudentWithAddressResult"> SELECT STUD_ID, NAME, EMAIL, A.ADDR_ID, STREET, CITY, STATE, ZIP, COUNTRY FROM STUDENTS S LEFT OUTER JOIN ADDRESSES A ON S.ADDR_ID=A.ADDR_ID WHERE STUD_ID=#{studId} </select>
自己內部嵌套
<resultMap type="Student" id="StudentWithAddressResult"> <id property="studId" column="stud_id" /> <result property="name" column="name" /> <result property="email" column="email" /> <association property="address" javaType="Address"> <id property="addrId" column="addr_id" /> <result property="street" column="street" /> <result property="city" column="city" /> <result property="state" column="state" /> <result property="zip" column="zip" /> <result property="country" column="country" /> </association> </resultMap>
方式3: 使用其那套select查詢語句
每個對應的對象實現本身的查詢語句
<resultMap type="Address" id="AddressResult"> <id property="addrId" column="addr_id" /> <result property="street" column="street" /> </resultMap> //查詢語句 <select id="findAddressById" parameterType="int" resultMap="AddressResult"> SELECT * FROM ADDRESSES WHERE ADDR_ID=#{id} </select> <resultMap type="Student" id="StudentWithAddressResult"> <id property="studId" column="stud_id" /> <association property="address" column="addr_id" select="findAddressById" /> </resultMap> <select id="findStudentWithAddress" parameterType="int" resultMap="StudentWithAddressResult"> SELECT * FROM STUDENTS WHERE STUD_ID=#{Id} </select>
注意嵌套查詢:經過association
將另外一個對象的查詢語句嵌套進入, 而且此標籤好像只能用於查詢
一對一查詢中內部的對象在數據庫中對應的都是一個Id或者惟一標識值,因此此處底部的嵌套xml中的值都是id屬性的
使用<collection>
元素將 一對多類型的結果 映射到 一個對象集合上
使用嵌套對象形式顯示
public class Tutor { private Integer tutorId; private String name; private String email; private Address address; private List<Course> courses; / setters & getters } <resultMap type="Tutor" id="TutorResult"> <id column="tutor_id" property="tutorId" /> <result column="tutor_name" property="name" /> <result column="email" property="email" /> <collection property="courses" resultMap="CourseResult" /> </resultMap> <select id="findTutorById" parameterType="int" resultMap="TutorResult"> SELECT T.TUTOR_ID, T.NAME AS TUTOR_NAME, EMAIL, C.COURSE_ID, C.NAME, DESCRIPTION, START_DATE, END_DATE FROM TUTORS T LEFT OUTER JOIN ADDRESSES A ON T.ADDR_ID=A.ADDR_ID LEFT OUTER JOIN COURSES C ON T.TUTOR_ID=C.TUTOR_ID WHERE T.TUTOR_ID=#{tutorId} </select>
使用嵌套語句實現
<resultMap type="Tutor" id="TutorResult"> <id column="tutor_id" property="tutorId" /> <result column="tutor_name" property="name" /> <result column="email" property="email" /> <association property="address" resultMap="AddressResult" /> <collection property="courses" column="tutor_id" select="findCoursesByTutor" /> </resultMap> <select id="findTutorById" parameterType="int" resultMap="TutorResult"> SELECT T.TUTOR_ID, T.NAME AS TUTOR_NAME, EMAIL FROM TUTORS T WHERE T.TUTOR_ID=#{tutorId} </select> <select id="findCoursesByTutor" parameterType="int" resultMap="CourseResult"> SELECT * FROM COURSES WHERE TUTOR_ID=#{tutorId} </select>
注意: 嵌套 Select 語句查詢會致使 N+1 選擇問. 首先,主查詢將會執行(1 次),對於主 查詢返回的每一行,另一個查詢將會被執行(主查詢 N 行,則此查詢 N 次)。對於 大型數據庫而言,這會致使不好的性能問題。
mybatis 提供: <if>
,<choose>
,<where>
,<foreach>
,<trim>
進行構造動態SQL
<select id="searchCourses" parameterType="hashmap" resultMap="CourseResult"></select> SELECT * FROM COURSES WHERE TUTOR_ID= #{tutorId} <if test="courseName != null"> AND NAME LIKE #{courseName} </if> </select>
當if中test條件成立時, 纔會添加if中的內容到SQL語句中
<select id="searchCourses" parameterType="hashmap" resultMap="CourseResult"> SELECT * FROM COURSES <choose> <when test="searchBy == 'Tutor'"> WHERE TUTOR_ID= #{tutorId} </when> <when test="searchBy == 'CourseName'"> WHERE name like #{courseName} </when> <otherwise> WHERE TUTOR start_date >= now() </otherwise> </choose> </select>
__mybatis計算<choose>
測試條件的值,且使用第一個值爲true的子句, 若是沒有條件爲true,則使用<otherwise> 內的子句。
<select id="searchCourses" parameterType="hashmap" resultMap="CourseResult"> SELECT * FROM COURSES <where> <if test=" tutorId != null "> TUTOR_ID= #{tutorId} </if> <if test="courseName != null"> AND name like #{courseName} </if> <if test="startDate != null"> AND start_date >= #{startDate} </if> <if test="endDate != null"> AND end_date <= #{endDate} </if> </where> </select>
<select id="searchCourses" parameterType="hashmap" resultMap="CourseResult"> SELECT * FROM COURSES <trim prefix="WHERE" prefixOverrides="AND | OR"> <if test=" tutorId != null "> TUTOR_ID= #{tutorId} </if> <if test="courseName != null"> AND name like #{courseName} </if> </trim> </select>
<select id="searchCoursesByTutors" parameterType="map" resultMap="CourseResult"> SELECT * FROM COURSES <if test="tutorIds != null"> <where> <foreach item="tutorId" collection="tutorIds"> OR tutor_id=#{tutorId} </foreach> </where> </if> </select>
存儲枚舉名
默認狀況下mybatis支持開箱方式持久化枚舉類型屬性, 其經過`EnumTypeHandler`來處理枚舉類型與Java類型對應 默認是使用字符串進行存儲的,數據表中對應的是枚舉對應的字符串
存儲枚舉對應的int類型值
須要將枚舉對應的handler修改成如下類
<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="com.mybatis3.domain.Gender"/>
__仍是建議使用默認的形式的,使用順序的若是改變了枚舉對應的順序,數據庫中值就沒法對應上了__
默認狀況下,mybatis將CLOB類型的列映射到 java.lang.String
類型上,
將BLOB 映射到byte[]
類型上
使用map形式引入
<select id="findAllStudentsByNameEmail" resultMap="StudentResult" parameterType="map"> select stud_id, name,email, phone from Students where name=#{name} and email=#{email} </select>
使用參數替代
<select id="findAllStudentsByNameEmail" resultMap="StudentResult"> select stud_id, name,email, phone from Students where name=#{param1} and email=#{param2} </select>
默認狀況下,mybatis開啓一級緩存,對select進行緩存支持。 能夠經過<cache>
開啓二級緩存
開啓耳機緩存的同時引起的問題:
全部在映射語句文件定義的<select>語句的查詢結果都會被緩存
全部的在映射語句文件定義的<insert>,<update> 和<delete>語句將會刷新緩存
緩存根據最近最少被使用(Least Recently Used,LRU)算法管理
緩存不會被任何形式的基於時間表的刷新(沒有刷新時間間隔),即不支持定時刷新機制
緩存將存儲1024個 查詢方法返回的列表或者對象的引用
緩存會被看成一個讀/寫緩存。這是指檢索出的對象不會被共享,而且能夠被調用者安全地修改,不會其餘潛 在的調用者或者線程的潛在修改干擾。(即,緩存是線程安全的)
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
說明:
eviction
LRU : 最近不多使用
FIFO : 先進先出
SOFT : 軟引用
WEAK : 若引用
flushInterval(定義刷新時間)
size 大小
readOnly 只讀
基於註解的一些內容:
INSERT
UPDATE
SELECT
DELETE
基本使用
@Insert("INSERT INTO STUDENTS(NAME,EMAIL,ADDR_ID, PHONE) VALUES(#{name},#{email},#{address.addrId},#{phone})") //經過如下註解實現主鍵 @Options(useGeneratedKeys = true, keyProperty = "studId") //經過此註解爲任意SQL語句指定主鍵值(使用此註解生成主鍵) @SelectKey(statement="SELECT STUD_ID_SEQ.NEXTVAL FROM DUAL", keyProperty="studId", resultType=int.class, before=true) //使用觸發器生成 @SelectKey(statement="SELECT STUD_ID_SEQ.CURRVAL FROM DUAL", keyProperty="studId", resultType=int.class, before=false) //結果集映射 @Results( { @Result(id = true, column = "stud_id", property = "studId"), @Result(column = "name", property = "name"), @Result(column = "email", property = "email"), @Result(column = "addr_id", property = "address.addrId") })
一對一映射
嵌套sql語句形式
//使用嵌套select 語句實現 @Results( { @Result(id = true, column = "stud_id", property = "studId"), @Result(column = "name", property = "name"), @Result(column = "email", property = "email"), @Result(property = "address", column = "addr_id", one = @One(select = "com.mybatis3.mappers.StudentMapper. findAddressById")) })
嵌套對象
此種方式並無註解形式的實現 ,能夠經過在XML中定義映射`resultMap`集,而後經過`@ResultMap`進行映射
@ResultMap("com.mybatis3.mappers.StudentMapper. StudentWithAddressResult")
一對多映射
一樣的只有嵌套SQL的形式
@Result(property = "courses", column = "tutor_id", many = @Many(select = "com.mybatis3.mappers.TutorMapper. findCoursesByTutorId"))
遇到的問題
結果集不能重用,由於沒法賦予id, 因此沒法重用,哪怕相同都必須重寫寫
能夠經過一個xml進行映射
<mapper namespace="com.mybatis3.mappers.StudentMapper"> <resultMap type="Student" id="StudentResult"> <id property="studId" column="stud_id" /> <result property="name" column="name" /> <result property="email" column="email" /> <result property="phone" column="phone" /> </resultMap> </mapper> //經過此種方式解決沒法重用的問題 @Select("SELECT * FROM STUDENTS WHERE STUD_ID=#{studId}") @ResultMap("com.mybatis3.mappers.StudentMapper.StudentResult")
針對動態SQL經過工具類的方式生成SQL語句
return new SQL() { { SELECT("tutor_id as tutorId, name, email"); FROM("tutors"); WHERE("tutor_id=" + tutorId); } } .toString(); }
動態SQL映射
建立動態SQL映射類
public class TutorDynaSqlProvider { public String findTutorByIdSql(int tutorId) { return "SELECT TUTOR_ID AS tutorId, NAME, EMAIL FROM TUTORS WHERE TUTOR_ID=" + tutorId; } }
public String findTutorByNameAndEmailSql(Map<String, Object> map) { String name = (String) map.get("param1"); String email = (String) map.get("param2"); //you can also get those values using 0,1 keys //String name = (String) map.get("0"); //String email = (String) map.get("1"); return new SQL() { { SELECT("tutor_id as tutorId, name, email"); FROM("tutors"); WHERE("name=#{name} AND email=#{email}"); } } .toString(); }
添加動態SQL註解到方法上
@SelectProvider(type=TutorDynaSqlProvider.class, method="findTutorByIdSql") Tutor findTutorById(int tutorId);
配置mybatis beans
`applicationContext.xml` 中添加
<beans> <bean id="dataSource" class="org.springframework.jdbc.datasource. DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/elearning" /> <property name="username" value="root" /> <property name="password" value="admin" /> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="typeAliases" value="com.mybatis3.domain.Student, com.mybatis3.domain.Tutor" /> <property name="typeAliasesPackage" value="com.mybatis3.domain" /> <property name="typeHandlers" value="com.mybatis3.typehandlers.PhoneTypeHandler" /> <property name="typeHandlersPackage" value="com.mybatis3.typehandlers" /> <property name="mapperLocations" value="classpath*:com/mybatis3/**/*.xml" /> <property name="configLocation" value="WEB-INF/mybatisconfig.xml" /> </bean> </beans> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>
經過此種方式配置就能夠引用sqlSession
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.mybatis3.mappers" /> </bean>
經過以上的方式掃描包中的映射器Mapper接口, 並自動註冊
mybatis關於mapper掃描有兩種方式 :
* 使用XML形式 ` <mybatis:scan base-package="com.mybatis3.mappers" />` * 使用`@MapperScan`註解
很是感謝針對本書翻譯的工做者