Краткое изложение классических вопросов интервью Mybatis о «коллекционном издании» в заметках короля

Java задняя часть MyBatis
Краткое изложение классических вопросов интервью Mybatis о «коллекционном издании» в заметках короля

Это 26-й день моего участия в августовском испытании обновлений. Ознакомьтесь с подробностями мероприятия: Испытание августовского обновления

Предисловие:

Некоторое время назад я делился с вами фактическим содержанием java-проекта.Сегодня я воспользовался выходными, чтобы организовать вопросы для интервью «Java--Mybatis», которые Java-инженерам часто задают в интервью о структуре сохраняемого уровня. , Надеюсь, вам понравится и вы поддержите его. Позже мы продолжим организовывать другие точки знаний, такие как ZooKeeper, Dubbo, Redis, MySQL, Spring, Spring Boot, Spring Cloud и другие технологические стеки. Давайте посмотрим на классические темы ниже, Если вам это нравится, вы можете поддержать его одним щелчком мыши и тремя ссылками.

Что такое фреймворк Mybatis? 

       MyBatis — превосходная структура уровня сохраняемости. Она поддерживает настраиваемый SQL, хранимые процедуры и расширенное сопоставление. Она инкапсулирует jdbc внутри, поэтому нам не нужно писать JDBC-соединения, поэтому разработчикам нужно сосредоточиться только на самой инструкции SQL и бизнесе. Не требуется усилий для работы со сложными процессами, такими как загрузка драйверов, создание соединений и создание операторов. Просто загрузите и импортируйте напрямую через файл конфигурации или пакет драйвера maven.

В чем преимущества Mybaits: ****

Mybatis основан на программировании операторов SQL, которое является очень гибким и не повлияет на дизайн существующих приложений или баз данных. XML, написанный SQL, устраняет связь между SQL и программным кодом, что удобно для унифицированного управления. Он предоставляет теги XML для позволяют вам писать динамические операторы SQL и повторно использовать их.

По сравнению с JDBC он сокращает объем кода более чем на 50 %, устраняет много избыточного кода JDBC и не требует ручного переключения соединений;

Хорошая совместимость с различными базами данных (поскольку MyBatis использует JDBC для подключения к базе данных, пока JDBC поддерживает базу данных, которую поддерживает MyBatis).

Хорошая интеграция с Spring и Spring MVCD framework;

Предоставляет метки сопоставления для поддержки сопоставления полей ORM между объектами и базами данных; предоставляет метки объектно-реляционного сопоставления для поддержки обслуживания объектно-реляционных компонентов.

Каковы недостатки фреймворка MyBatis:

Метод JDBC можно отлаживать по контрольным точкам, а Mybatis — нет.Он должен выводить информацию из журнала через журнал log4j, чтобы облегчить отладку, а затем изменять ее в файле конфигурации.

Написание операторов SQL требует много работы, особенно для разработчиков со многими полями и множеством связанных таблиц.Существуют определенные требования к основам операторов SQL.

Операторы SQL зависят от базы данных, что приводит к плохой переносимости базы данных. Таким образом, базу данных нельзя изменить произвольно.

К каким сценариям применима платформа MyBatis:  

Поскольку MyBatis фокусируется на самом SQL, это достаточно гибкое решение уровня DAO. Удовлетворить базовый однотабличный CRUD.

Проекты с относительно высокими требованиями к производительности или проекты с большим количеством изменений в требованиях, такие как проекты с большим объемом работы в Интернете, в основном используют MyBatis в качестве структуры уровня сохраняемости.

Разница между MyBatis и Hibernate? 

MyBatis поддерживает настройку операторов SQL, которые необходимо выполнять с помощью XML или аннотаций, и, наконец, сама структура сопоставляет объекты Java и операторы SQL для создания окончательного SQL для выполнения.После выполнения результаты отображаются в объекты Java и возвращаются. По сравнению с Hibernate Mybatis может писать собственный SQL, то есть он может строго контролировать производительность выполнения SQL и обладает высокой гибкостью. Однако предпосылкой гибкости является то, что MyBatis не может достичь независимости от базы данных.Если вам нужно внедрить программное обеспечение, которое поддерживает несколько баз данных, вам нужно настроить несколько наборов файлов сопоставления SQL, что требует большой работы.

Давайте поговорим о Hibernate, он имеет сильные возможности объектно-реляционного сопоставления и может достичь независимости от базы данных. Если вы используете Hibernate для разработки, вам не нужно писать реляционный SQL (люди, которые не умеют писать SQL, могут работать с базой данных), что может сэкономить много кода и повысить эффективность. Однако недостатком Hibernate является то, что порог обучения высок, порог освоения выше, а то, как спроектировать сопоставление O/R, как сбалансировать производительность и объектную модель, и как правильно использовать Hibernate, требует большого опыта и способностей.

Я думаю, в конце концов, объединить бизнес компании, выбрать наиболее подходящий фреймворк, не использовать технологию ради технологии, иначе будет хулиганство. Например, если вы работаете в относительно небольшой компании, объем данных невелик, а стек технологий разработчиков компании больше Hibernate, то рекомендуется использовать JPA и Hibernate, не требующие ручного написания SQL persistence. структуры слоев для повышения эффективности разработки, скорости итерации версий. Если вы являетесь интернет-компанией с большим количеством пользователей и строгими требованиями к производительности для соответствующего выполнения SQL, рекомендуется Mybatis. Короче говоря, в соответствии с потребностями пользователей, если программная архитектура с хорошей ремонтопригодностью и масштабируемостью может быть создана в среде с ограниченными ресурсами, это хорошая архитектура, поэтому инфраструктура является лучшей, только если она подходит.

В чем разница между #{} и ${}? 

Этот вопрос является более простым и более классическим, но в основном это обязательный вопрос на собеседовании.

#{} — это прекомпилированная обработка, ${} — замена строки.

Когда Mybatis обрабатывает #{}, он заменяет #{} в sql на ? и вызывает метод set в PreparedStatement для присвоения значений;

Mybatis перерабатывает, это поставить{}, это поставить{} заменяется значением переменной.

Использование #{} может эффективно предотвратить внедрение SQL и повысить безопасность системы.

Проиллюстрируем на примере

Всем известно, что тип параметра в операторе Mapper.xml Mybatis передает параметры оператору SQL двумя способами: #{} и ${}

Мы часто используем #{}. Общее объяснение состоит в том, что этот метод может предотвратить внедрение SQL. Проще говоря, оператор SQL в #{} предварительно скомпилирован. Он экранирует параметры в середине #{} в строку, например:

select * from student where student_name = #{name} 

Будет ли он после предварительной компиляции динамически анализироваться в маркер параметра?

select * from student where student_name = #{name} 

При использовании ${} в динамическом анализе строка параметра будет передана в

​
select * from student where student_name = #{name} 

​

Что делать, если имя атрибута в классе сущностей отличается от имени поля в таблице? 

Пример. Один из них — использовать resultMap в файле сопоставления Mapper для настройки правил сопоставления.

<!-- 自定义高级映射 -->
<!-- namespace属性:必须是接口的全类名 -->
<mapper namespace="com.tt.mybatis.mapper.EmployeeMapper">
	<!-- 
		id属性:必须是接口中方法的方法名
		resultType属性:必须是方法的返回值的全类名
	 -->
	<select id="getEmployeeById" resultMap="myMap">
		select * from employees where id = #{id}
	</select>
	
	<!-- 自定义高级映射 -->
    <resultMap type="com.tt.mybatis.entities.Employee" id="myMap">
    	<!-- 映射主键 -->
    	<id column="id" property="id"/>
    	<!-- 映射其他列 -->
    	<result column="last_name" property="lastName"/>
    	<result column="email" property="email"/>
    	<result column="salary" property="salary"/>
    	<result column="dept_id" property="deptId"/>
    </resultMap>
</mapper>

Существует также псевдоним, когда используется оператор sql.

<configuration>
 	<settings>
		 <!-- 开启驼峰命名规则 ,可以将数据库中的下划线映射为驼峰命名
		 	例如:last_name可以映射为lastName
		 -->
 		<setting name="mapUnderscoreToCamelCase" value="true"/>
 	</settings>
	<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/mybatis" />
				<property name="username" value="root" />
				<property name="password" value="root" />
			</dataSource>
		</environment>
	</environments>
	<!-- 注册映射文件 -->
	<mappers>
		<mapper resource="EmployeeMapper.xml" />
	</mappers>

Как написать нечеткий запрос, подобный оператору?

Пример: добавьте подстановочные знаки sql в код Java.

string wildcardname = “%smi%”;

list<name> names = mapper.selectlike(wildcardname);
<select id=”selectlike”>

select * from foo where bar like #{value}

</select>

Другой способ - объединить подстановочные знаки в операторе sql, но это может привести к внедрению sql.

 string wildcardname = “smi”;

list<name> names = mapper.selectlike(wildcardname);
<select id=”selectlike”>

select * from foo where bar like "%"#{value}"%"

</select>

Каков принцип работы интерфейса слоя Mybatis Dao? Методы в интерфейсе Dao имеют разные параметры, могут ли методы быть перегружены?

Например: интерфейс Dao — это интерфейс Mapper, --- вы можете создать интерфейс на основе аннотаций и определить абстрактные методы в интерфейсе;

public interface UserMapper {

	    @Select("select * from users where id=#{id}")
        public User getUserById(int id);
	    
}

Полное имя интерфейса — это значение пространства имен в файле сопоставления:

<mapper namespace="com.mybatis.test3.orderMapper">
<select id="selectUser" parameterType="int" resultType="Order">
select * from users where id=#{id}
</select>
</mapper>

Полное имя интерфейса — это значение пространства имен в файле сопоставления:

<mapper namespace="com.mybatis.test3.orderMapper">
<select id="selectUser" parameterType="int" resultType="Order">
select * from users where id=#{id}
</select>
</mapper>

Имя метода интерфейса (getUserById) — это значение идентификатора (selectUser) в MappedStatement в файле сопоставления, а параметры в методе интерфейса — это параметры, переданные в SQL (#{id} >>> #{id}).

Интерфейс Mapper не имеет классов реализации. При вызове метода интерфейса объедините имя интерфейса и имя метода со строкой в ​​качестве значения ключа, чтобы однозначно найти MappedStatement. Например: ком. Мибатис. Тест2. карта пользователя. Можно найти только пространство имен com. Мибатис. Тест2. UserMapper id = insertUser MappedStatement выглядит следующим образом.

В Mybatis каждый тег select, INSERT, update, delete анализируется как объект MappedStatement.

Объяснение о перегрузке и как это работает

Два метода в интерфейсе Dao не могут быть переопределены, потому что это стратегия сохранения и поиска полного имени + имени метода.

Интерфейс Dao работает как динамический прокси JDK. Когда Mybatis запущен, он будет использовать динамический прокси JDK для создания прокси-объекта прокси для интерфейса Dao.

Как Mybatis выполняет пейджинг?

   Использование Mybatis RowBounds Объекты выгружаются, что представляет собой подкачку памяти, выполняемую для набора результатов ResultSet, а не физическую подкачку. Вы можете напрямую записать параметры с физическим пейджингом в sql, чтобы завершить функцию физического пейджинга, или вы можете использовать подключаемый модуль пейджинга для завершения физического пейджинга. Давайте посмотрим, как Mybatis выполняет пейджинг


throws SQLException {
    DefaultResultContext resultContext = new DefaultResultContext();
    // 跳到offset位置,准备读取
    skipRows(rsw.getResultSet(), rowBounds);
    // 读取limit条数据
    while (shouldProcessMoreRows(resultContext, rowBounds) && rsw.getResultSet().next()) {
      ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(rsw.getResultSet(), resultMap, null);
      Object rowValue = getRowValue(rsw, discriminatedResultMap);
      storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
    }
  }
    private void skipRows(ResultSet rs, RowBounds rowBounds) throws SQLException {
    if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {
      if (rowBounds.getOffset() != RowBounds.NO_ROW_OFFSET) {
        // 直接定位
        rs.absolute(rowBounds.getOffset());
      }
    } else {
      // 只能逐条滚动到指定位置
      for (int i = 0; i < rowBounds.getOffset(); i++) {
        rs.next();
      }
    }
  }

Суммировать:

Что ж, я поделюсь ею сегодня.Вообще говоря, эта статья относительно хороша для изучения или интервью, и точки знаний, затронутые в статье, более важны.

Обновления Java 26 / 100 дней

Вы можете ставить лайки, добавлять в избранное, подписываться на меня, комментировать меня, а также активно участвовать в голосовании ниже.