国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java的MyBatis框架中Mapper映射配置的使用及原理解析

2019-11-26 14:15:35
字體:
供稿:網(wǎng)友

Mapper的內(nèi)置方法
model層就是實(shí)體類,對(duì)應(yīng)數(shù)據(jù)庫的表。controller層是Servlet,主要是負(fù)責(zé)業(yè)務(wù)模塊流程的控制,調(diào)用service接口的方法,在struts2就是Action。Service層主要做邏輯判斷,Dao層是數(shù)據(jù)訪問層,與數(shù)據(jù)庫進(jìn)行對(duì)接。至于Mapper是mybtis框架的映射用到,mapper映射文件在dao層用。

下面是介紹一下Mapper的內(nèi)置方法:

1、countByExample ===>根據(jù)條件查詢數(shù)量

int countByExample(UserExample example); //下面是一個(gè)完整的案列UserExample example = new UserExample(); Criteria criteria = example.createCriteria(); criteria.andUsernameEqualTo("joe"); int count = userDAO.countByExample(example);

 相當(dāng)于:select count(*) from user where username='joe'
 
2、deleteByExample ===>根據(jù)條件刪除多條

int deleteByExample(AccountExample example); //下面是一個(gè)完整的案例UserExample example = new UserExample(); Criteria criteria = example.createCriteria(); criteria.andUsernameEqualTo("joe"); userDAO.deleteByExample(example); 相當(dāng)于:delete from user where username='joe'

3、deleteByPrimaryKey===>根據(jù)條件刪除單條

int deleteByPrimaryKey(Integer id);userDAO.deleteByPrimaryKey(101); 

相當(dāng)于:

delete from user where id=101 

4、insert===>插入數(shù)據(jù)

int insert(Account record); //下面是完整的案例User user = new User(); //user.setId(101); user.setUsername("test"); user.setPassword("123456") user.setEmail("674531003@qq.com"); userDAO.insert(user);

 相當(dāng)于:

insert into user(ID,username,password,email) values(101,'test','123456','674531003@qq.com');

 5、insertSelective===>插入數(shù)據(jù)

int insertSelective(Account record);

6、selectByExample===>根據(jù)條件查詢數(shù)據(jù)

List<Account> selectByExample(AccountExample example); //下面是一個(gè)完整的案例UserExample example = new UserExample();Criteria criteria = example.createCriteria();criteria.andUsernameEqualTo("joe");criteria.andUsernameIsNull();example.setOrderByClause("username asc,email desc");List<?>list = userDAO.selectByExample(example);相當(dāng)于:select * from user where username = 'joe' and username is null order by username asc,email desc //注:在iBator 生成的文件UserExample.java中包含一個(gè)static 的內(nèi)部類 Criteria ,在Criteria中有很多方法,主要是定義SQL 語句where后的查詢條件。

 7、selectByPrimaryKey===>根據(jù)主鍵查詢數(shù)據(jù)

Account selectByPrimaryKey(Integer id);//相當(dāng)于select * from user where id = 變量id

 
8、updateByExampleSelective===>按條件更新值不為null的字段

int updateByExampleSelective(@Param("record") Account record, @Param("example") AccountExample example); //下面是一個(gè)完整的案列UserExample example = new UserExample(); Criteria criteria = example.createCriteria(); criteria.andUsernameEqualTo("joe"); User user = new User(); user.setPassword("123"); userDAO.updateByPrimaryKeySelective(user,example); 相當(dāng)于:update user set password='123' where username='joe'

 
9、updateByExampleSelective===>按條件更新

int updateByExample(@Param("record") Account record, @Param("example") AccountExample example);

10、updateByPrimaryKeySelective===>按條件更新

int updateByPrimaryKeySelective(Account record);//下面是一個(gè)完整的案例 User user = new User();user.setId(101);user.setPassword("joe");userDAO.updateByPrimaryKeySelective(user);

相當(dāng)于:

update user set password='joe' where id=101
int updateByPrimaryKeySelective(Account record); //下面是一個(gè)完整的案例  User user = new User();user.setId(101);user.setPassword("joe");userDAO.updateByPrimaryKeySelective(user);

相當(dāng)于:update user set password='joe' where id=101

11、updateByPrimaryKey===>按主鍵更新

int updateByPrimaryKey(Account record);//下面是一個(gè)完整的案例User user =new User(); user.setId(101); user.setUsername("joe"); user.setPassword("joe"); user.setEmail("joe@163.com"); userDAO.updateByPrimaryKey(user);

 相當(dāng)于:

update user set username='joe',password='joe',email='joe@163.com' where id=101
int updateByPrimaryKey(Account record); //下面是一個(gè)完整的案例User user =new User(); user.setId(101); user.setUsername("joe"); user.setPassword("joe"); user.setEmail("joe@163.com"); userDAO.updateByPrimaryKey(user);

 相當(dāng)于:

update user set username='joe',password='joe',email='joe@163.com' where id=101

 
解析mapper的xml配置文件
我們來看看mybatis是怎么讀取mapper的xml配置文件并解析其中的sql語句。

我們還記得是這樣配置sqlSessionFactory的:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">     <property name="dataSource" ref="dataSource" />    <property name="configLocation" value="classpath:configuration.xml"></property>     <property name="mapperLocations" value="classpath:com/xxx/mybatis/mapper/*.xml"/>     <property name="typeAliasesPackage" value="com.tiantian.mybatis.model" />   </bean>  

這里配置了一個(gè)mapperLocations屬性,它是一個(gè)表達(dá)式,sqlSessionFactory會(huì)根據(jù)這個(gè)表達(dá)式讀取包c(diǎn)om.xxx.mybaits.mapper下面的所有xml格式文件,那么具體是怎么根據(jù)這個(gè)屬性來讀取配置文件的呢?

答案就在SqlSessionFactoryBean類中的buildSqlSessionFactory方法中:

if (!isEmpty(this.mapperLocations)) {    for (Resource mapperLocation : this.mapperLocations) {     if (mapperLocation == null) {      continue;     }      try {      XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),        configuration, mapperLocation.toString(), configuration.getSqlFragments());      xmlMapperBuilder.parse();     } catch (Exception e) {      throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);     } finally {      ErrorContext.instance().reset();     }      if (logger.isDebugEnabled()) {      logger.debug("Parsed mapper file: '" + mapperLocation + "'");     }    }   } 

mybatis使用XMLMapperBuilder類的實(shí)例來解析mapper配置文件。

public XMLMapperBuilder(Reader reader, Configuration configuration, String resource, Map<String, XNode> sqlFragments) {   this(new XPathParser(reader, true, configuration.getVariables(), new XMLMapperEntityResolver()),     configuration, resource, sqlFragments);  } private XMLMapperBuilder(XPathParser parser, Configuration configuration, String resource, Map<String, XNode> sqlFragments) {   super(configuration);   this.builderAssistant = new MapperBuilderAssistant(configuration, resource);   this.parser = parser;   this.sqlFragments = sqlFragments;   this.resource = resource;  } 

接著系統(tǒng)調(diào)用xmlMapperBuilder的parse方法解析mapper。

public void parse() {   //如果configuration對(duì)象還沒加載xml配置文件(避免重復(fù)加載,實(shí)際上是確認(rèn)是否解析了mapper節(jié)點(diǎn)的屬性及內(nèi)容,   //為解析它的子節(jié)點(diǎn)如cache、sql、select、resultMap、parameterMap等做準(zhǔn)備),   //則從輸入流中解析mapper節(jié)點(diǎn),然后再將resource的狀態(tài)置為已加載   if (!configuration.isResourceLoaded(resource)) {    configurationElement(parser.evalNode("/mapper"));    configuration.addLoadedResource(resource);    bindMapperForNamespace();   }   //解析在configurationElement函數(shù)中處理resultMap時(shí)其extends屬性指向的父對(duì)象還沒被處理的<resultMap>節(jié)點(diǎn)   parsePendingResultMaps();   //解析在configurationElement函數(shù)中處理cache-ref時(shí)其指向的對(duì)象不存在的<cache>節(jié)點(diǎn)(如果cache-ref先于其指向的cache節(jié)點(diǎn)加載就會(huì)出現(xiàn)這種情況)   parsePendingChacheRefs();   //同上,如果cache沒加載的話處理statement時(shí)也會(huì)拋出異常   parsePendingStatements();  } 

mybatis解析mapper的xml文件的過程已經(jīng)很明顯了,接下來我們看看它是怎么解析mapper的:

private void configurationElement(XNode context) {   try {    //獲取mapper節(jié)點(diǎn)的namespace屬性    String namespace = context.getStringAttribute("namespace");    if (namespace.equals("")) {     throw new BuilderException("Mapper's namespace cannot be empty");    }    //設(shè)置當(dāng)前namespace    builderAssistant.setCurrentNamespace(namespace);    //解析mapper的<cache-ref>節(jié)點(diǎn)    cacheRefElement(context.evalNode("cache-ref"));    //解析mapper的<cache>節(jié)點(diǎn)    cacheElement(context.evalNode("cache"));    //解析mapper的<parameterMap>節(jié)點(diǎn)    parameterMapElement(context.evalNodes("/mapper/parameterMap"));    //解析mapper的<resultMap>節(jié)點(diǎn)    resultMapElements(context.evalNodes("/mapper/resultMap"));    //解析mapper的<sql>節(jié)點(diǎn)    sqlElement(context.evalNodes("/mapper/sql"));    //使用XMLStatementBuilder的對(duì)象解析mapper的<select>、<insert>、<update>、<delete>節(jié)點(diǎn),    //mybaits會(huì)使用MappedStatement.Builder類build一個(gè)MappedStatement對(duì)象,    //所以mybaits中一個(gè)sql對(duì)應(yīng)一個(gè)MappedStatement    buildStatementFromContext(context.evalNodes("select|insert|update|delete"));   } catch (Exception e) {    throw new BuilderException("Error parsing Mapper XML. Cause: " + e, e);   }  } 

configurationElement函數(shù)幾乎解析了mapper節(jié)點(diǎn)下所有子節(jié)點(diǎn),至此mybaits解析了mapper中的所有節(jié)點(diǎn),并將其加入到了Configuration對(duì)象中提供給sqlSessionFactory對(duì)象隨時(shí)使用。這里我們需要補(bǔ)充講一下mybaits是怎么使用XMLStatementBuilder類的對(duì)象的parseStatementNode函數(shù)借用MapperBuilderAssistant類對(duì)象builderAssistant的addMappedStatement解析MappedStatement并將其關(guān)聯(lián)到Configuration類對(duì)象的:

public void parseStatementNode() {   //ID屬性   String id = context.getStringAttribute("id");   //databaseId屬性   String databaseId = context.getStringAttribute("databaseId");    if (!databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) {    return;   }   //fetchSize屬性   Integer fetchSize = context.getIntAttribute("fetchSize");   //timeout屬性   Integer timeout = context.getIntAttribute("timeout");   //parameterMap屬性   String parameterMap = context.getStringAttribute("parameterMap");   //parameterType屬性   String parameterType = context.getStringAttribute("parameterType");   Class<?> parameterTypeClass = resolveClass(parameterType);   //resultMap屬性   String resultMap = context.getStringAttribute("resultMap");   //resultType屬性   String resultType = context.getStringAttribute("resultType");   //lang屬性   String lang = context.getStringAttribute("lang");   LanguageDriver langDriver = getLanguageDriver(lang);    Class<?> resultTypeClass = resolveClass(resultType);   //resultSetType屬性   String resultSetType = context.getStringAttribute("resultSetType");   StatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));   ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);    String nodeName = context.getNode().getNodeName();   SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));   //是否是<select>節(jié)點(diǎn)   boolean isSelect = sqlCommandType == SqlCommandType.SELECT;   //flushCache屬性   boolean flushCache = context.getBooleanAttribute("flushCache", !isSelect);   //useCache屬性   boolean useCache = context.getBooleanAttribute("useCache", isSelect);   //resultOrdered屬性   boolean resultOrdered = context.getBooleanAttribute("resultOrdered", false);    // Include Fragments before parsing   XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);   includeParser.applyIncludes(context.getNode());    // Parse selectKey after includes and remove them.   processSelectKeyNodes(id, parameterTypeClass, langDriver);      // Parse the SQL (pre: <selectKey> and <include> were parsed and removed)   SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);   //resultSets屬性   String resultSets = context.getStringAttribute("resultSets");   //keyProperty屬性   String keyProperty = context.getStringAttribute("keyProperty");   //keyColumn屬性   String keyColumn = context.getStringAttribute("keyColumn");   KeyGenerator keyGenerator;   String keyStatementId = id + SelectKeyGenerator.SELECT_KEY_SUFFIX;   keyStatementId = builderAssistant.applyCurrentNamespace(keyStatementId, true);   if (configuration.hasKeyGenerator(keyStatementId)) {    keyGenerator = configuration.getKeyGenerator(keyStatementId);   } else {    //useGeneratedKeys屬性    keyGenerator = context.getBooleanAttribute("useGeneratedKeys",      configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType))      ? new Jdbc3KeyGenerator() : new NoKeyGenerator();   }    builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,     fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,     resultSetTypeEnum, flushCache, useCache, resultOrdered,      keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);  } 

由以上代碼可以看出mybaits使用XPath解析mapper的配置文件后將其中的resultMap、parameterMap、cache、statement等節(jié)點(diǎn)使用關(guān)聯(lián)的builder創(chuàng)建并將得到的對(duì)象關(guān)聯(lián)到configuration對(duì)象中,而這個(gè)configuration對(duì)象可以從sqlSession中獲取的,這就解釋了我們?cè)谑褂胹qlSession對(duì)數(shù)據(jù)庫進(jìn)行操作時(shí)mybaits怎么獲取到mapper并執(zhí)行其中的sql語句的問題。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 达拉特旗| 施甸县| 日喀则市| 宁阳县| 濮阳市| 东兰县| 新巴尔虎右旗| SHOW| 永仁县| 寿阳县| 陵水| 漳州市| 获嘉县| 榕江县| 资源县| 寻乌县| 富川| 揭西县| 延津县| 山丹县| 巴中市| 榆树市| 上林县| 云浮市| 甘肃省| 通道| 徐水县| 孙吴县| 澳门| 泸溪县| 平乐县| 连江县| 吉林市| 湟源县| 崇州市| 廊坊市| 健康| 寻乌县| 寻乌县| 霍林郭勒市| 横峰县|