Spring集成JPA和MyBatis例子

现在Spring流行基于Java的配置(JavaConfig),总体来说是充分利用隐式的bean发现机制和自动装配,结合Java显式配置,完成整个项目的配置。《Spring实战(第4版)》第2章和第3章详细介绍了这些技术。
本文根据第11章第11.3节借助Spring Data实现自动化的JPA Repository,整理了一个简单例子,记录下来。

本例子源代码下载地址为:
Spring集成JPA和MyBatis简单例子-20170622

一、用idea创建Maven项目
结构如下图所示
这里写图片描述
pom.xml配置如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.wu.demo.spring</groupId>
    <artifactId>jpamybatis</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>4.12</junit.version>
        <springframework.version>4.3.8.RELEASE</springframework.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.29</version>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.11.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.8.Final</version>
        </dependency>
    </dependencies>
</project>

数据源配置文件如下

jdbc.driver = org.postgresql.Driver
db.url = jdbc:postgresql://localhost:5432/test
db.username = postgres
db.password = postgres

initdb.sql不是项目必须的,只是用于建表测试,内容如下:

drop table if exists user_test;
create table user_test (
  id varchar(32) primary key,
  username varchar(32) not null,
  password varchar(32) not null
);

准备工作做完了。
二、创建User类

package com.wu.demo.spring.jpamybatis.bean;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;

@Entity
@Table(name="user_test")
public class User {

    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid")
    private String id;

    @Column
    private String username;

    @Column
    private String password;

    //此处节省篇幅,省略了get/set。
}

三、Dao包中,UserRepository继承JpaRepository。

package com.wu.demo.spring.jpamybatis.dao;

import com.wu.demo.spring.jpamybatis.bean.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, String>{
}

UserMapper接口如下:

package com.wu.demo.spring.jpamybatis.dao;

import com.wu.demo.spring.jpamybatis.bean.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;

public interface UserMapper {

    @Select(value="select * from user_test where username = #{username}")
    User getByUsername(@Param("username") String username);

    @SelectProvider(type = UserSqlProvider.class, method = "get")
    User get(@Param("username") String username, @Param("password") String password);

    @UpdateProvider(type = UserSqlProvider.class, method = "update")
    void update(User user);
}

UserSqlProvider如下:

package com.wu.demo.spring.jpamybatis.dao;

import com.alibaba.druid.util.StringUtils;
import com.wu.demo.spring.jpamybatis.bean.User;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * MyBatis动态SQL语句构建器,链式SQL构建始于version 3.4.2
 */
@Component
public class UserSqlProvider {

    /**
     * 根据用户名和密码查询
     * @param params
     * @return
     */
    public String get(Map<String, String> params){
        String username = params.get("username");
        String password = params.get("password");
        SQL sql = new SQL().SELECT("*").FROM("user_test");
        if(!StringUtils.isEmpty(username)){
            sql.WHERE("username=#{username}");
        }
        if(!StringUtils.isEmpty(password)){
            sql.WHERE("password=#{password}");
        }
        return sql.toString();
    }

    /**
     * 修改用户名和密码
     * @param user
     * @return
     */
    public String update(User user){
        SQL sql = new SQL().UPDATE("user_test").SET("username = #{username}, password = #{password}")
                .WHERE("id=#{id}");
        return sql.toString();
    }
}

四、Service如下

package com.wu.demo.spring.jpamybatis.service;

import com.wu.demo.spring.jpamybatis.bean.User;
import com.wu.demo.spring.jpamybatis.dao.UserMapper;
import com.wu.demo.spring.jpamybatis.dao.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserMapper userMapper;

    public void save(User user) {
        userRepository.save(user);
    }

    public User getByUsername(String username){
        return userMapper.getByUsername(username);
    }

    public User get(String username, String password){
        return userMapper.get(username, password);
    }

    public void update(User user){
        userMapper.update(user);
    }

    public void insertAndUpdate(){
        User o = new User();
        o.setUsername("guest");
        o.setPassword("guest123");
        save(o);//JPA保存用户

        User user = getByUsername("admin");
        user.setPassword("admin123456");
        update(user);//MyBatis修改用户

//        throw new RuntimeException(); //事务测试,抛出异常则全部回滚
    }
}

JpaTransactionManager可以同时管理JPA和MyBatis事务。

五、工程主配置文件AppConfig.java如下:

package com.wu.demo.spring.jpamybatis.conf;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;

@Configuration
@PropertySource(value={"classpath:jdbc.properties"})
@ComponentScan(basePackages = {"com.wu.demo.spring.jpamybatis.service"})
public class AppConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
        return new PropertySourcesPlaceholderConfigurer();
    }

}

数据源DataSourceConfig.java配置如下:

package com.wu.demo.spring.jpamybatis.conf;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    @Value("${jdbc.driver}")
    private String jdbcDriver;

    @Value("${db.url}")
    private String dbUrl;

    @Value("${db.username}")
    private String username;

    @Value("${db.password}")
    private String password;

    @Bean(destroyMethod = "close")
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(jdbcDriver);
        dataSource.setUrl(dbUrl);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

JPA和MyBatis配置DaoConfig.java如下:

package com.wu.demo.spring.jpamybatis.conf;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@Configuration
@EnableTransactionManagement
@Import({ DataSourceConfig.class })
@EnableJpaRepositories(entityManagerFactoryRef="entityManagerFactory", transactionManagerRef="jpaTransactionManager",
        basePackages = "com.wu.demo.spring.jpamybatis.dao")
@MapperScan("com.wu.demo.spring.jpamybatis.dao")//Mapper扫描
public class DaoConfig {

    @Bean
    public JpaVendorAdapter jpaVendorAdapter(){
        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setDatabase(Database.POSTGRESQL);
        adapter.setShowSql(true);
        adapter.setGenerateDdl(false);
        adapter.setDatabasePlatform("org.hibernate.dialect.HSQLDialect");
        return adapter;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource){
        LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean();
        emfb.setDataSource(dataSource);
        emfb.setJpaVendorAdapter(jpaVendorAdapter());
        emfb.setPackagesToScan("com.wu.demo.spring.jpamybatis.bean");
        return emfb;
    }

    @Bean
    public JpaTransactionManager jpaTransactionManager(DataSource dataSource) {
        JpaTransactionManager jtm = new JpaTransactionManager();
        jtm.setEntityManagerFactory(entityManagerFactory(dataSource).getObject());
        return jtm;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        return sessionFactory.getObject();
    }

}

六、测试类如下:

package com.wu.demo.spring.jpamybatis.test;
import com.wu.demo.spring.jpamybatis.bean.User;
import com.wu.demo.spring.jpamybatis.conf.AppConfig;
import com.wu.demo.spring.jpamybatis.conf.DataSourceConfig;
import com.wu.demo.spring.jpamybatis.conf.DaoConfig;
import com.wu.demo.spring.jpamybatis.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={AppConfig.class, DataSourceConfig.class, DaoConfig.class})
@Rollback(value = false)//关闭自动事务自动回滚
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void save(){
        User o = new User();
        o.setUsername("admin");
        o.setPassword("admin123");
        userService.save(o);
    }

    @Test
    public void getByUsername(){
        User o = userService.getByUsername("admin");
        System.out.println(o);
    }

    @Test
    public void get(){
        User o = userService.get("admin", "admin123");
        System.out.println(o);
    }

    @Test
    public void update(){
        User o = userService.getByUsername("admin");
        o.setUsername("admin2");
        o.setPassword("admin222");
        userService.update(o);
    }

    @Test
    public void insertAndUpdate(){
        userService.insertAndUpdate();
    }

}

本例子源代码下载地址为:
Spring集成JPA和MyBatis简单例子-20170622

参考资料如下:
1、Spring4.X + spring MVC + Mybatis3 零配置应用开发框架搭建详解
2、Spring Data JPA @EnableJpaRepositories配置详解
3、Spring事物管理器TransactionManager解析
4、《Spring实战(第4版)》
5、《Spring 3.x企业应用开发实战》

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值