rainit2006 / My_AWS-Cloud

0 stars 0 forks source link

JPA/Hibernate/Mybatis #16

Open rainit2006 opened 6 years ago

rainit2006 commented 6 years ago

image

rainit2006 commented 6 years ago

POJO Plain Old Java Object (POJO) は、あるJavaオブジェクトがEJB(特にEJB 3より前のEJB)のように特殊なものではなく、ごく普通のJavaオブジェクトであることを強調した名称。 設計はシンプルであればあるほど良いと主張する人たちが好んで使用する。

Hibernate, JPA, @PersistenceContext ■基本概念 hibernate是持久化实现技术,而jpa是持久化的标准,一个是具体实现,一个是接口协议,当然springdata jpa是在hibernate的基础上更上层的封装实现。

JPA是ORM规范,hibernate是ORM实现。

目前比较成熟的 JPA 框架主要包括 Jboss 的 Hibernate EntityManager、Oracle 捐献给 Eclipse 社区的 EclipseLink、Apache 的 OpenJPA 等。

■参考サイト ・非常好的JPA说明网页 https://terasolunaorg.github.io/guideline/public_review/ArchitectureInDetail/DataAccessJpa.html#pom-xml ・Hibernate项目的入门实例指导: http://www.byteslounge.com/tutorials/spring-jpa-hibernate-example

Java EEでは @PersistenceContext アノテーション (javax.persistenceパッケージにある) を用いることによって、コンテナから Beanに対して自動的に EntityManager (Factoryじゃなく、さっそく使える方)をインジェクトしてもらえる.

**Bean定義ファイルに追加する内容**
<bean id="entityManager"
    class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

**EntityManagerをインジェクトされる側**
private EntityManager entityManager;
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
}

■JPA基本用語

■Spring Data JPA 「Spring Data JPA」では、メソッド名を命名規則に従って実装することでSQL文が自動で作成されます。今回実装した例では、「findBy”カラム名”」で「SELECT u FROM User u WHERE id = ?」になり、メソッドの引数が「?」に代入されることになります。

「Spring Data JPA」の命名規則に関しては下記URLの「Table 2.3. Supported keywords inside method names」を確認してください。 URL:http://docs.spring.io/spring-data/data-jpa/docs/1.4.3.RELEASE/reference/html/jpa.repositories.html#jpa.query-methods

■ jpaVendorAdapter:JPAベンダーアダプタというものを指定します。ここでは、HibernateJpaVendorAdapterクラスのBeanを用意しておきます。 persistenceUnitName: packagesToScan

rainit2006 commented 6 years ago

image image image image image

image image image

image

rainit2006 commented 6 years ago

JPA 一个简单的 JPA 示例 https://www.ibm.com/developerworks/cn/opensource/os-cn-spring-jpa/index.html 示例主要涉及七个文件,但是很清晰:业务层包含一个接口和一个实现;持久层包含一个接口、一个实现、一个实体类;另外加上一个 JPA 配置文件和一个测试类。

  1. 实体类 AccountInfo.java 用到@Entity ,@Table(name = "t_accountinfo") ,class名为 public class AccountInfo implements Serializable 。
    1. 业务层接口 UserService.java 包含一个方法 :AccountInfo createNewAccount(String user, String pwd, Integer init); 3,业务层的实现类 UserServiceImpl.java
      
      private UserDao userDao = new UserDaoImpl(); 

public AccountInfo createNewAccount(String user, String pwd, Integer init){ // 封装域对象 AccountInfo accountInfo = new AccountInfo(); UserInfo userInfo = new UserInfo(); userInfo.setUsername(username); userInfo.setPassword(password); accountInfo.setBalance(initBalance); accountInfo.setUserInfo(userInfo); // 调用持久层,完成数据的保存 return userDao.save(accountInfo); }

 4. 持久层接口

public interface UserDao { public AccountInfo save(AccountInfo accountInfo); }

5. 持久层的实现类

public class UserDaoImpl implements UserDao { public AccountInfo save(AccountInfo accountInfo) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("SimplePU"); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); em.persist(accountInfo); em.getTransaction().commit(); emf.close(); return accountInfo; } }

 6. JPA 标准配置文件 persistence.xml
 7. 本文使用如下的 main 方法进行开发者测试
`new UserServiceImpl().createNewAccount("ZhangJianPing", "123456", 1); `

 **Spring 框架对 JPA 的支持**
业务层接口 UserService 保持不变,UserServiceImpl 中增加了三个注解,以让 Spring 完成依赖注入,因此不再需要使用 new 操作符创建 UserDaoImpl 对象了。同时我们还使用了 Spring 的声明式事务:

8. 配置为 Spring Bean 的业务层实现

@Service("userService") public class UserServiceImpl implements UserService { @Autowired private UserDao userDao;

@Transactional public AccountInfo createNewAccount( String name, String pwd, Integer init) { …… } }

对于持久层,UserDao 接口也不需要修改,只需修改 UserDaoImpl 实现,修改后的代码如下:
9. 配置为 Spring Bean 的持久层实现

@Repository("userDao") public class UserDaoImpl implements UserDao {

@PersistenceContext private EntityManager em;

@Transactional public Long save(AccountInfo accountInfo) { em.persist(accountInfo); return accountInfo.getAccountId(); } }


10. Spring 配置文件

<?xml version="1.0" encoding="UTF-8"?>

11. 改造后的基于 Spring 的开发者测试代码

public class SimpleSpringJpaDemo{ public static void main(String[] args){ ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-demo-cfg.xml"); UserDao userDao = ctx.getBean("userDao", UserDao.class); userDao.createNewAccount("ZhangJianPing", "123456", 1); } }


通过对比重构前后的代码,可以发现 Spring 对 JPA 的简化已经非常出色了,我们可以大致总结一下 Spring 框架对 JPA 提供的支持主要体现在如下几个方面:
- 首先,它使得 JPA 配置变得更加灵活。JPA 规范要求,配置文件必须命名为 persistence.xml,并存在于类路径下的 META-INF 目录中。该文件通常包含了初始化 JPA 引擎所需的全部信息。Spring 提供的 LocalContainerEntityManagerFactoryBean 提供了非常灵活的配置,persistence.xml 中的信息都可以在此以属性注入的方式提供。
- 其次,Spring 实现了部分在 EJB 容器环境下才具有的功能,比如对 @PersistenceContext、@PersistenceUnit 的容器注入支持。
- 第三,也是最具意义的,Spring 将 EntityManager 的创建与销毁、事务管理等代码抽取出来,并由其统一管理,开发者不需要关心这些,如前面的代码所示,业务方法中只剩下操作领域对象的代码,事务管理和 EntityManager 创建、销毁的代码都不再需要开发者关心了。

**更进一步:Spring Data JPA 让一切近乎完美**
Spring 开发小组并没有止步,他们再接再厉,于最近推出了 Spring Data JPA 框架,主要针对的就是 Spring 唯一没有简化到的业务逻辑代码,至此,开发者连仅剩的实现持久层业务逻辑的工作都省了,唯一要做的,就只是声明持久层的接口,其他都交给 Spring Data JPA 来帮你完成!
框架是怎么做到的呢?其实这背后的思想并不复杂,比如,当你看到 UserDao.findUserById() 这样一个方法声明,大致应该能判断出这是根据给定条件的 ID 查询出满足条件的 User 对象。Spring Data JPA 做的便是规范方法的名字,根据符合规范的名字来确定方法需要实现什么样的逻辑。

在着手写代码之前,开发者需要先 下载Spring Data JPA 的发布包(需要同时下载 Spring Data Commons 和 Spring Data JPA 两个发布包,Commons 是 Spring Data 的公共基础包),并把相关的依赖 JAR 文件加入到 CLASSPATH 中。
首先,让持久层接口 UserDao 继承 Repository 接口。该接口使用了泛型,需要为其提供两个类型:第一个为该接口处理的域对象类型,第二个为该域对象的主键类型。修改后的 UserDao 如下:
12. Spring Data JPA 风格的持久层接口

public interface UserDao extends Repository<AccountInfo, Long> { public AccountInfo save(AccountInfo accountInfo); }

然后删除 UserDaoImpl 类,因为我们前面说过,框架会为我们完成业务逻辑。最后,我们需要在 Spring 配置文件中增加如下配置,以使 Spring 识别出需要为其实现的持久层接口:
13. 在 Spring 配置文件中启用扫描并自动创建代理的功能

<-- 需要在 标签中增加对 jpa 命名空间的引用 --> <jpa:repositories base-package="footmark.springdata.jpa.dao" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager"/>


**JPA (Java Persistence API)のアノテーション**
![image](https://user-images.githubusercontent.com/12871721/32977112-3a0a10ea-cc6a-11e7-8ab7-af577e3ae38c.png)

JPAにおけるアノテーションの使用例を示す。

@Entity @Table(name = "EMPLOYEE") public class Employee { @Id @GeneratedValue @Column(name = "EMPNO") private Long empno;


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
rainit2006 commented 6 years ago

■ JPAのクエリー実装方法 JPAでは EntityManage を使用してクエリーを構築/実行するが、主な実装方法は以下の通り。

■ Spring Data JPA のクエリー実装方法 Spring Data JPA では Repositoryインターフェイスにメソッドを定義することでクエリーが作成される。

UserRepository.java
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
    public User findByName(String name);
    public User findByEmail(String email);
    :

Repositoryのスーパーインターフェイスには以下が用意されている。

org.springframework.data.repository.CrudRepository
org.springframework.data.repository.PagingAndSortingRepository
org.springframework.data.jpa.repository.JpaRepository
org.springframework.data.jpa.repository.JpaSpecificationExecutor

JpaRepositoryには標準的なCRUD操作を行うメソッドが用意されている。 通常はJpaRepositoryだけ使用すれば良いが、後述のSpecificationを使用する場合はJpaSpecificationExecutorも併用する。

標準のメソッド以外のクエリーを作るには、Repositoryインターフェイスにクエリーメソッドを追加する。 クエリーメソッドの実装方法は以下の通り。

rainit2006 commented 6 years ago

■Spring中的JdbcTemplate http://www.cnblogs.com/lichenwei/p/3902294.html 接触过JAVA WEB开发的朋友肯定都知道Hibernate框架,虽然不否定它的强大之处,但个人对它一直无感,总感觉不够灵活,太过臃肿了。 今天来说下Spring中关于JDBC的一个辅助类(JDBC Template),它封装了JDBC的操作,使用起来非常方便。

详情看:http://www.cnblogs.com/lichenwei/p/3902294.html


JndiDataSourceLookup().getDataSource() HibernateJpaVendorAdapter

LocalContainerEntityManagerFactoryBean setPackagesToScan

rainit2006 commented 6 years ago

实体关系映射 https://builder.japan.zdnet.com/sp_oracle/35067018/2/

JPAのオブジェクト/リレーショナル・マッピングには、次の5つのタイプがあります。 One-to-One(片方向) One-to-Many(片方向) One-to-One(双方向) One-to-Many/Many-to-One (双方向) Many-to-Many(双方向)

■(1) One to One (片方) image

■(2) One-to-Many(片方向)のマッピング 「One-to-Many(1対多)」のマッピングは、例えば1つの「注文(Cart)」に複数の「注文明細(Orderline)」をひも付けるといった場合に使用します。 このタイプのエンティティを定義する際のポイント: 指定の方法は、「@OneToMany(cascade = {…略…})」と「@ManyToOne(cascade = {…略…})」のどちらでもかまいません。 image

■ (3) One-to-One(双方向)のマッピング image ポイント: ・データベース操作を実行するクラスに「@OneToOne(cascade = {…略…})」を付ける ・いずれかのクラスに「@OneToOne(mappedBy = …略…)」を付ける image

双向关联,必须设置mappedBy属性,因为双向关联只能交给一方去控制,不可能在双方都设置外键保存关联关系,否则双方都无法保存. "mappedBy=xxxx"表示把控制权交给xxxx. @OneToOneのmappedBy属性にエンティティAでエンティティBを参照する永続化プロパティ(またはフィールド)名を指定します。

■(4)One-to-Many/Many-to-One(双方向) 「Cart(注文)」と「Orderline(注文明細)」の関係を例にとって表すと、「1つ1つのOrderlineにCartの情報を持たせ、明細を見れば、どの注文かがわかるようにする」といった具合になります。 image 「One-to-One(双方向)」の場合とは異なり、mappedByの指定は必ず「One-to-ManyのMany側」に記述します。 image

■(5)Many-to-Many(双方向) 例えば「俳優(Actor)」と「映画(Movie)」を関連付ける場合などが考えられます。 image

image

rainit2006 commented 6 years ago

CascadeType(级联操作) http://www.jianshu.com/p/e8caafce5445 Cascade操作是什么? 经过实践检验,我的理解是:给当前设置的实体操作另一个实体的权限。

public class Student {
    @ManyToMany(cascade=CascadeType.PERSIST,fetch=FetchType.LAZY)
    private Set<Course> courses = new HashSet<>();
    //其他代码略。
}

可以看到,我们在上面的代码中给了Student对Course进行级联保存(cascade=CascadeType.PERSIST)的权限。此时,若Student实体持有的Course实体在数据库中不存在时,保存该Student时,系统将自动在Course实体对应的数据库中保存这条Course数据。而如果没有这个权限,则无法保存该Course数据。

image


FetchType ■FetchType.LAZY 延迟加载,在查询实体A时,不查询出关联实体B,在调用getxxx方法时,才加载关联实体,但是注意,查询实体A时和getxxx必须在同一个Transaction中,不然会报错:no session

■FetchType.EAGER 饥饿加载,在查询实体A时,查询出关联的实体B

rainit2006 commented 6 years ago

Spring Data Spring Data 是 Spring 的一个子项目。用于简化数据库访问,支持NoSQL 和 关系数据存储。

■入门教程 https://www.ibm.com/developerworks/cn/opensource/os-cn-spring-jpa/index.html

JPA Spring Data : 致力于减少数据访问层 (DAO) 的开发量。开发者只要写好持久层接口就好,然后其它的框架会帮程序员实现。

实现步骤: 1.配置 Spring 整合 JPA 2.在 Spring 配置文件中配置 Spring Data,让 Spring 为声明的接口创建代理对象。 3.声明持久层的接口,该接口继承 Repository 4.在接口中声明需要的方法 同时下载 Spring Data Commons 和 Spring Data JPA 两个发布包,也可以在maven里配置

<dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>${spring-data-jpa.version}</version>
</dependency>

写个接口Repository:

public interface UserRepository extends Repository<User,Integer>{
    User getByUserId(Integer id);
}

Repository接口概述: (1)Repository 接口是 Spring Data 的一个核心接口,它不提供任何方法,开发者需要在自己定义的接口中声明需要的方法 public interface Repository<T, ID extends Serializable> { } (2)Spring Data可以让我们只定义接口,只要遵循 Spring Data的规范,就无需写实现类。 (3)与继承 Repository 等价的一种方式,就是在持久层接口上使用 @RepositoryDefinition 注解,并为其指定 domainClass 和 idClass 属性。

按照 Spring Data 的规范,查询方法以 find | read | get 开头, 涉及条件查询时,条件的属性用条件关键字连接,要注意的是:条件属性以首字母大写。

■查询方法解析: 假如创建如下的查询:findByUserDepUuid(),框架在解析该方法时,首先剔除 findBy,然后对剩下的属性进行解析,假设查询实体为Doc (1)先判断 userDepUuid (根据 POJO 规范,首字母变为小写)是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第二步; (2)从右往左截取第一个大写字母开头的字符串(此处为Uuid),然后检查剩下的字符串是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设 user 为查询实体的一个属性; (3)接着处理剩下部分(DepUuid),先判断 user 所对应的类型是否有depUuid属性,如果有,则表示该方法最终是根据 “ Doc.user.depUuid” 的取值进行查询;否则继续按照步骤 2 的规则从右往左截取,最终表示根据 “Doc.user.dep.uuid” 的值进行查询。 (4)可能会存在一种特殊情况,比如 Doc包含一个 user 的属性,也有一个 userDep 属性,此时会存在混淆。可以明确在属性之间加上 "_" 以显式表达意图,比如 "findByUser_DepUuid()" 或者 "findByUserDep_uuid()" 特殊的参数: 还可以直接在方法的参数上加入分页或排序的参数,比如: Page findByName(String name, Pageable pageable); List findByName(String name, Sort sort);

■使用 @Query 注解 @Query来指定本地查询 我们可以使用@Query标注轻松的使用类似sql查询的功能。 JpaRepositoryを継承したインターフェースで@Queryを使ってネイティブなSQLを書いていきます! @Queryをつけたメソッドを呼び出すことで@Queryに書いているSQLが実行されます。 http://javatechnology.net/spring/jpa-annotation-query/ 気をつけるポイント:上記のSQLですが、よーく見てみて下さい。テーブル名やカラム名がエンティティクラスのクラス名とフィールド名になっていますね。

rainit2006 commented 6 years ago

@JoinTable 次のクラスに設定する結合表を指定するアノテーションです。 ・ManyToManyリレーションシップを指定する場合の所有者側のクラス ・片方向のOneToManyリレーションシップを持つクラス name属性が指定されない場合,結合表の名前は次の名称になります。 <所有者側テーブル名>_<被所有者側テーブル名> 適用可能要素は,メソッドとフィールドです。

@JoinColumn エンティティクラス間の関連づけをする場合に,結合表のための外部キーカラムまたは外部キーカラムによって参照された,結合先テーブルのカラム名を指定するアノテーションです。必ず結合先テーブルのプライマリキーとなっているカラムを指定してください。 複数の外部キーカラムがある場合は@JoinColumnsを使用し,それぞれの関連に対して@JoinColumnを指定してください。

@PrimaryKeyJoinColumn ほかのテーブルと結合する場合に外部キーとして使われるカラムを指定するアノテーションです。次の場合に使用します。 1、継承マッピング戦略のJOINED戦略で,エンティティのスーパークラスのプライマリキーとサブクラスのプライマリキーが異なる名前の場合 2、@SecondaryTableで,プライマリテーブルとセカンダリテーブルを結合する場合※ 3、OneToOneリレーションシップで,被所有者側のエンティティクラスのプライマリキーが外部キーとして使用されている場合

rainit2006 commented 6 years ago

all spring and hibernate versions are not compatible。 If you are using some other versions and getting java.lang.NoClassDefFoundError, then it means that they are not compatible. Mostly it’s because Hibernate classes are moved from one package to another causing this error. For example org.hibernate.engine.FilterDefinition class is moved to org.hibernate.engine.spi.FilterDefinition in latest hibernate versions.

Spring version is 4.1.7.RELEASE which does not support hibernate 5. Hibernate 5 is supported in 4.2.x plus version of Spring.

rainit2006 commented 6 years ago

C3P0 https://baike.baidu.com/item/c3p0 C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。

c3p0与dbcp区别 dbcp没有自动回收空闲连接的功能 c3p0有自动回收空闲连接功能。

rainit2006 commented 6 years ago

Mybatis

入门Sample http://ziqoo.com/wiki/index.php?mybatis%20%A5%B5%A5%F3%A5%D7%A5%EB%CD%D1%A5%D7%A5%ED%A5%B8%A5%A7%A5%AF%A5%C8%BA%EE%C0%AE 关键点:

<?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">

insert into emp (emp_no, e_name, job, mgr, hire_date, sal, comm, dept_no) values (#{empNo,jdbcType=INTEGER}, #{eName,jdbcType=VARCHAR}, #{job,jdbcType=VARCHAR}, #{mgr,jdbcType=INTEGER}, #{hireDate,jdbcType=DATE}, #{sal,jdbcType=NUMERIC}, #{comm,jdbcType=NUMERIC}, #{deptNo,jdbcType=INTEGER})
- 設定ファイル作成

例) src/main/resources/com/ziqoo/mybatisSample/mybatis-config.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">


- Mapperインターフェースの作成

package com.ziqoo.mybatisSample.mapper; import com.ziqoo.mybatisSample.entity.Emp; public interface EmpMapper { Emp getEmp(int userId); ★和Mapper XML文件里的id相对应 int insert(Emp record); ★和Mapper XML文件里的id相对应 }

- エンティティクラス作成

package com.ziqoo.mybatisSample.entity;

public class Emp { private Integer userId; private String userName;

public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } }


- Main函数

public static void main( String[] args ) throws IOException { String resource = "com/ziqoo/mybatisSample/mybatis-config.xml"; InputStream in = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);

    SqlSession session = sqlSessionFactory.openSession();
    try {
        EmpMapper mapper = session.getMapper(EmpMapper.class);
        Emp emp = mapper.getEmp(1000);
        System.out.println("userName:"+emp.getUserName());
        emp.setEmpNo(8000);
        emp.seteName("山田");
        mapper.insert(emp);

        session.commit();
    } finally {
        session.close();
    }
}
rainit2006 commented 6 years ago

MyBatis-Spring このライブラリを使えば、MyBatis のステートメントを Spring のトランザクション内で実行することもできますし、Mapper や SqlSession の生成、他の Bean への注入、MyBatis の例外から Spring の DataAccessException への変換、さらには MyBatis や Spring, MyBatis-Spring に依存しないコードでアプリケーションを構築することも可能になります。

image

配置手顺: http://www.mybatis.org/spring/ja/getting-started.html Maven をお使いの場合は、 pom.xml に次の dependency を追加してください。

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis-spring</artifactId>
  <version>x.x.x</version>
</dependency>

MyBatis と Spring を組み合わせて使う場合、Spring の Application Context 内に少なくとも SqlSessionFactory と一つ以上の Mapper インターフェイスを定義する必要があります。 MyBatis-Spring では SqlSessionFactory の生成に SqlSessionFactoryBean を使います。この Factory Bean を設定するため、Spring の XML 設定ファイルに次の Bean を追加してください。

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
</bean>

Mapper インターフェイスが次のように定義されている場合...

public interface UserMapper {
  @Select("SELECT * FROM users WHERE id = #{userId}")
  User getUser(@Param("userId") String userId);
} 

MapperFactoryBean を使ってこのインターフェイスを Spring に登録する場合、以下のように設定します。

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
  <property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
  <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

ここで指定した Mapper は、実装クラスではなく インターフェイス である必要がありますので注意してください。

この例では、アノテーションを使って SQL を指定していますが、Mapper XML ファイルを使うこともできます。

MapperFactoryBean は SqlSession の生成とクローズを行います。 もし Spring のトランザクション内で実行された場合は、トランザクション終了時にセッションがコミットあるいはロールバックされます。 最後にもう一点、全ての例外は Spring の DataAccessException に変換されます。

MyBatis のデータメソッドは、一行だけで実行可能となります。

public class FooServiceImpl implements FooService {

private UserMapper userMapper;

public void setUserMapper(UserMapper userMapper) {
  this.userMapper = userMapper;
}

public User doSomeBusinessStuff(String userId) {
  return this.userMapper.getUser(userId);
}