文档章节

Spring笔记 - 访问数据库

Peter_Peng
 Peter_Peng
发布于 2015/07/16 14:26
字数 1135
阅读 40
收藏 1

1. 访问数据库

1.1 Spring的数据访问哲学

1.1.1 解耦数据访问层

- DAO皆为接口,面向接口编程

- DAO无关持久化技术

- Spring提供统一的数据访问异常体系,Spring提供的异常为非检查型异常,允许不捕获

1.1.2 数据访问模板化

- Spring将数据访问的相同部分抽象为模板,数据操作抽象为回调;前者包括连接管理、事务管理、资源管理和错误处理

- 模板例如JdbcTemplate


1.2 管理数据源

1.2.1 JNDI数据源

<!-- 在tomcat的server.xml中加入下面的配置,或在META-INF目录下面新建context.xml再加入下面的配置 -->
<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Resource name="jdbc/demoDb" auth="Container" type="javax.sql.DataSource"
        driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://localhost:3306/demo"
        username="root"
        password="123"
        maxActive="50"
        maxIdle="30"
        maxWait="10000"/>
</Context>
<!-- 创建数据源,方法1 -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">  
    <property name="jndiName">  
        <value>java:comp/env/jdbc/demoDb</value>  
    </property>  
</bean> 
<!-- 创建数据源,方法2 -->
<beans>
    <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/demoDb"/>
</beans>
// JavaConfig方式
@Bean
public JndiObjectFactoryBean dataSource() {
   JndiObjectFactoryBean jndiObjectFB = new JndiObjectFactoryBean();
   jndiObjectFB.setJndiName("jdbc/demoDb");
   jndiObjectFB.setResourceRef(true);
   jndiObjectFB.setProxyInterface(javax.sql.DataSource.class);
   return jndiObjectFB;
}

1.2.2 连接池

[参考]

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    <property name="url" value="${jdbc.url}"></property>
    <property name="username" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.password}"></property>
    <!-- 其他配置 ... -->
</bean>

1.2.3 JDBC数据源

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
    p:driverClassName="com.mysql.jdbc.Driver"
    p:url="${jdbc.url}"
    p:username="${jdbc.username}"
    p:password="${jdbc.password}" />


1.3 JDBC模板

包括JdbcTemplate、NamedParameterJdbcTemplate,还有一个从Spring 3.1开始已经过时的SimpleJdbcTemplate

// 定义一个JdbcTemplate
@Bean
public NamedParameterJdbcTemplate jdbcTemplate(DataSource dataSource) {
    return new NamedParameterJdbcTemplate(dataSource);
}
// 定义一个Repository
@Repository
public class UserRepository {
    private static final String sql = "select id, username from users where id=:id";
    
    @Resource("jdbcTemplate")
    NamedParameterJdbcTemplate jdbcTemplate; // 也可以使用JdbcOperations,JdbcTemplate实现了该接口,这样可以减少耦合
    
    public User findUser(int id) {
        Map params = new HashMap();
        params.put("id", id);
        return jdbcOperations.queryForObject(
            sql, new UserRowMapper(), params
        );
    }
    
    private static final class UserRowMapper implements RowMapper<Spitter> {
        public User mapRow(ResultSet rs, int rowNum) throws SQLException {
            return new User(
                rs.getLong("id"),
                rs.getString("username"));
        }
    }
}

// 运用Java8 lamdas改写上面的代码
    public User findUser(int id) {
        // params ...
        return jdbcOperations.queryForObject(
            "sql语句", (rs, rowNum) -> {
                return new User(
                    rs.getLong("id"),
                    rs.getString("username"));
            }, params
        );
    }


1.4 集成ORM - Hibernate

- ORM可以提供延迟加载、预先抓取、级联、缓存、分布式缓存、生成SQL等功能

- Spring集成ORM,可以提供声明式事务、异常处理、资源管理等功能

1.4.1 HibernateTemplate

HibernaateTemplate会造成repository和Spring的耦合,现在推荐在repository里面注入HibernateSessionFactory,以此获得session

@Repository
public class UserDaoImpl implements UserDao {
    HibernaateTemplate hibernaateTemplate;
    
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.hibernaateTemplate = new HibernaateTemplate(essionFactory);
    }
    
    public User findOne(int id) {
        return (User)this.hibernaateTemplate.get(User.class, id);
    }
}

1.4.2 Hibernate Session Factory

- Hibernate Session可以实现数据库数据的增删改查等功能

- Hibernate Session Factory可以开关并管理session

- Spring提供了org.springframework.orm.hibernate4.LocalSessionFactoryBean以获得Hibernate 4的session factory,与更早的版本不同,该版本可以同时支持xml和注解配置的Hibernate映射

// JavaConfig
@Bean
public LocalSessionFactoryBean sessionFactory(DataSource dataSource) {
    LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
    factory.setDataSource(dataSource);
    // 支持xml配置的Hibernate映射
    factory.setMappingSource(new String[] {"User.hbm.xml"});
    // 支持注解配置的Hibernate映射
    // factory.setPackagesToScan(new String[] {"x.y.z.domain"});
    Properties props = new Properties();
    props.setProperty("dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
    factory.setHibernateProperties(props);
    return factory;
}

// 让平台相关的异常自动转换成Spring统一的非检查型异常,需结合@Repository注解
@Bean
public BeanPostProcessor persistenceTranslation() {
    return new PersistenceExceptionTranslationPostProcessor();
}

// DAO
@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    SessionFactory sessionFactory;
    
    public User findOne(int id) {
        return (User)sessionFactory.getCurrentSession().get(User.class, id);
    }
    
    public User findByUsername(String username) {
        return (User) sessionFactory.getCurrentSession()
            .createCriteria(User.class)
            .add(Restrictions.eq("username", username))
            .list().get(0);
    }
}
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="mappingResources">
        <list>
            <value>x/y/z/domain/petclinic.hbm.xml</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <value>
            hibernate.dialect=${hibernate.dialect}
        </value>
    </property>
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>


1.5 集成ORM - JPA

- JPA是Java EE 5的标准ORM接口,也是ejb3规范的一部分

- JPA是规范,要使用JPA,需要借助其实现,例如Hibernate、EclipseLink、TopLink、OpenJpa等

- Hibernate的核心之一是Session,JPA相对应的核心是Entity Manager

- Spring集成JPA的好处[参考]

  • Spring使得 JPA 配置变得更加灵活。JPA 规范要求,配置文件必须命名为 persistence.xml,并存在于类路径下的 META-INF 目录中。该文件通常包含了初始化 JPA 引擎所需的全部信息。Spring 提供的 LocalContainerEntityManagerFactoryBean 提供了非常灵活的配置,persistence.xml 中的信息都可以在此以属性注入的方式提供。

  • Spring 实现了部分在 EJB 容器环境下才具有的功能,比如对 @PersistenceContext、@PersistenceUnit 的容器注入支持。

  • Spring 将 EntityManager 的创建与销毁、事务管理等代码抽取出来,并由其统一管理,开发者不需要关心这些,DAO只需关注领域对象的操作,开发者无需关心事务管理和 EntityManager 创建、销毁。


© 著作权归作者所有

共有 人打赏支持
Peter_Peng
粉丝 4
博文 8
码字总数 10793
作品 0
普陀
私信 提问
让Spring Security 来保护你的Spring Boot项目吧

参考资料: 书籍:Spring实战(第4版) 第9章和第14章 Spring Security 参考手册 初识 Spring Security 程序猿DD的Spring Security学习笔记 Spring Security 简介 Spring Security是一个能够为...

潇潇漓燃
2018/05/19
0
0
咕泡-装饰器 decorator 设计模式笔记

装饰器模式(Decorator) 应用场景:在我们的项目中遇到这样一个问题:我们的项目需要连接多个数据库,而且不同的客户在每 次访问中根据需要会去访问不同的数据库。我们以往在Spring 和Hiber...

职业搬砖20年
2018/09/04
0
0
Spring Boot学习笔记

多模块开发 [SpringBoot学习]-IDEA创建Gradle多Module结构的SpringBoot项目 RabbitMQ RabbitMQ 安装 linux安装RabbitMQ详细教程 Ubuntu 16.04 RabbitMq 安装与运行(安装篇) ubantu安装...

OSC_fly
2018/07/26
0
0
Spring实战读书笔记(1)

Spring的根本使命是? 简化Java开发 为了降低Java开发的复杂性,Spring采取了哪4种关键策略? 1、基于POJO的轻量级和最小侵入性编程 2、通过依赖注入和面向接口实现松耦合 3、基于切面和惯例...

祥林会跟你远走高飞
2014/12/30
0
0
Spring Batch学习笔记——steps之间共享数据

名词说明: 上下文: 执行: 执行上下文: 案例: 警告:一旦steps共享数据,这些数据就会把这些steps连接起来。努力使steps独立。如果你实在是不能独立他们,才使用下面的技术。你应该把数据...

xhujinjun
2015/04/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

AWS的自动部署工具codedeploy 部署前的准备工作

开始部署codedeploy: 1.先预置IAM用户: 创建一个IAM用户或使用一个与AWS相关联的用户; 复制以下的策略附加到IAM用户,向IAM用户赋予对codedeploy(及codedeploy所依赖的AWS服务和操作)的...

守护-创造
23分钟前
0
0
这可能是最详细的一线大厂Mysql面试题详解了

1、MySQL的复制原理以及流程 基本原理流程,3个线程以及之间的关联; 主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中; 从:io线程——在使用start slave 之后...

Java干货分享
33分钟前
1
0
人的精力是什么?如何强化精力

人的精力是什么? 人的精力是什么? 精力指精神和体力。精神包括一个人的精神状态,兴奋度,做事情的投入度,专注度,持续时间等。 人的精力来源 人的精力有4种来源,身体的、情感的、思想的和...

莫库什勒
52分钟前
1
0
JFinal开发的旅游线路营销Saas平台演示系统我部署了一个

今天部署了一个旅游线路营销管理系统的演示版: 演示地址:http://lvyou.jfinalxueyuan.com 演示账号:(暂时只给一个门店版的吧,批发商和总部的如果需要 演示看看 单独联系我微信:1876673...

山东-小木
今天
2
0
如何学习大数据技术

学习大数据技术,首先要明确大数据的概念。 大数据的概念作者认为有如下几点: 1.数据的来源多样性。例如关系数据库+文本+excel等 2.数据量大。TB级别的数据。 3.业务应用领域。实时性高与实...

董黎明
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部