您好,登錄后才能下訂單哦!
mybatis怎么進行使用,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
1.數據源DataSource
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 數據源配置, 使用 BoneCP 數據庫連接池 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!-- 數據源驅動類可不寫,Druid默認會自動根據URL識別DriverClass --> <property name="driverClassName" value="${jdbc.driver}" /> <!-- 基本屬性 url、user、password --> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- config.decrypt=true生效 必須配置 filters的value包含config --> <property name="connectionProperties" value="druid.stat.slowSqlMillis=5000;config.decrypt=true;config.decrypt.key=${jdbc.publicKey}"/> <!-- 配置初始化大小、最小、最大 --> <property name="initialSize" value="${jdbc.pool.init}" /> <property name="minIdle" value="${jdbc.pool.minIdle}" /> <property name="maxActive" value="${jdbc.pool.maxActive}" /> <!-- 配置獲取連接等待超時的時間 --> <property name="maxWait" value="60000" /> <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 配置一個連接在池中最小生存的時間,單位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="300000" /> <property name="validationQuery" value="${jdbc.testSql}" /> <property name="testWhileIdle" value="true" /> <property name="testOnBorrow" value="false" /> <property name="testOnReturn" value="false" /> <!-- 打開PSCache,并且指定每個連接上PSCache的大小(Oracle使用) <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> --> <!-- 配置監控統計攔截的filters --> <property name="filters" value="config,stat,mergeStat,wall" /> </bean> <!-- 數據源配置, 使用應用服務器的數據庫連接池 <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/umanager" />--> <!-- 數據源配置, 不使用連接池 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>--> </beans>
2.mapper.xml文件
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:META-INF/com/unilife/mybatis-config.xml" /> <property name="mapperLocations" value="classpath:META-INF/com/unilife/**/sqlmap/**/*.xml"/> </bean>
3.Dao類的實例化
方法一:原生方法的實例化
自定義一個BaseDao抽象類實現SqlSessionDaoSupport并注入sqlSessionFactory,通過namespace+id找到mapper.xml文件
方法二:spring-mytabis動態代理生成實例化
<!-- 掃描basePackage下所有以@MyBatisDao注解的接口 --> <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> <property name="basePackage" value="com.unilife"/> <property name="annotationClass" value="com.unilife.annotation.UMemberBatisDao"/> </bean>
4.分頁插件
4.1自定義分頁插件
<plugins> <plugin interceptor="com.unilife.commons.utils.PagePlugin"> <property name="dialect" value="mysql" /> <property name="pageSqlId" value=".*ByPage" /> </plugin> </plugins> package com.unilife.commons.utils; import com.unilife.commons.dto.Page; import org.apache.ibatis.executor.ErrorContext; import org.apache.ibatis.executor.ExecutorException; import org.apache.ibatis.executor.statement.BaseStatementHandler; import org.apache.ibatis.executor.statement.RoutingStatementHandler; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.ParameterMapping; import org.apache.ibatis.mapping.ParameterMode; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.property.PropertyTokenizer; import org.apache.ibatis.scripting.xmltags.ForEachSqlNode; import org.apache.ibatis.session.Configuration; import org.apache.ibatis.type.TypeHandler; import org.apache.ibatis.type.TypeHandlerRegistry; import org.springframework.util.StringUtils; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Properties; @Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) }) public class PagePlugin implements Interceptor { private String dialect = ""; // 數據庫方言 private String pageSqlId = ""; // mapper.xml中需要攔截的ID(正則匹配) @Override public Object intercept(Invocation ivk) throws Throwable { if (ivk.getTarget() instanceof RoutingStatementHandler) { RoutingStatementHandler statementHandler = (RoutingStatementHandler) ivk .getTarget(); BaseStatementHandler delegate = (BaseStatementHandler) ReflectHelper .getValueByFieldName(statementHandler, "delegate"); MappedStatement mappedStatement = (MappedStatement) ReflectHelper .getValueByFieldName(delegate, "mappedStatement"); if (mappedStatement.getId().matches(pageSqlId)) { // 攔截需要分頁的SQL BoundSql boundSql = delegate.getBoundSql(); Object parameterObject = boundSql.getParameterObject();// 分頁SQL<select>中parameterType屬性對應的實體參數,即Mapper接口中執行分頁方法的參數,該參數不得為空 if (parameterObject == null) { throw new NullPointerException("parameterObject尚未實例化!"); } else { Connection connection = (Connection) ivk.getArgs()[0]; String sql = boundSql.getSql(); String countSql = "select count(0) from (" + sql + ") tmp_count"; // 記錄統計 PreparedStatement countStmt = connection .prepareStatement(countSql); BoundSql countBS = new BoundSql( mappedStatement.getConfiguration(), countSql, boundSql.getParameterMappings(), parameterObject); /* * 此處特殊處理foreach的參數 */ Field metaParamsField = ReflectHelper.getFieldByFieldName( boundSql, "metaParameters"); if (metaParamsField != null) { MetaObject mo = (MetaObject) ReflectHelper .getValueByFieldName(boundSql, "metaParameters"); ReflectHelper.setValueByFieldName(countBS, "metaParameters", mo); } setParameters(countStmt, mappedStatement, countBS, parameterObject); ResultSet rs = countStmt.executeQuery(); int count = 0; if (rs.next()) { count = rs.getInt(1); } rs.close(); countStmt.close(); // System.out.println(count); Page page = null; if (parameterObject instanceof Page) { // 參數就是Page實體 page = (Page) parameterObject; page.setEntityOrField(true); // 見com.flf.entity.Page.entityOrField // // 注釋 page.setTotalResult(count); } else { // 參數為某個實體,該實體擁有Page屬性 Field pageField = ReflectHelper.getFieldByFieldName( parameterObject, "page"); if (pageField != null) { page = (Page) ReflectHelper.getValueByFieldName( parameterObject, "page"); if (page == null) page = new Page(); page.setEntityOrField(false); // 見com.flf.entity.Page.entityOrField // 注釋 page.setTotalResult(count); ReflectHelper.setValueByFieldName(parameterObject, "page", page); // 通過反射,對實體對象設置分頁對象 } else { throw new NoSuchFieldException(parameterObject .getClass().getName() + "不存在 page 屬性!"); } } String pageSql = generatePageSql(sql, page); ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql); // 將分頁sql語句反射回BoundSql. } } } return ivk.proceed(); } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } /** * 對SQL參數(?)設值,參考org.apache.ibatis.executor.parameter. * DefaultParameterHandler * * @param ps * @param mappedStatement * @param boundSql * @param parameterObject * @throws SQLException */ private void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject) throws SQLException { ErrorContext.instance().activity("setting parameters") .object(mappedStatement.getParameterMap().getId()); List<ParameterMapping> parameterMappings = boundSql .getParameterMappings(); if (parameterMappings != null) { Configuration configuration = mappedStatement.getConfiguration(); TypeHandlerRegistry typeHandlerRegistry = configuration .getTypeHandlerRegistry(); MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject); for (int i = 0; i < parameterMappings.size(); i++) { ParameterMapping parameterMapping = parameterMappings.get(i); if (parameterMapping.getMode() != ParameterMode.OUT) { Object value; String propertyName = parameterMapping.getProperty(); PropertyTokenizer prop = new PropertyTokenizer(propertyName); if (parameterObject == null) { value = null; } else if (typeHandlerRegistry .hasTypeHandler(parameterObject.getClass())) { value = parameterObject; } else if (boundSql.hasAdditionalParameter(propertyName)) { value = boundSql.getAdditionalParameter(propertyName); } else if (propertyName .startsWith(ForEachSqlNode.ITEM_PREFIX) && boundSql.hasAdditionalParameter(prop.getName())) { value = boundSql.getAdditionalParameter(prop.getName()); if (value != null) { value = configuration.newMetaObject(value) .getValue( propertyName.substring(prop .getName().length())); } } else { value = metaObject == null ? null : metaObject .getValue(propertyName); } TypeHandler typeHandler = parameterMapping.getTypeHandler(); if (typeHandler == null) { throw new ExecutorException( "There was no TypeHandler found for parameter " + propertyName + " of statement " + mappedStatement.getId()); } typeHandler.setParameter(ps, i + 1, value, parameterMapping.getJdbcType()); } } } } /** * 根據數據庫方言,生成特定的分頁sql * * @param sql * @param page * @return */ private String generatePageSql(String sql, Page page) { if (page != null && StringUtils.hasLength(dialect)) { StringBuffer pageSql = new StringBuffer(); if ("mysql".equals(dialect)) { pageSql.append(sql); if (StringUtils.hasLength(page.getSort())) { pageSql.append(" ORDER BY " + page.getSort()); if (StringUtils.hasLength(page.getSort())) { pageSql.append(" " + page.getOrder()); } } pageSql.append(" limit " + page.getCurrentResult() + "," + page.getShowCount()); } else if ("oracle".equals(dialect)) { pageSql.append("select * from (select tmp_tb.*,ROWNUM row_id from ("); pageSql.append(sql); pageSql.append(") tmp_tb where ROWNUM<="); pageSql.append(page.getCurrentResult() + page.getShowCount()); pageSql.append(") where row_id>"); pageSql.append(page.getCurrentResult()); if (StringUtils.hasLength(page.getSort())) { pageSql.append(" ORDER BY " + page.getSort()); if (StringUtils.hasLength(page.getSort())) { pageSql.append(" " + page.getOrder()); } } } return pageSql.toString(); } else { return sql; } } @Override public void setProperties(Properties properties) { dialect = properties.getProperty("dialect"); pageSqlId = properties.getProperty("pageSqlId"); } } class ReflectHelper { /** * 獲取obj對象fieldName的Field * * @param obj * @param fieldName * @return */ public static Field getFieldByFieldName(Object obj, String fieldName) { for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass .getSuperclass()) { try { return superClass.getDeclaredField(fieldName); } catch (NoSuchFieldException e) { } } return null; } /** * 獲取obj對象fieldName的屬性值 * * @param obj * @param fieldName * @return * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException */ public static Object getValueByFieldName(Object obj, String fieldName) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { Field field = getFieldByFieldName(obj, fieldName); Object value = null; if (field != null) { if (field.isAccessible()) { value = field.get(obj); } else { field.setAccessible(true); value = field.get(obj); field.setAccessible(false); } } return value; } /** * 設置obj對象fieldName的屬性值 * * @param obj * @param fieldName * @param value * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException */ public static void setValueByFieldName(Object obj, String fieldName, Object value) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { Field field = obj.getClass().getDeclaredField(fieldName); if (field.isAccessible()) { field.set(obj, value); } else { field.setAccessible(true); field.set(obj, value); field.setAccessible(false); } } }
4.2 開源分頁插件
com.github.pagehelper
5.補充,可以通過mybatis-config.xml進行configuration對象的配置
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。