对ORM的支持 之 8.4 集成JPA ——跟我学spring3
8.4 集成JPA
JPA全称为Java持久性API(Java Persistence API),JPA是Java EE 5标准之一,是一个ORM规范,由厂商来实现该规范,目前有Hibernate、OpenJPA、TopLink、EclipseJPA等实现。
8.4.1 如何集成
Spring目前提供集成Hibernate、OpenJPA、TopLink、EclipseJPA四个JPA标准实现。
Spring通过使用如下Bean进行集成JPA(EntityManagerFactory):
- LocalEntityManagerFactoryBean:适用于那些仅使用JPA进行数据访问的项目,该FactoryBean将根据JPA PersistenceProvider自动检测配置文件进行工作,一般从“META-INF/persistence.xml”读取配置信息,这种方式最简单,但不能设置Spring中定义的DataSource,且不支持Spring管理的全局事务,而且JPA 实现商可能在JVM启动时依赖于VM agent从而允许它们进行持久化类字节码转换(不同的实现厂商要求不同,需要时阅读其文档),不建议使用这种方式;
 
persistenceUnitName:指定持久化单元的名称;
使用方式:
- <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
 - <property name="persistenceUnitName" value="persistenceUnit"/>
 - </bean>
 
- 从JNDI中获取:用于从Java EE服务器获取指定的EntityManagerFactory,这种方式在进行Spring事务管理时一般要使用JTA事务管理;
 
使用方式:
- <beans xmlns="http://www.springframework.org/schema/beans"
 - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 - xmlns:jee="http://www.springframework.org/schema/jee"
 - xsi:schemaLocation="
 - http://www.springframework.org/schema/beans
 - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 - http://www.springframework.org/schema/jee
 - http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
 - <jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/persistenceUnit"/>
 - </beans>
 
此处需要使用“jee”命名标签,且使用<jee:jndi-lookup>标签进行JNDI查找,“jndi-name”属性用于指定JNDI名字。
- LocalContainerEntityManagerFactoryBean:适用于所有环境的FactoryBean,能全面控制EntityManagerFactory配置,如指定Spring定义的DataSource等等。
 
persistenceUnitManager:用于获取JPA持久化单元,默认实现DefaultPersistenceUnitManager用于解决多配置文件情况
dataSource:用于指定Spring定义的数据源;
persistenceXmlLocation:用于指定JPA配置文件,对于对配置文件情况请选择设置persistenceUnitManager属性来解决;
persistenceUnitName:用于指定持久化单元名字;
persistenceProvider:用于指定持久化实现厂商类;如Hibernate为org.hibernate.ejb.HibernatePersistence类;
jpaVendorAdapter:用于设置实现厂商JPA实现的特定属性,如设置Hibernate的是否自动生成DDL的属性generateDdl;这些属性是厂商特定的,因此最好在这里设置;目前Spring提供HibernateJpaVendorAdapter、OpenJpaVendorAdapter、EclipseLinkJpaVendorAdapter、TopLinkJpaVendorAdapter、OpenJpaVendorAdapter四个实现。其中最重要的属性是“database”,用来指定使用的数据库类型,从而能根据数据库类型来决定比如如何将数据库特定异常转换为Spring的一致性异常,目前支持如下数据库(DB2、DERBY、H2、HSQL、INFORMIX、MYSQL、ORACLE、POSTGRESQL、SQL_SERVER、SYBASE)。
jpaDialect:用于指定一些高级特性,如事务管理,获取具有事务功能的连接对象等,目前Spring提供HibernateJpaDialect、OpenJpaDialect 、EclipseLinkJpaDialect、TopLinkJpaDialect、和DefaultJpaDialect实现,注意DefaultJpaDialect不提供任何功能,因此在使用特定实现厂商JPA实现时需要指定JpaDialect实现,如使用Hibernate就使用HibernateJpaDialect。当指定jpaVendorAdapter属性时可以不指定jpaDialect,会自动设置相应的JpaDialect实现;
jpaProperties和jpaPropertyMap:指定JPA属性;如Hibernate中指定是否显示SQL的“hibernate.show_sql”属性,对于jpaProperties设置的属性自动会放进jpaPropertyMap中;
loadTimeWeaver:用于指定LoadTimeWeaver实现,从而允许JPA 加载时修改相应的类文件。具体使用得参考相应的JPA规范实现厂商文档,如Hibernate就不需要指定loadTimeWeaver。
接下来学习一下Spring如何集成JPA吧:
1、准备jar包,从下载的hibernate-distribution-3.6.0.Final包中获取如下Hibernate需要的jar包从而支持JPA:
| 
 lib\jpa\hibernate-jpa-2.0-api-1.0.0.Final.jar //用于支持JPA  | 
2、对象模型定义,此处使用UserModel2:
- package cn.javass.spring.chapter8;
 - //省略import
 - @Entity
 - @Table(name = "test")
 - public class UserModel2 {
 - @Id @GeneratedValue(strategy = GenerationType.AUTO)
 - private int id;
 - @Column(name = "name")
 - private String myName;
 - //省略getter和setter
 - }
 
注意此处使用的所有注解都是位于javax.persistence包下,如使用@org.hibernate.annotations.Entity 而非@javax.persistence. Entity将导致JPA不能正常工作。
1、 JPA配置定义(chapter8/persistence.xml),定义对象和数据库之间的映射:
- <?xml version="1.0" encoding="UTF-8"?>
 - <persistence version="1.0"
 - xmlns="http://java.sun.com/xml/ns/persistence"
 - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 - xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
 - <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL"/>
 - </persistence>
 
在JPA配置文件中,我们指定要持久化单元名字,和事务类型,其他都将在Spring中配置。
2、 数据源定义,此处使用第7章的配置文件,即“chapter7/ applicationContext-resources.xml”文件。
3、 EntityManagerFactory配置定义(chapter8/applicationContext-jpa.xml):
- <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
 - <property name="dataSource" ref="dataSource"/>
 - <property name="persistenceXmlLocation" value="chapter8/persistence.xml"/>
 - <property name="persistenceUnitName" value="persistenceUnit"/>
 - <property name="persistenceProvider" ref="persistenceProvider"/>
 - <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
 - <property name="jpaDialect" ref="jpaDialect"/>
 - <property name="jpaProperties">
 - <props>
 - <prop key="hibernate.show_sql">true</prop>
 - </props>
 - </property>
 - </bean>
 - <bean id="persistenceProvider" class="org.hibernate.ejb.HibernatePersistence"/>
 
- <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
 - <property name="generateDdl" value="false" />
 - <property name="database" value="HSQL"/>
 - </bean>
 - <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
 
- LocalContainerEntityManagerFactoryBean:指定使用本地容器管理EntityManagerFactory,从而进行细粒度控制;
 - dataSource属性指定使用Spring定义的数据源;
 - persistenceXmlLocation指定JPA配置文件为chapter8/persistence.xml,且该配置文件非常简单,具体配置完全在Spring中进行;
 - persistenceUnitName指定持久化单元名字,即JPA配置文件中指定的;
 - persistenceProvider:指定JPA持久化提供商,此处使用Hibernate实现HibernatePersistence类;
 - jpaVendorAdapter:指定实现厂商专用特性,即generateDdl= false表示不自动生成DDL,database= HSQL表示使用hsqldb数据库;
 - jpaDialect:如果指定jpaVendorAdapter此属性可选,此处为HibernateJpaDialect;
 - jpaProperties:此处指定“hibernate.show_sql =true”表示在日志系统debug级别下将打印所有生成的SQL。
 
4、 获取EntityManagerFactory:
- package cn.javass.spring.chapter8;
 - //省略import
 - public class JPATest {
 - private static EntityManagerFactory entityManagerFactory;
 - @BeforeClass
 - public static void setUpClass() {
 - String[] configLocations = new String[] {
 - "classpath:chapter7/applicationContext-resources.xml",
 - "classpath:chapter8/applicationContext-jpa.xml"};
 - ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocations);
 - entityManagerFactory = ctx.getBean(EntityManagerFactory.class);
 - }
 - }
 
此处我们使用了chapter7/applicationContext-resources.xml定义的“dataSource”数据源,通过ctx.getBean(EntityManagerFactory.class)获取EntityManagerFactory。
5、 通过EntityManagerFactory获取EntityManager进行创建和删除表:
- @Before
 - public void setUp() throws SQLException {
 - //id自增主键从0开始
 - String createTableSql = "create memory table test" + "(id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, " + "name varchar(100))";
 - executeSql(createTableSql);
 - }
 - @After
 - public void tearDown() throws SQLException {
 - String dropTableSql = "drop table test";
 - executeSql(dropTableSql);
 - }
 - private void executeSql(String sql) throws SQLException {
 - EntityManager em = entityManagerFactory.createEntityManager();
 - beginTransaction(em);
 - em.createNativeQuery(sql).executeUpdate();
 - commitTransaction(em);
 - closeEntityManager(em);
 - }
 - private void closeEntityManager(EntityManager em) {
 - em.close();
 - }
 - private void rollbackTransacrion(EntityManager em) throws SQLException {
 - if(em != null) {
 - em.getTransaction().rollback();
 - }
 - }
 - private void commitTransaction(EntityManager em) throws SQLException {
 - em.getTransaction().commit();
 - }
 - private void beginTransaction(EntityManager em) throws SQLException {
 - em.getTransaction().begin();
 - }
 
使用EntityManagerFactory创建EntityManager,然后通过EntityManager对象的createNativeQuery创建本地SQL执行创建和删除表。
6、 使用EntityManagerFactory获取EntityManager对象进行持久化数据:
- @Test
 - public void testFirst() throws SQLException {
 - UserModel2 model = new UserModel2();
 - model.setMyName("test");
 - EntityManager em = null;
 - try {
 - em = entityManagerFactory.createEntityManager();
 - beginTransaction(em);
 - em.persist(model);
 - commitTransaction(em);
 - } catch (SQLException e) {
 - rollbackTransacrion(em);
 - throw e;
 - } finally {
 - closeEntityManager(em);
 - }
 - }
 
使用EntityManagerFactory获取EntityManager进行操作,看到这还能忍受冗长的代码和事务管理吗?Spring同样提供JpaTemplate模板类来简化这些操作。
大家有没有注意到此处的模型对象能自动映射到数据库,这是因为Hibernate JPA实现默认自动扫描类路径中的@Entity注解类及*.hbm.xml映射文件,可以通过更改Hibernate JPA属性“hibernate.ejb.resource_scanner”,并指定org.hibernate.ejb.packaging.Scanner接口实现来定制新的扫描策略。
8.4.2 使用JpaTemplate
JpaTemplate模板类用于简化事务管理及常见操作,类似于JdbcTemplate模板类,对于复杂操作通过提供JpaCallback回调接口来允许更复杂的操作。
接下来示例一下JpaTemplate的使用:
1、修改Spring配置文件(chapter8/applicationContext-jpa.xml),添加JPA事务管理器:
- <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
 - <property name="entityManagerFactory" ref="entityManagerFactory"/>
 - </bean>
 
- txManager:指定事务管理器,JPA使用JpaTransactionManager事务管理器实现,通过entityManagerFactory指定EntityManagerFactory;用于支持Java SE环境的JPA扩展的持久化上下文(EXTENDED Persistence Context)。
 
2、修改JPATest类,添加类变量ctx,用于后边使用其获取事务管理器使用:
- package cn.javass.spring.chapter8;
 - public class JPATest {
 - private static EntityManagerFactory entityManagerFactory;
 - private static ApplicationContext ctx;
 - @BeforeClass
 - public static void beforeClass() {
 - String[] configLocations = new String[] {
 - "classpath:chapter7/applicationContext-resources.xml",
 - "classpath:chapter8/applicationContext-jpa.xml"};
 - ctx = new ClassPathXmlApplicationContext(configLocations);
 - entityManagerFactory = ctx.getBean(EntityManagerFactory.class);
 - }
 - }
 
3)JpaTemplate模板类使用:
- @Test
 - public void testJpaTemplate() {
 - final JpaTemplate jpaTemplate = new JpaTemplate(entityManagerFactory);
 - final UserModel2 model = new UserModel2();
 - model.setMyName("test1");
 - PlatformTransactionManager txManager = ctx.getBean(PlatformTransactionManager.class);
 - new TransactionTemplate(txManager).execute(
 - new TransactionCallback<Void>() {
 - @Override
 - public Void doInTransaction(TransactionStatus status) {
 - jpaTemplate.persist(model);
 - return null;
 - }
 - });
 - String COUNT_ALL = "select count(*) from UserModel";
 - Number count = (Number) jpaTemplate.find(COUNT_ALL).get(0);
 - Assert.assertEquals(1, count.intValue());
 - }
 
- jpaTemplate:可通过new JpaTemplate(entityManagerFactory)方式创建;
 - txManager:通过ctx.getBean(PlatformTransactionManager.class)获取事务管理器;
 - TransactionTemplate:通过new TransactionTemplate(txManager)创建事务模板对象,并通过execute方法执行TransactionCallback回调中的doInTransaction方法中定义需要执行的操作,从而将由模板类通过txManager事务管理器来进行事务管理,此处是调用jpaTemplate对象的persist方法进行持久化;
 - jpaTemplate.persist():根据JPA规范,在JPA扩展的持久化上下文,该操作必须运行在事务环境,还有persist()、 merge()、remove()操作也必须运行在事务环境;
 - jpaTemplate.find():根据JPA规范,该操作无需运行在事务环境,还有find()、getReference()、 refresh()、detach()和查询操作都无需运行在事务环境。
 
此实例与Hibernate和Ibatis有所区别,通过JpaTemplate模板类进行如持久化等操作时必须有运行在事务环境中,否则可能抛出如下异常或警告:
- “javax.persistence.TransactionRequiredException:Executing an update/delete query”:表示没有事务支持,不能执行更新或删除操作;
 - 警告“delaying identity-insert due to no transaction in progress”:需要在日志系统启动debug模式才能看到,表示在无事务环境中无法进行持久化,而选择了延迟标识插入。
 
以上异常和警告是没有事务造成的,也是最让人困惑的问题,需要大家注意。
8.4.3 集成JPA及最佳实践
类似于JdbcDaoSupport类,Spring对JPA也提供了JpaDaoSupport类来支持一致的数据库访问。JpaDaoSupport也是DaoSupport实现:
接下来示例一下Spring集成JPA的最佳实践:
1、 定义Dao接口,此处使用cn.javass.spring.chapter7.dao. IUserDao:
2、 定义Dao接口实现,此处是JPA实现:
- package cn.javass.spring.chapter8.dao.jpa;
 - //省略import
 - @Transactional(propagation = Propagation.REQUIRED)
 - public class UserJpaDaoImpl extends JpaDaoSupport implements IUserDao {
 - private static final String COUNT_ALL_JPAQL = "select count(*) from UserModel";
 - @Override
 - public void save(UserModel model) {
 - getJpaTemplate().persist(model);
 - }
 - @Override
 - public int countAll() {
 - Number count =
 - (Number) getJpaTemplate().find(COUNT_ALL_JPAQL).get(0);
 - return count.intValue();
 - }
 - }
 
此处注意首先JPA实现放在dao.jpa包里,其次实现类命名如UserJpaDaoImpl,即×××JpaDaoImpl,当然如果自己有更好的命名规范可以遵循自己的,此处只是提个建议。
另外在类上添加了@Transactional注解表示该类的所有方法将在调用时需要事务支持,propagation传播属性为Propagation.REQUIRED表示事务是必需的,如果执行该类的方法没有开启事务,将开启一个新的事务。
3、进行资源配置,使用resources/chapter7/applicationContext-resources.xml:
4、dao定义配置,在chapter8/applicationContext-jpa.xml中添加如下配置:
4.1、首先添加tx命名空间用于支持事务:
- <?xml version="1.0" encoding="UTF-8"?>
 - <beans xmlns="http://www.springframework.org/schema/beans"
 - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 - xmlns:tx="http://www.springframework.org/schema/tx"
 - xsi:schemaLocation="
 - http://www.springframework.org/schema/beans
 - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 - http://www.springframework.org/schema/tx
 - http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
 
4.2、为@Transactional注解事务开启事务支持:
- <tx:annotation-driven transaction-manager="txManager"/>
 
只为类添加@Transactional 注解是不能支持事务的,需要通过<tx:annotation-driven>标签来开启事务支持,其中txManager属性指定事务管理器。
4.3、配置DAO Bean:
- <bean id="abstractDao" abstract="true">
 - <property name="entityManagerFactory" ref="entityManagerFactory"/>
 - </bean>
 - <bean id="userDao"
 - class="cn.javass.spring.chapter8.dao.jpa.UserJpaDaoImpl"
 - parent="abstractDao"/>
 
首先定义抽象的abstractDao,其有一个entityManagerFactory属性,从而可以让继承的子类自动继承entityManagerFactory属性注入;然后定义userDao,且继承abstractDao,从而继承entityManagerFactory注入;我们在此给配置文件命名为applicationContext-jpa.xml表示JPA实现。
5、最后测试一下吧(cn.javass.spring.chapter8. JPATest):
- @Test
 - public void testBestPractice() {
 - String[] configLocations = new String[] {
 - "classpath:chapter7/applicationContext-resources.xml",
 - "classpath:chapter8/applicationContext-jpa.xml"};
 - ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocations);
 - IUserDao userDao = ctx.getBean(IUserDao.class);
 - UserModel model = new UserModel();
 - model.setMyName("test");
 - userDao.save(model);
 - Assert.assertEquals(1, userDao.countAll());
 - }
 
和Spring JDBC框架的最佳实践完全一样,除了使用applicationContext-jpa.xml代替了applicationContext-jdbc.xml,其他完全一样。也就是说,DAO层的实现替换可以透明化。
还有与集成其他ORM框架不同的是JPA在进行持久化或更新数据库操作时需要事务支持。
8.4.4 Spring+JPA的CRUD
Spring+JPA CRUD(增删改查)也相当简单,让我们直接看具体示例吧:
- @Test
 - public void testCRUD() {
 - PlatformTransactionManager txManager = ctx.getBean(PlatformTransactionManager.class);
 - final JpaTemplate jpaTemplate = new JpaTemplate(entityManagerFactory);
 - TransactionTemplate tansactionTemplate = new TransactionTemplate(txManager);
 - tansactionTemplate.execute(new TransactionCallback<Void>() {
 - @Override
 - public Void doInTransaction(TransactionStatus status) {
 - UserModel model = new UserModel();
 - model.setMyName("test");
 - //新增
 - jpaTemplate.persist(model);
 - //修改
 - model.setMyName("test2");
 - jpaTemplate.flush();//可选
 - //查询
 - String sql = "from UserModel where myName=?";
 - List result = jpaTemplate.find(sql, "test2");
 - Assert.assertEquals(1, result.size());
 - //删除
 - jpaTemplate.remove(model);
 - return null;
 - }
 - });
 - }
 
- 对于增删改必须运行在事务环境,因此我们使用TransactionTemplate事务模板类来支持事务。
 - 持久化:使用JpaTemplate 类的persist方法持久化模型对象;
 - 更新:对于持久化状态的模型对象直接修改属性,调用flush方法即可更新到数据库,在一些场合时flush方法调用可选,如执行一个查询操作等,具体请参考相关文档;
 - 查询:可以使用find方法执行JPA QL查询;
 - 删除:使用remove方法删除一个持久化状态的模型对象。
 
Spring集成JPA进行增删改查也相当简单,但本文介绍的稍微复杂一点,因为牵扯到编程式事务,如果采用声明式事务将和集成Hibernate方式一样简洁。
对ORM的支持 之 8.4 集成JPA ——跟我学spring3的更多相关文章
- 开涛spring3(8.1) - 对ORM的支持 之 8.1 概述
		
8.1 概述 8.1.1 ORM框架 ORM全称对象关系映射(Object/Relation Mapping),指将Java对象状态自动映射到关系数据库中的数据上,从而提供透明化的持久化支持,即把 ...
 - spring集成JPA的三种方法配置
		
JPA是Java EE5规范之一,是一个orm规范,由厂商来实现该规范.目前有hibernate,OpenJPA,TopLink和EclipseJPA等实现 spring提供三种方法集成JPA:1.L ...
 - Flowable实战(六)集成JPA
		
上文提到,Flowable所有的表单数据都保存在一张表(act_hi_varinst)中,随着时间的推移,表中数据越来越多,再加上数据没有结构优化,查询使用效率会越来越低. 在Flowable ...
 - Spring Data JPA系列2:SpringBoot集成JPA详细教程,快速在项目中熟练使用JPA
		
大家好,又见面了. 这是Spring Data JPA系列的第2篇,在上一篇<Spring Data JPA系列1:JDBC.ORM.JPA.Spring Data JPA,傻傻分不清楚?给你个 ...
 - springboot 集成 jpa/hibernate
		
pom.xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
 - spring集成jpa【为什么有 persistant.xml 文件呢?】
		
原文地址: http://www.cnblogs.com/javahuang/archive/2012/12/19/2824633.html spring集成JPA的其中一种方式 JPA和hibern ...
 - Spring同时集成JPA与Mybatis
		
@ 目录 ORM Spring ORM Spring ORM 同时集成JPA与Mybatis 一.创建一个SpringBoot项目 二.建立用户信息登记表 三.Web应用项目集成mysql 四.添加S ...
 - Spring Boot集成JPA的Column注解命名字段无效的问题
		
偶然发现,Spring Boot集成jpa编写实体类的时候,默认使用的命名策略是下划线分隔的字段命名. Spring Boot版本:1.5.4.release 数据表: id int, userNam ...
 - spingboot集成jpa(一)
		
springboot + jpa 练习 spingboot集成jpa(一):最基本的环境搭建 spingboot集成jpa(二):使用单元测试 1. pom.xml中添加依赖 <!-- jdbc ...
 
随机推荐
- IntelliJ IDEA 中安装junit插件
			
1.在Intellij IDEA 中安装了 Junit,TestNG插件,首先检查一下intellij IDEA 是否在安装时默认安装了这两个插件,检查方法 打开 settings -->Plu ...
 - NTP多种模式的配置
			
自己安装和配置了一个NTP服务器的一些心得,希望与大家分享.写了一个文档包含了各个命令和参数的具体含义,由于不能上传无法与大家分享.以后还希望大家多多支持和帮助我们共同成长,我会不断做把这些年的经营和 ...
 - Oracle学习笔记:外连接(+)的用法
			
Oracle中常用 left join 和 right join 来进行外连接,同时,oracle也支持 (+) 的特殊用法,也是表示外连接,并且总是放在非主表的一方. 例如: 左外连接: selec ...
 - HTML相对路径相对目录--上级目录及下级目录的写法
			
如何表示上级目录 ../表示源文件所在目录的上一级目录,../../表示源文件所在目录的上上级目录,以此类推. 假设info.html路径是:c:/Inetpub/wwwroot/sites/blab ...
 - Python Extension 编译问题
			
Python 的一大好处是调用C扩展程序相当方便,但是 Windows 下的话,编译器版本是一个大问题.以Python27为例,官方版本时采用VC2008编译的.在setup.py中添加Extensi ...
 - 如何简单区分Web前后端与MVC
			
MVC是开发所有软件所必须涉及的基本几个划分 M主要负责数据与模型,V主要负责显示C主要负责交互与业务所以不管是前端还是后端,都是有MVC的.MVC是一个对于软件简单的抽象,不管是M还是V,还是C都是 ...
 - linux convert mp3 to wav  and opus to wav
			
link : https://www.cyberciti.biz/faq/convert-mp3-files-to-wav-files-in-linux/ Install mpg321 or mpg ...
 - 必读,sql加索引调优案例和explain extended说明
			
做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 昨天分享了Mysql中的 explain 命令,使用 explain 来分析 select 语句的运行效果,如 :expl ...
 - poj-1459-最大流dinic+链式前向星-isap+bfs+stack
			
title: poj-1459-最大流dinic+链式前向星-isap+bfs+stack date: 2018-11-22 20:57:54 tags: acm 刷题 categories: ACM ...
 - [转]C++ STL list的初始化、添加、遍历、插入、删除、查找、排序、释放
			
list是C++标准模版库(STL,Standard Template Library)中的部分内容.实际上,list容器就是一个双向链表,可以高效地进行插入删除元素. 使用list容器之前必须加上S ...