数据库设计中,多对多一般如何处理?
1.数据库中的多对多关联关系一般需采用中间表的方式处理,将多对多转化为两个一对多。
数据库连接池的原理。为什么要使用连接池?
数据库连接池的原理。为什么要使用连接池?
a、数据库连接是一种关键的有限的昂贵的资源,对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的。 b、数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对 数据 库操作的性能。 c、 数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设 定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了 这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。
什么是领域模型(domain model)?贫血模型(anaemic domain model)和充血模型(rich domain model)有什么区别?
领域模型是领域内的概念类或现实世界中对象的可视化表示,又称为概念模型或分析对象模型,它专注于分析问题领域本身,发掘重要的业务领域概念,并建立业务领域概念之间的关系。
贫血模型是指使用的领域对象中只有setter和getter方法(POJO),所有的业务逻辑都不包含在领域对象中而是放在业务逻辑层。有人将我们这里说的贫血模型进一步划分成失血模型(领域对象完全没有业务逻辑)和贫血模型(领域对象有少量的业务逻辑),我们这里就不对此加以区分了。
充血模型将大多数业务逻辑和持久化放在领域对象中,业务逻辑(业务门面)只是完成对业务逻辑的封装、事务和权限等的处理。
如何配置配置事务增强?
事务增强一般写在aop的配置中,但也可以写在用注解来写。一般来说,用前者的话可以将整个工程的事务增强一次性配置好,而后者需要对每个需要事务增强的方法单独添加注解,所以一般来说写在通过aop配置事务增强是有效节省代码量的。
首先我们要引入spring配置文件中引入tx约束。
示例配置
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="PooledDataSource"></property> </bean> <aop:config> <aop:pointcut expression="execution(* com.xuxiao.crud.service..*(..))" id="txPoint"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/> </aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*"/> <tx:method name="get*" read-only="true"/> </tx:attributes> </tx:advice>
事务管理器
我们来一点点分析首先是,首先是定义事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="PooledDataSource"></property> </bean>
这里的PooledDataSource是我们在spring的ioc容器中配置的c3p0线程池的id,我们通过引入它来控制我们的数据源。 而bean id="transactionManager" 是我们在aop中要引入这个事务,所以给个id。 而class,正是我们要配置的到ioc容器中的事务管理器。 在spring的配置中配置数据源即dataSource、事务管理器,事务管理器使用不同的orm框架事务管理器类就不同,比如这里使用的是mybatis 所以是: org.springframework.jdbc.datasource.DataSourceTransactionManager 如果使用hibernate 则事务管理器类为: org.springframework.orm.hibernate3.HibernateTransactionManager 下面给个用Hibernate的例子
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
那么至此,我们的事务管理器就配好了,接下来我们来写具体的事务增强。
事务增强
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*"/> <tx:method name="get*" read-only="true"/> </tx:attributes> </tx:advice>
我们通过transaction-manager="transactionManager"来指定我们下面写的具体事务增强,是在刚刚写好的事务管理器之中的。然后留一个id给aop。 接下来我们在tx:attributes /tx:attributes标签中指定我们的具体事务增强。 在上面的代码中,我用<tx:method name="*"/>指定了,我们在aop中指定的扫描包的所有方法,均为事务方法。" read-only="true"/> 指定我们的方法中以get为名的方法是只读的。
其实在tx:attributes标签中能配置的比我写的要多,接下来给个比较全的样例,以及能配置的所有东西。
<tx:advice id="TestAdvice" transaction-manager="transactionManager"> <!--配置事务传播性,隔离级别以及超时回滚等问题 --> <tx:attributes> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="del*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="*" rollback-for="Exception" /> </tx:attributes> </tx:advice>
我们可以在标签中配置各种方法的隔离级别,传播性,以及回滚,超时等。 比如<tx:method name="*" rollback-for="Exception" />就是说,如果我们的方法在运行期出现异常,我们的事务将会回滚。 而" propagation="REQUIRED" />指的是我们以save开头的方法是代表支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
Spring中Bean的作用域有哪些?
-
singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例
-
prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例
-
request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效
-
session:对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效
-
globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效
Spring中自动装配的方式有哪些?
-
no:不进行自动装配,手动设置Bean的依赖关系。
-
byName:根据Bean的名字进行自动装配。
-
byType:根据Bean的类型进行自动装配。
-
constructor:类似于byType,不过是应用于构造器的参数,如果正好有一个Bean与构造器的参数类型相同则可以自动装配,否则会导致错误。
-
autodetect:如果有默认的构造器,则通过constructor的方式进行自动装配,否则使用byType的方式进行自动装配。
JDBC的最佳实践
使用PrearedStatement
使用ConnectionPool(连接池)
禁用自动提交
使用Batch Update
使用列名获取ResultSet中的数据,从而避免invalidColumIndexError
使用变量绑定而不是字符串拼接
要记住关闭Statement、PreparedStatement和Connection
选择合适的JDBC驱动
尽量使用标准的SQL语句,从而在某种程度上避免数据库对SQL支持的差异
使用正确的getXXX()方法
Spring支持的事务管理类型有哪些?你在项目中使用哪种方式?
事务管理器实现类 目标对象 DataSourceTransactionManager 注入DataSource HibernateTransactionManager 注入SessionFactory JdoTransactionManager 管理JDO事务 JtaTransactionManager 使用JTA管理事务 PersistenceBrokerTransactionManager 管理Apache的OJB事务
execute,executeQuery,executeUpdate的区别是什么?
\1. ResultSet executeQuery(String sql); 执行SQL查询,并返回ResultSet 对象。 2.int executeUpdate(String sql); 可执行增,删,改,返回执行受到影响的行数。 3.boolean execute(String sql); 可执行任何SQL语句,返回一个布尔值,表示是否返回ResultSet 。
你如何理解AOP中的连接点(Joinpoint)、切点(Pointcut)、增强(Advice)、引介(Introduction) 、织入(Weaving) 、切面(Aspect)这些概念?
切面(Aspect)
比较大的概念, 是指连接点的集合可以形成。所有功能的总称叫切面。
连接点(Joinpoint)
在Spring AOP中代表一个方法的执行程序执行的某个特定位置(如:某个方法调用前、调用后,方法抛出异常后)。一个类或一段程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就是连接点。Spring仅支持方法的连接点。
切点(Pointcut) 一些特定的连接点(根据切点表达式进行匹配的连接点)。如果连接点相当于数据中的记录,那么切点相当于查询条件,一个切点可以匹配多个连接点。Spring AOP的规则解析引擎负责解析切点所设定的查询条件,找到对应的连接点。
建议/增强(Advice)
针对特定连接点采取的操作。增强是织入到目标类连接点上的一段程序代码。Spring提供的增强接口都是带方位名的,如:BeforeAdvice、AfterReturningAdvice、ThrowsAdvice等。
引介(Introduction)
(为某个类)声明另外的方法或字段的代表类型
引介是一种特殊的增强,它为类添加一些属性和方法。这样,即使一个业务类原本没有实现某个接口,通过引介功能,可以动态的未该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。
织入(Weaving)
连接切面与其他应用类型或者对象来创建一个被建议过的对象(形成一个有Advice的原有对象的代理对象) 如何在Spring IoC容器中配置数据源?
DBCP配置:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>
<context:property-placeholder location="jdbc.properties"/> C3P0配置:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driverClassName}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>
<context:property-placeholder location="jdbc.properties"/>
Spring中如何使用注解来配置Bean?有哪些相关的注解?
首先需要在Spring配置文件中增加如下配置:
<context:component-scan base-package="org.example"/>
然后可以用@Component、@Controller、@Service、@Repository注解来标注需要由Spring IoC容器进行对象托管的类。这几个注解没有本质区别,只不过@Controller通常用于控制器,@Service通常用于业务逻辑类,@Repository通常用于仓储类(例如我们的DAO实现类),普通的类用@Component来标注。
依赖注入时如何注入集合属性?
可以在定义Bean属性时,通过<list>/<set>/<map>/<props>分别为其注入列表、集合、映射和键值都是字符串的映射属性。
阐述Spring框架中Bean的生命周期?
① Spring IoC容器找到关于Bean的定义并实例化该Bean。 ② Spring IoC容器对Bean进行依赖注入。 ③ 如果Bean实现了BeanNameAware接口,则将该Bean的id传给setBeanName方法。 ④ 如果Bean实现了BeanFactoryAware接口,则将BeanFactory对象传给setBeanFactory方法。 ⑤ 如果Bean实现了BeanPostProcessor接口,则调用其postProcessBeforeInitialization方法。 ⑥ 如果Bean实现了InitializingBean接口,则调用其afterPropertySet方法。 ⑦ 如果有和Bean关联的BeanPostProcessors对象,则这些对象的postProcessAfterInitialization方法被调用。 ⑧ 当销毁Bean实例时,如果Bean实现了DisposableBean接口,则调用其destroy方法。