MyBatisкнигадаapacheпроект с открытым исходным кодомiBatis,В 2010 году этот проект был запущен Apache. software фонд переехал в Google код и переименовал его в Mybatis. Перенесен на Github в ноябре 2013 года. Слово iBatis происходит от комбинации слов «интернет» и «abatis» и представляет собой структуру уровня персистентности, основанную на Java. Структура уровня персистентности, предоставляемая iBatis, включает SQL. Карты и данные Access Objects(DAOS)。 mybatis Инкапсулированный внутри jdbc, так что разработчикам нужно сосредоточиться только на sql само заявление, не тратя энергию на загрузку драйверов, создание связей, создание statement Подождите сложного процесса. mybatis проходить xml Или аннотируйте различные методы для выполнения statement Настройте его и проведите java объект и statement середина sql Динамические параметры сопоставляются для генерации окончательного выполнения. sql заявление, состоящее, наконец, из mybatis рамное исполнение sql и сопоставьте результат с java возразить и вернуться. использовать ORM Идея решает проблему сопоставления сущностей и баз данных. jdbc Инкапсулированный и экранированный jdbc api детали доступа низкого уровня, чтобы нам не приходилось иметь дело с jdbc api Сделав это, вы сможете завершить операцию сохранения базы данных.
1. Создать проект Маван
2. Добавьте координаты Мибатиса.
существоватьпроектpom.xml
документсерединадобавить вMybatis3.4.5координировать:
<dependencies>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- mybatis использует драйвер MySQL, требуется -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version> <scope>runtime</scope>
</dependency>
<!-- Зависимости модульного теста, необязательно -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<!-- Зависимость журнала, необязательно -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
3.добавить в Класс сущностиUser
существоватьdomain
Бао Сясоздавать Класс сущностиUser
:
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username; }
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", birthday=" + birthday
+ ", sex=" + sex + ", address="
+ address + "]";
}
}
4.Написать интерфейс уровня персистентностиIUserDao
существоватьdao
Бао Сясоздавать Класс сущностиIUserDao
:
//Интерфейс уровня персистентности (также можно записать как UserDao или ВОЗ UserMapper)
public interface IUserDao {
/**
* Опросить всех пользователей
* @return
*/
List<User> findAll();
}
5.Написать интерфейс уровня персистентностиизкартографированиедокументIUserDao.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.itheima.dao.IUserDao">
<!-- Настроить запрос всех операций -->
<select id="findAll" resultType="com.itheima.domain.User">
select * from user
</select>
</mapper>
Уведомление:
6.писатьSqlMapConfig.xml
Конфигурациядокумент
<?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>
<!-- Конфигурация mybatis среда -->
<environments default="mysql">
<!-- Конфигурация mysql среда -->
<environment id="mysql">
<!-- Виды Конфигурациидела -->
<transactionManager type="JDBC"></transactionManager>
<!-- Конфигурациясоединятьбаза Информация о данных: да используемый источник данных (пул соединений) -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ee50"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
</dataSource>
</environment>
</environments>
<!-- информировать mybatis картографирование Конфигурациярасположение -->
<mappers>
<mapper resource="com/itheima/dao/IUserDao.xml"/>
</mappers>
</configuration>
7. Напишите тестовые классы.
public class MybatisTest {
public static void main(String[] args)throws Exception {
//1.читать Конфигурациядокумент
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.Создать SqlSessionFactory Строитель по объекту
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.использовать строитель создает фабричный объект SqlSessionFactory
SqlSessionFactory factory = builder.build(in);
//4.использовать SqlSessionFactory Производство SqlSession объект
SqlSession session = factory.openSession();
//5.использовать SqlSession создавать dao Интерфейсный прокси-объект
IUserDao userDao = session.getMapper(IUserDao.class);
//6.использовать выполнение прокси-объекта, запросить все методы
List<User> users = userDao.findAll();
for(User user : users) {
System.out.println(user);
}
//7. Освободить ресурсы.
session.close();
in.close();
}
}
Если соблюдаются следующие три правила, нет необходимости писать класс реализации dao, Mybatis автоматически создает класс реализации:
1.существоватьинтерфейс уровня персистентностиIUserDao
серединадобавить ваннотация
public interface IUserDao {
/**
* Опросить всех пользователей
* @return
*/
@Select("select * from user")
List<User> findAll();
}
2.不再нуждатьсяинтерфейс уровня персистентностиизкартографированиедокументIUserDao.xml
,прямойудалить
3.ИсправлятьSqlMapConfig.xml
,Измените путь xml на имя класса
<!-- информировать mybatis картографирование Конфигурациярасположение -->
<mappers>
<mapper class="com.itheima.dao.IUserDao"/>
</mappers>
1.создаватьинтерфейс уровня персистентностиIUserDao
извыполнитьдобрыйimpl.UserDaoImpl
public class UserDaoImpl implements IUserDao{
private SqlSessionFactory factory;
public UserDaoImpl(SqlSessionFactory factory){
this.factory = factory;
}
public List<User> findAll(){
//1.использоватьфабрикасоздаватьSqlSessionобъект
SqlSession session = factory.openSession();
//2.usesession выполняет все методы запроса. Здесь вам необходимо указать метод полного имени интерфейса, содержащий полное имя пакета, чтобы найти последний оператор sql, который необходимо выполнить.
List<User> users = session.selectList("com.itheima.dao.IUserDao.findAll");
session.close();
//3. Возвращаем результаты запроса.
return users;
}
}
2. Измените вызывающий метод тестового класса.
public class MybatisTest {
public static void main(String[] args)throws Exception {
//1.читать Конфигурациядокумент
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.Создать SqlSessionFactory Строитель по объекту
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.использовать строитель создает фабричный объект SqlSessionFactory
SqlSessionFactory factory = builder.build(in);
//4.использоватьфабрикасоздаватьdaoобъект
IUserDao userDao = new UserDaoImpl(factory);
//5.использоватьdaoобъект выполнить запрос всех методов
List<User> users = userDao.findAll();
for(User user : users) {
System.out.println(user);
}
//6. Освободить ресурсы.
in.close();
}
}
существоватьвыше Быстрый стартсерединапредставлять Понятно最基книгаиз Запросдействовать,Далее мы представим использование mybatis на базе Добавляйте, удаляйте, проверяйте и изменяйте операции с данными
1.существоватьинтерфейс уровня персистентностиIUserDao
серединадобавить в Методы интерфейса
/**
* Запрос информации о пользователе на основе идентификатора
* @param userId
* @return
*/
User findById(Integer userId);
/**
* сохранить пользователя
* @param user
*/
void saveUser(User user);
/**
* Обновить пользователя
* @param user
*/
void updateUser(User user);
/**
* Удалить пользователя по идентификатору
* @param userId
*/
void deleteUser(Integer userId);
/**
* Нечеткий запрос информации о пользователе на основе имени
* @param username
* @return
*/
List<User> findByName(String username);
2.существоватьпользовательизкартографирование КонфигурациядокументSqlMapConfig.xml
середина Увеличивать Конфигурация
<!-- Запрос пользователя по идентификатору -->
<!-- Встроенный тип может использовать сокращение int или полное имя java.lang.Integer, но пользовательский тип должен использовать полное имя. -->
<select id="findById" parameterType="int" resultType="com.itheima.domain.User">
select * from user where id = #{uid}
</select>
<!-- сохранить пользователя -->
<insert id="saveUser" parameterType="com.itheima.domain.User">
<!-- Конфигурация插入действоватьназад,获取插入数据изid -->
<!-- имя свойства класса сущности keyProperty -->
<!-- keyColumnбаза данных列имя -->
<!-- Выполните оператор order="AFTER" после завершения выполнения. -->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday});
</insert>
<!-- Обновить пользователя -->
<update id="updateUser" parameterType="com.itheima.domain.User">
update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}
</update>
<!-- Удалить пользователя-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id = #{uid}
</delete>
<!-- Нечеткий запрос по имени -->
<select id="findByName" parameterType="string" resultType="com.itheima.domain.User">
select * from user where username like #{name}
<!-- select * from user where username like '%${value}%'-->
</select>
#{}
:Представляет заполнитель,Эквивалент оригиналаjdbcиз?
,Оба используются для замены фактических данных при выполнении операторов.,具体из数据由#{}
里面из内容决定из,если Тип данныхда Базовый тип,Вы можете ввести в него любое имя,напримерfindById
серединаизuid
Можетверно应Методы интерфейсасерединаиз实际параметримяuserId
。еслитип данныхдасложный тип,Грамматический формат – даиспользовать. #{объект.объект}
из Способ,например#{user.username}
он будет искать его первым user объект,Затемсуществовать user объектсередина找到 username свойство и вызовем метод getUsername(), чтобы получить значение, мы существуем parameterType свойство上指定Понятно Класс сущностиимя,Так что это можно опуститьuser.
,Вместо этого напишите имя пользователя напрямую.3. Напишите тестовые классы
public class MybatisTest {
private InputStream in;
private SqlSession sqlSession;
private IUserDao userDao;
@Before//Используется для выполнения до того, как будет выполнен существующий тестовый метод
public void init()throws Exception{
//1.читать Конфигурациядокумент,Сгенерировать поток ввода байтов
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2. Получить SqlSessionFactory.
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3. Получить объект SqlSession.
sqlSession = factory.openSession();
//4. Получить прокси-объект Дао
userDao = sqlSession.getMapper(IUserDao.class);
}
@After//Используется для выполнения после выполнения тестового метода
public void destroy()throws Exception{
//представлять на рассмотрениедела sqlSession.commit();
//6. Освободить ресурсы.
sqlSession.close();
in.close();
}
@Test
public void testFindOne(){
//5. Выполняем метод запроса.
User user = userDao.findById(50);
System.out.println(user);
}
@Test
public void testFindByName(){
//5. Выполняем метод запроса.
List<User> users = userDao.findByName("%король%"); //List<User> users = userDao.findByName("король"); for(User user : users){
System.out.println(user);
}
}
}
4. Параметр серединаесли должен передать несколько Pojo (Plain Ordinary Java Object)объект,Может用一个pojoдобрыйQueryVo
Содержит несколькоpojo
public class QueryVo {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
<!-- Согласно нечеткому запросу имени пользователя, параметр становится QueryVo объект Понятно -->
<select id="findByVo" resultType="com.itheima.domain.User" parameterType="com.itheima.domain.QueryVo">
select * from user where username like #{user.username};
</select>
Содержимое и иерархическая связь конфигурации файла SqlMapConfig.xml:
-характеристики —property -settings (параметры глобальной конфигурации) —setting -typeAliases (псевдонимы типов) —typeAliase —package -typeHandlers (обработчики типов) -objectFactory (фабрика объектов) -плагины -environments (объект атрибута коллекции сред) —environment (объект субсвойства «окружающая среда») ---transactionManager (управление транзакциями) ---dataSource (источник данных) -картографы (картографы) —mapper —package
resultMap
sqlзаявлениесерединаиз Запрос Возвращенные столбцы должны быть суммойresultType
добрый型серединаизсвойствоимяверно应,нетприсвоит значениедляnull
,если отличается только в случае,Задание все еще может быть успешным,потому чтодляmysql существовать windows Система середина не чувствительна к регистру!
Для сопоставления можно использовать оператор существования SQL середина, чтобы установить псевдоним для принудительного сопоставления. Этот метод может потребовать изменения большого количества операторов SQL, что требует большой рабочей нагрузки. Можно рассмотреть другой метод картографирования при возврате. ценить:
1.существоватьIUserDao.xml
серединаопределениеresultMap
<!-- Конфигурация Соответствие названий столбцов результатов запроса названию класса сущности -->
<resultMap id="userMap" type="com.itheima.domain.User">
<!-- Соответствие первичного ключа Поле -->
<id property="userId" column="id"></id>
<!--Нет Соответствие первичного ключа Поле-->
<result property="userName" column="username"></result>
<result property="userAddress" column="address"></result>
<result property="userSex" column="sex"></result>
<result property="userBirthday" column="birthday"></result>
</resultMap>
2.существоватьнуждатьсянанесен на карту地方Волявозвращатьсядобрый型由resultType
изменятьдляresultMap
<!-- Запрос пользователя по идентификатору -->
<select id="findById" parameterType="int" resultMap="userMap">
select * from user where id = #{uid}
</select>
properties
Некоторые могут быть Конфигурация Извлеките информацию и сохраните еесуществоватьproperties
Этикеткасередина,Реализуйте повторное использование,ИсправлятьSqlMapConfig.xml
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"></property>
<property name="username" value="root"></property>
<property name="password" value="1234"></property>
</properties>
...
<!--Настроить пул соединений-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</dataSource>
Вы также можете выделить свойства и существование в отдельный документ существования. classpath 下определениеjdbcConfig.properties
документ
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy
jdbc.username=root
jdbc.password=1234
SqlMapConfig.xml
изproperties
Этикетканастраиватьurl
или ВОЗresources
свойство,для цитированияjdbcConfig.properties
документ, разница между ними заключается в следующем:
resourceсвойство:常用изиспользуется для指定Конфигурациядокументрасположение,да записывается в соответствии с путем к классу.,И он должен храниться в пути к классу.
<properties resource="jdbcConfig.properties"></properties>
Атрибут url: необходимо написать адрес в соответствии с методом записи URL.
<properties url="file:///D:/xxx/xxx/jdbcConfig.properties"></properties>
typeAliases
<!--использоватьtypeAliasesКонфигурация别имя,它может только Конфигурацияdomainсерединадобрыйиз别имя -->
<typeAliases>
<!--typeAliasиспользуется для Конфигурация别имя。typeсвойство指定изда Класс сущности全限定добрыйимя。aliasсвойство指定别имя,当指定Понятно别имя就再区分大小写 -->
<!-- Определение единого псевдонима -->
<-- <typeAlias type="com.itheima.domain.User" alias="user"></typeAlias> -->
<!-- используется для指定要Конфигурация别имяиз包,После указания,Классы сущностей в этом пакете будут регистрировать псевдонимы.,И имя класса — даалиас,Больше не чувствителен к регистру-->
<!-- Пакетное определение псевдонима, сканирование классов по всему пакету, псевдоним для имени класса (первая буква может быть как прописной, так и строчной) -->
<package name="com.itheima.domain"></package>
</typeAliases>
mappers
<!-- Конфигурациякартографированиедокументрасположение -->
<mappers>
<!-- использовать ресурсы относительно пути к классам -->
<!--<mapper resource="com/itheima/dao/IUserDao.xml"></mapper>-->
<!-- Путь к классу интерфейса usemapper -->
<!--<mapper class="com.itheima.dao.UserDao"/>-->
<!-- Тег пакета da используется для указания пакета интерфейса dao. После его указания нет необходимости писать преобразователь, ресурс или класс. -->
<package name="com.itheima.dao"></package>
</mappers>
существовать Mybatis изSqlMapConfig.xml
Конфигурациядокументсередина,проходить<dataSource type="pooled">
осознать Mybatis серединасоединять池из Конфигурация。
Mybatis Делит собственные источники данных на три категории:
MyBatis内部определение Понятновыполнить Понятноjava.sql.DataSource
интерфейсизUnpooledDataSource
добрыйиPooledDataSource
добрый分别表示UNPOOLED、Источник данных типа POOLED.
Транзакция базы данных — это последовательность операций с базой данных, которые обращаются к различным элементам данных и могут работать с ними. Эти операции либо выполняются, либо не выполняются вообще. Они представляют собой неделимую единицу работы.
Четыре характеристики транзакций (ACID)
Три проблемы, вызванные параллелизмом транзакций
Резюме: Легко спутать неповторяющееся чтение и фантомное чтение, ориентированное на изменение, тогда как фантомное чтение сосредоточено на добавлении или удалении. Чтобы решить проблему неповторяющегося чтения, вам нужно заблокировать только те строки, которые соответствуют условиям (Повторяемое чтение). Чтобы решить проблему фантомного чтения, вам нужно заблокировать таблицу.
Четыре уровня изоляции транзакций, определенные MySQL
уровень изоляции транзакции | грязное чтение | неповторяющееся чтение | фантомное чтение | объяснять |
---|---|---|---|---|
чтение незафиксировано | да | да | да | Может читать незафиксированные транзакции |
неповторяющееся чтение(read-committed) | нет | да | да | Можно только читать отправленные транзакции |
Повторяемое чтение | нет | нет | да | Можно прочитать до и после отправки транзакции [MySql по умолчанию] |
сериализуемый | нет | нет | нет | Таблица будет заблокирована при сериализации,да Самый безопасный,Это также в принципе бесполезно для ежедневного развития. |
Команда настройки транзакции Mysql
set session transaction isolation level read uncommitted;
set session transaction isolation level read committed;
set session transaction isolation level repeatable read;
set session transaction isolation level serializable;
Mybatisсерединаиспользоватьдела
Mybatisда основана на инкапсуляции jdbc, существует JDBC середина МожетпроходитьsetAutoCommit()
Воляделапредставлять на рассмотрениенастраиватьдляавтоматическийили手动из Способ。
setAutoCommit
官方определение: Воля此соединятьизавтоматическийпредставлять на рассмотрение模式настраиватьдляданное состояние。еслисоединять处于автоматическийпредставлять на рассмотрение模式下,Тогда все его операторы SQL будут выполнены и отправлены как одно. неправило,Его операторы SQL будут сгруппированы в деласередина.,пока не позвонятcommit
метод илиrollback
До сих пор. По умолчанию новые соединения находятся в режиме автофиксации.
существоватьmybatisизsession = factory.openSession();
методсередина,Параметры по умолчаниюдаfalse
,То есть способ подачи дел вручную,существует после выполнения оператора sql,Необходимо выполнить вручнуюsession.commit
илиsession.rollback
,Это также широко используемый метод,потому чтодля我们Можетв соответствии с Определяется условиями бизнесаданет进行представлять на рассмотрение。
еслинастраивать`session = factory.openSession(true);
,Затем mybatis настроит метод jdbcдля для автоматической отправки дел.,Нет необходимости отображать исполнениеsession.commit
。
Повторяющиеся операторы sql могут быть извлечены и на них можно ссылаться с помощью include, когда они используются для достижения цели повторного использования sql.
<!-- Извлечь повторяющиеся предложенияфрагмент кода -->
<sql id="defaultSql">
select * from user
</sql>
<!-- Настроить запрос всех операций -->
<select id="findAll" resultType="user">
<include refid="defaultSql"></include>
</select>
<!-- в соответствии с id Запрос -->
<select id="findById" resultType="user" parameterType="int">
<include refid="defaultSql"></include>
where id = #{uid}
</select>
<if>
Можетв соответствии сусловия, чтобы судитьданетнуждаться拼接sqlзаявление,Этикеткасерединаиз test имя свойства объекта, показанного посередине, если должен использоваться объект класса-оболочки OGNL Как писать выражения.
для обеспечивает плавное сращивание,主заявление上要加上where 1=1
。
<select id="findByUser" resultType="user" parameterType="user">
select * from user where 1=1
<if test="username!=null and username != '' ">
and username like #{username}
</if>
<if test="address != null">
and address like #{address}
</if>
</select>
<where>
использовать<where>
Этикетка Может简化where 1=1
из条件инкапсуляция,同час Можетавтоматический处理条件掉表达式开头изand
или ВОЗor
характер,Сгенерируйте правильные операторы sql.
<!-- в соответствии с Информация о пользователе Запрос -->
<select id="findByUser" resultType="user" parameterType="user">
<include refid="defaultSql"></include>
<where>
<if test="username!=null and username != '' ">
and username like #{username}
</if>
<if test="address != null">
and address like #{address}
</if>
</where>
</select>
<foreach>
существуют при сращивании операторов sql,Иногда вам нужно передать коллекцию,напримертакизsqlзаявлениеselect Поле from user where id in (?)
,Вы можете написать такие утверждения:
<!-- в соответствии сqueryvoсерединаизIdРеализация коллекции Запрос Список пользователей -->
<select id="findUserInIds" resultMap="userMap" parameterType="queryvo">
<include refid="defaultUser"></include>
<where>
<if test="ids != null and ids.size()>0">
<foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
#{uid}
</foreach>
</if>
</where>
</select>
<foreach>
Этикеткаиспользуется для遍历собирать,Значение свойства для:
Тестовый метод, создайте коллекцию идентификаторов:
/**
* Проверка использования тега foreach
*/
@Test
public void testFindInIds(){
QueryVo vo = new QueryVo();
List<Integer> list = new ArrayList<Integer>();
list.add(41);
list.add(42);
list.add(46);
vo.setIds(list);
List<User> users = userDao.findUserInIds(vo);
for(User user : users){
System.out.println(user);
}
}
если2ассоциация таблиц Запрос,Например, таблица учетных записей и таблица пользователей.,Одна Учетная запись может соответствовать только одному Пользователю.,Отношения между учетной записью и пользователем1 к 1,Можетиспользоватьнаследоватьиз Способ让AccountнаследоватьUserиз全部Поле,sqlзаявлениевозвращатьсяиз数据列分别и各Полеобязательность。另一个更好из办法даиспользоватькомбинацияиз Способ,дляAccount определяет свойство пользователя,使之Воляиuser有关из数据инкапсуляция起来。
Mybatisсередина Можетиспользоватьassociation
Этикеткаопределение,IAccountDao.xml
изопределение:
<!-- Определите resultMap, который инкапсулирует учетную запись и пользователя. -->
<resultMap id="accountUserMap" type="account">
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!-- 一верно一из关系картографирование:Конфигурацияинкапсуляцияuserиз内容-->
<association property="user" column="uid" javaType="user">
<id property="id" column="id"></id>
<result column="username" property="username"></result>
<result column="address" property="address"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
</association>
</resultMap>
<!-- Все по Запросу -->
<select id="findAll" resultMap="accountUserMap">
select u.*,a.id as aid,a.uid,a.money from account a , user u where u.id = a.uid;
</select>
Класс сущности учетной записи:
public class Account implements Serializable {
...
//Субъект подчиненной таблицы должен содержать объектную ссылку на объект главной таблицы
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Один Пользователь может соответствовать нескольким Учетным записям, и между Пользователем и Учетной записью существует связь «один ко многим».
существоватьMybatisсередина Можетиспользоватьcollection
Этикеткаопределение,IUserDao.xml
изопределение:
<!-- определениеUserизresultMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!-- Конфигурацияuserобъектсерединаaccountsсобиратьизкартографирование -->
<!-- collection да используется для установления отношения соответствия «один ко многим» между свойством коллекций середина
ofType Используется для указания типа данных элементов коллекции. -->
<collection property="accounts" ofType="account">
<id column="aid" property="id"></id>
<result column="uid" property="uid"></result>
<result column="money" property="money"></result>
</collection>
</resultMap>
<!-- Все по Запросу -->
<select id="findAll" resultMap="userAccountMap">
select u.*,a.id as aid ,a.uid,a.money from user u left outer join account a on u.id =a.uid
</select>
Класс пользовательской сущности:
public class User implements Serializable {
...
//Картографирование отношений «один-ко-многим»: основная сущность таблицы должна содержать ссылку на коллекцию из подчиненной сущности таблицы.
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
}
Отложенная загрузка означает загрузку только тогда, когда данные необходимы.,Не загружайте данные, когда они не нужны,Также называется ленивой загрузкой.
1.ИсправлятьIAccountDao.xml
,Будут ли связанные пользовательские настройки для отложенной загрузки:
<!-- Определите resultMap, который инкапсулирует учетную запись и пользователя. -->
<resultMap id="accountUserMap" type="account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!-- 一верно一из关系картографирование:Конфигурацияинкапсуляцияuserиз内容
selectсвойство指定из内容:Запроспользовательиз唯一标识,имя метода,Необходимый
columnсвойство指定из内容:пользовательв соответствии сidЗапросчас,Имя обязательного параметра (имя столбца, возвращаемое оператором sql),Необходимый
-->
<association property="user" column="uid" javaType="user" select="com.itheima.dao.IUserDao.findById">
</association>
</resultMap>
<!-- Все по Запросу -->
<select id="findAll" resultMap="accountUserMap">
select * from account
</select>
2.ИсправлятьIUserDao.xml
,добавить в Запрос单个пользовательизметод:
<!-- Запрос пользователя по идентификатору -->
<select id="findById" parameterType="int" resultType="user">
select * from user where id = #{uid}
</select>
3. Включите Mybatis из Стратегия ленивой загрузки,ИсправлятьSqlMapConfig.xml
:
<!--Конфигурацияпараметр-->
<settings>
<!--延迟加载из全局开关,Включите Mybatis для поддержки отложенной загрузки.,значение по умолчаниюfalse-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--当включатьчас,Любой вызов метода загрузит все свойства этого объекта. неправило,Каждое свойство будет загружено по требованию.,значение по умолчаниюfalse(true in <=3.4.1)-->
<setting name="aggressiveLazyLoading" value="false"></setting>
</settings>
После завершения настройки, когда запрашивается только учетная запись без использования атрибута «Пользователь», оператор sql запроса для объекта «Пользователь» не будет выполнен.
1.ИсправлятьIUserDao.xml
,Установите для связанной учетной записи задержку загрузки:
<!-- определениеUserизresultMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!-- Конфигурацияuserобъектсерединаaccountsсобиратьизкартографирование -->
<!-- используется для指定Запросaccount列表изsqlзаявление,所以填写изда Долженsqlнанесен на картаid, обязателен
columnсвойство指定из内容:используется для指定selectсвойствоизsqlзаявлениеизпараметр来源,Параметр выше берется из столбца идентификатора пользователя.,Поэтому я написал это как идентификатор имени.,Необходимый-->
<collection property="accounts" ofType="account" select="com.itheima.dao.IAccountDao.findAccountByUid" column="id">
</collection>
</resultMap>
<!-- Все по Запросу -->
<select id="findAll" resultMap="userAccountMap">
select * from user
</select>
2.ИсправлятьIAccountDao.xml
,добавить вв соответствии спользовательidЗапрос账号изметод:
<!-- в соответствии спользовательidЗапрос Список аккаунтов -->
<select id="findAccountByUid" resultType="account">
select * from account where uid = #{uid}
</select>
3. Включите глобальный переключатель с задержкой загрузки.
Кэш L1да SqlSession уровень кэша, пока SqlSession Нет flush или close,оно существуетсуществовать。
напримерсуществоватьтот же самыйSqlSession
下вернопользователь Запрос2ВторосортныйUser user = userDao.findById(41);
,Оператор sql будет выполнен только один раз,2ВторосортныйвозвращатьсяизUserобъектдатот же самыйобъект。
Кэш L1да SqlSession Кэш по умолчанию при вызове SqlSession Кэш будет очищен при изменении, добавлении, удалении, commit(), close(),clearCache() и других методах. L1。
Кэш L2да mapper Кэш уровня сопоставления, множественный SqlSession действовать так же Mapper нанесен на карту sql Заявление: несколько SqlSession могут совместно использовать Кэш L2,Кэш L2дакросс SqlSession из.
Включение и выключение Кэш L2
1.существоватьSqlMapConfig.xml
документ Включи Кэш L2
<settings>
<!-- Включи Кэш Поддержка L2 -->
<!-- cacheEnabled изпо умолчанию取ценить就даtrue,所以这一步其实Может省略不Конфигурация -->
<setting name="cacheEnabled" value="true"/>
</settings>
2.Конфигурациянуждаться Кэш L2изMapperкартографированиедокумент
<?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.itheima.dao.IUserDao">
<!--включатьuserподдерживать Кэш L2-->
<!--Этикетка表示当前这个 mapper картографирование Воляиспользовать Кэш L2,区分из标准就看mapperизnamespaceценить-->
<cache></cache>
...
</mapper>
3. Настройте атрибут useCache в выражении.
<!-- Запрос пользователя по идентификатору -->
<select id="findById" parameterType="INT" resultType="user" useCache="true">
select * from user where id = #{uid}
</select>
ВоляIUserDao.xml
картографированиедокументсерединаиз<select>
ЭтикеткасерединанастраиватьuseCache="true"
代表当前这个 statement 要использовать Кэш L2, если использовать кэш L2 можно установить для false。
Уведомление:
java.io.Serializable
интерфейс,Таким образом, объект можно сохранить в режиме сериализации.использоватьMybatis提供изаннотация Способ,就Может不用создаватьMapperкартографированиедокумент Понятно。
1.писатьSqlMapConfig.xml
Конфигурациядокумент
<?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="jdbcConfig.properties"></properties>
<!-- Конфигурация别имяиз注册 -->
<typeAliases>
<package name="com.itheima.domain"></package>
</typeAliases>
<!-- Конфигурациясреда-->
<environments default="mysql">
<environment id="mysql">
<!-- Виды Конфигурацииделада JDBC -->
<transactionManager type="JDBC"></transactionManager>
<!-- Данные конфигурации -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</dataSource>
</environment>
</environments>
<!-- Конфигурациякартографирование信息 -->
<!-- Указывает расположение интерфейса dao с аннотацией. -->
<mappers>
<!-- Конфигурация dao Расположение интерфейса, у него есть два пути
第一种:использовать mapper Этикетка Конфигурация class свойство
Второй вид:использовать package Метка, указанная непосредственно dao Пакет интерфейса существует
-->
<mapper class="com.itheima.dao.IUserDao"></mapper>
</mappers>
</configuration>
2.использоватьаннотация Способ开发интерфейс уровня персистентностиIUserDao
public interface IUserDao {
/**
* Опросить всех пользователей
* @return
*/
@Select("select * from user")
@Results(id="userMap",
value= {
@Result(id=true,column="id",property="userId"),
@Result(column="username",property="userName"),
@Result(column="sex",property="userSex"),
@Result(column="address",property="userAddress"),
@Result(column="birthday",property="userBirthday")
})
List<User> findAll();
/**
* в соответствии с id Запрос一个пользователь
* @param userId
* @return
*/
@Select("select * from user where id=#{id} ")
@ResultMap("userMap")
User findById(Integer userId);
/**
* Сохранить операцию
* @param user
*/
@Insert("insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})")
@SelectKey(keyColumn="id",keyProperty="id",resultType=Integer.class,before =
false, statement = { "select last_insert_id()" })
int saveUser(User user);
/**
* операция обновления
* @param user
*/
@Update("update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address} where id=#{id}")
int updateUser(User user);
/**
* Удалить пользователя
* @param userId
*/
@Delete("delete from user where id=#{uid} ")
int deleteUser(Integer userId);
/**
* Запросиспользовать агрегатную функцию
* @return
*/
@Select("select count(*) from user ")
int findTotalUser();
/**
* в соответствии спользовательимя Нечеткий Запрос
* @param username
* @return
*/
//@Select("select * from user where username like #{username} ")
@Select("select * from user where username like '%${value}%' ")
List<User> findUserByName(String username);
}
Results
指定Понятноidназад,接下来изResultMap
Можетпрямой引用这个Results
,например Опросить всех пользователейи Запрос单个пользовательизметод。
аннотацияверно应изxmlкартографирование Поле:
аннотация | xml | иллюстрировать |
---|---|---|
@Results | <resultMap> | Можно использовать один @Result аннотация,也Можетиспользовать@Result собирать<br>@Results({@Result(),@Result()})или@Results(@Result()) |
@Result | <id>или<result> | Введение атрибута: id данетдапервичный ключ Полеколонка Свойство имени столбца базы данных Имя атрибута, который необходимо собрать,является одним нуждатьсяиспользоватьиз@Oneаннотацияmany нуждатьсяиспользоватьиз@Manyаннотация |
@One | <assocation> | Используется для указания подзапроса для возврата одного объекта. Введение в свойство: выберите. Предназначен для многотабличных запросиз sqlmapperfetchType Запрос Способ,Отложенная загрузка или немедленная загрузка,会覆盖全局из Конфигурацияпараметр lazyLoadingEnabledиспользовать Формат:<br>@Result(column="",property="",one=@One(select="")) |
@Many | <collection> | используется для указания суб Запросвозвращатьсяобъектсобирать,свойствопредставлять:картографированиедокументсерединаизjavaType В целом ArrayList,аннотациясередина Может不определениеиспользовать Формат:<br>@Result(column="",property="",many=@Many(select="")) |
использовать@One
аннотациявыполнить一верно一关系картографирование
/**
* Все по Запросу账户,использовать延迟加载из Способ Запрос账户из所属пользователь
* @return
*/
@Select("select * from account")
@Results(id="accountMap",
value= {
@Result(id=true,column="id",property="id"),
@Result(column="uid",property="uid"),
@Result(column="money",property="money"),
@Result(column="uid",property="user",one=@One(select="com.itheima.dao.IUserDao.findById",fetchType=FetchType.LAZY))
})
List<Account> findAll();
использовать@Many
аннотациявыполнить一верно多关系картографирование
/**
* Опросить всех пользователей
* @return
*/
@Select("select * from user")
@Results(id="userMap",
value= {
@Result(id=true,column="id",property="userId"),
@Result(column="username",property="userName"),
@Result(column="sex",property="userSex"),
@Result(column="address",property="userAddress"),
@Result(column="birthday",property="userBirthday"),
@Result(column="id",property="accounts",many=@Many(select="com.itheima.dao.IAccountDao.findByUid",fetchType=FetchType.LAZY))
})
List<User> findAll();
1.существоватьSqlMapConfig.xml
середина Включи Кэш Поддержка L2
<!-- Конфигурация Кэш L2 -->
<settings>
<!-- Включи Кэш Поддержка L2 -->
<setting name="cacheEnabled" value="true"/>
</settings>
2.существоватьинтерфейс уровня персистентностисерединаиспользоватьаннотация Конфигурация Кэш L2
@CacheNamespace(blocking=true) //mybatis на основеаннотация Способвыполнить Конфигурация Кэш L2
public interface IUserDao {
...
}
Ссылки:
Подкаст Chuanzhi SSM Framework MyBatis Подробное объяснение серии Mybatis (5) Глава, посвященная Mybatis