日系框架之seasar2(S2JPA之Hibernate3)

 官方主页:http://s2hibernate.seasar.org/ja/

本例使用MySQL作为数据库,数据库名暂定为s2hb3jpa。

使用的jar包如下。

antlr-2.7.6.jar
aopalliance-1.0.jar
commons-collections-3.1.jar
commons-lang-2.3.jar
commons-logging-1.1.jar
dom4j-1.6.1.jar
ehcache-1.2.3.jar
ejb3-persistence.jar
geronimo-annotation_1.0_spec-1.0.jar
geronimo-ejb_3.0_spec-1.0.jar
geronimo-interceptor_3.0_spec-1.0.jar
geronimo-j2ee_1.4_spec-1.0.jar
hibernate3.jar
hibernate-annotations.jar
hibernate-commons-annotations.jar
hibernate-entitymanager.jar
hibernate-search.jar
hibernate-validator.jar
hsqldb-1.8.0.1.jar
javassist-3.4.GA.jar
jboss-archive-browsing-5.0.0alpha-200607201-119.jar
jta-1.1.jar
junit-3.8.2.jar
log4j-1.2.13.jar
lucene-core-2.3.0.jar
mysql-connector-java-5.1.6-bin.jar
ognl-2.6.9-patch-20070908.jar
poi-3.0-FINAL.jar
s2-extension-2.4.29.jar
s2-framework-2.4.29.jar
s2hibernate-jpa-1.0.1.jar
s2-tiger-2.4.29.jar
servlet-api.jar
slf4j-api-1.4.2.jar
slf4j-log4j12.jar

 

代码如下:

app.dicon

  1. <?xml version="1.0" encoding="Shift_JIS"?>
  2. <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
  3.     "http://www.seasar.org/dtd/components21.dtd">
  4. <components>
  5.     <include path="jdbc.dicon"/>
  6.     <include path="examples/dicon/DepartmentDao.dicon"/>
  7. </components>

convention.dicon

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" 
  3.     "http://www.seasar.org/dtd/components24.dtd">
  4. <components>
  5.     <component class="org.seasar.framework.convention.impl.NamingConventionImpl" />
  6. </components>

env_ut.txt

  1. ct

import.sql

只要放在classpath下,seasar2会自动执行DML(注意:似乎文件名只能是import.sql)。

  1. INSERT INTO DEPT (DEPTNO,DNAME,LOC,VERSIONNO,ACTIVE) VALUES(10,'ACCOUNTING','NEW YORK',0,1)
  2. INSERT INTO DEPT (DEPTNO,DNAME,LOC,VERSIONNO,ACTIVE) VALUES(20,'RESEARCH','DALLAS',0,1)
  3. INSERT INTO DEPT (DEPTNO,DNAME,LOC,VERSIONNO,ACTIVE) VALUES(30,'SALES','CHICAGO',0,1)
  4. INSERT INTO DEPT (DEPTNO,DNAME,LOC,VERSIONNO,ACTIVE) VALUES(40,'OPERATIONS','BOSTON',0,1)
  5. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20,'LAS VEGAS','110','2000-01-01 00:00:00.0')
  6. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30,'MIAMI','120','2000-01-01 00:00:00.0')
  7. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30,'WASHINGTON','130','2000-01-01 00:00:00.0')
  8. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20,'IOWA CITY','140','2000-01-01 00:00:00.0')
  9. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30,'LOS ANGELES','150','2000-01-01 00:00:00.0')
  10. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30,'LOS ANGELES','160','2000-01-01 00:00:00.0')
  11. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10,'WASHINGTON','170','2000-01-01 00:00:00.0')
  12. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7788,'SCOTT','ANALYST',7566,'1982-12-09',3000.0,NULL,20,'NEW YORK','180','2005-01-18 13:09:32.213')
  13. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10,'SEATTLE','190','2000-01-01 00:00:00.0')
  14. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30,'NEW YORK','210','2000-01-01 00:00:00.0')
  15. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7876,'ADAMS','CLERK',7788,'1983-01-12',1100,NULL,20,'SANTA FE','220','2000-01-01 00:00:00.0')
  16. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30,'NEW YORK','230','2000-01-01 00:00:00.0')
  17. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20,'SANTA FE','240','2000-01-01 00:00:00.0')
  18. INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,CITY,ZIP,TSTAMP) VALUES(7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10,'IOWA CITY','250','2000-01-01 00:00:00.0')

jdbc.dicon

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" 
  3.     "http://www.seasar.org/dtd/components24.dtd">
  4. <components namespace="jdbc">
  5.     <include path="jta.dicon"/>
  6.     <include path="jdbc-extension.dicon"/>
  7.     <component class="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/>
  8.     <component class="org.seasar.extension.jdbc.impl.ConfigurableStatementFactory">
  9.         <arg>
  10.             <component class="org.seasar.extension.jdbc.impl.BasicStatementFactory"/>
  11.         </arg>
  12.         <property name="fetchSize">100</property>
  13.     </component>
  14.     <component name="xaDataSource"
  15.         class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
  16.         <property name="driverClassName">
  17.             "com.mysql.jdbc.Driver"
  18.         </property>
  19.         <property name="URL">
  20.             "jdbc:mysql://localhost:3306/s2hb3jpa"
  21.         </property>
  22.         <property name="user">"root"</property>
  23.         <property name="password">"root"</property>
  24.     </component>
  25.     <component name="connectionPool"
  26.         class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
  27.         <property name="timeout">600</property>
  28.         <property name="maxPoolSize">10</property>
  29.         <property name="allowLocalTx">true</property>
  30.         <destroyMethod name="close"/>
  31.     </component>
  32.     <component name="dataSource" class="org.seasar.extension.dbcp.impl.DataSourceImpl"/>
  33. </components>

jpa.dicon

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" 
  3.     "http://www.seasar.org/dtd/components24.dtd">
  4. <components>
  5.     <include path="s2hibernate-jpa.dicon"/>
  6.     <component name="persistenceUnitProvider" class="org.seasar.framework.jpa.impl.ContainerPersistenceUnitProvider">
  7.         <property name="unitName">"s2hb3jpaUnit"</property>
  8.     </component>
  9.     
  10.     <component name="entityManagerFactory" class="javax.persistence.EntityManagerFactory">
  11.         persistenceUnitProvider.entityManagerFactory
  12.     </component>
  13.     <component name="entityManager" class="org.seasar.framework.jpa.impl.TxScopedEntityManagerProxy"/>
  14. </components>
log4j.properties
  1. log4j.category.org.seasar=DEBUG, C
  2. log4j.additivity.org.seasar=false
  3. log4j.category.examples=DEBUG, C
  4. log4j.additivity.examples=false
  5. log4j.appender.C=org.apache.log4j.ConsoleAppender
  6. log4j.appender.C.Target=System.out
  7. log4j.appender.C.ImmediateFlush=true
  8. log4j.appender.C.layout=org.apache.log4j.PatternLayout
  9. log4j.appender.C.layout.ConversionPattern=%-5p %d [%t] %m%n
  10. log4j.rootLogger=INFO, A1
  11. log4j.appender.A1=org.apache.log4j.ConsoleAppender
  12. log4j.appender.A1.layout=org.apache.log4j.PatternLayout
  13. log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

META-INF/persistence.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <persistence xmlns="http://java.sun.com/xml/ns/persistence"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
  5.     http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
  6.     version="1.0">
  7.     <persistence-unit name="s2hb3jpaUnit" transaction-type="RESOURCE_LOCAL">
  8.         <provider>org.hibernate.ejb.HibernatePersistence</provider>
  9.         <jta-data-source>jdbc/dataSource</jta-data-source>
  10.         <class>examples.entity.Department</class>
  11.         <class>examples.entity.Employee</class>
  12.         <properties>
  13.             <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
  14.             <property name="hibernate.jndi.class" value="org.seasar.extension.j2ee.JndiContextFactory"/>
  15.             <property name="hibernate.transaction.manager_lookup_class" value="org.seasar.hibernate.jpa.transaction.SingletonTransactionManagerProxyLookup"/>
  16.             <property name="hibernate.show_sql" value="true"/>
  17.             <property name="hibernate.format_sql" value="true"/>
  18.             <property name="hibernate.use_sql_comments" value="false"/>
  19.             <property name="hibernate.archive.autodetection" value=""/> 
  20.             <property name="hibernate.hbm2ddl.auto" value="create"/>
  21.         </properties>
  22.     </persistence-unit>
  23. </persistence>

DepartmentDao.dicon

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
  3.     "http://www.seasar.org/dtd/components24.dtd">
  4. <components>
  5.     <include path="javaee5.dicon"/>
  6.     <include path="jpa.dicon"/>
  7.     <component name="dao" class="examples.dao.DepartmentDaoImpl"/>
  8. </components>

DepartmentDao.java

  1. package examples.dao;
  2. import examples.entity.Department;
  3. public interface DepartmentDao {
  4.     Department getDepartment(int id);
  5. }

DepartmentDaoImpl.java

  1. package examples.dao;
  2. import javax.ejb.Stateless;
  3. import javax.persistence.EntityManager;
  4. import javax.persistence.PersistenceContext;
  5. import examples.entity.Department;
  6. @Stateless
  7. public class DepartmentDaoImpl implements DepartmentDao {
  8.     @PersistenceContext(unitName = "s2hb3jpaUnit")
  9.     EntityManager em;
  10.     public DepartmentDaoImpl() {
  11.     }
  12.     public Department getDepartment(int id) {
  13.         
  14.         return em.find(Department.class, id);
  15.     }
  16. }

Address.java

  1. package examples.entity;
  2. import java.io.Serializable;
  3. import javax.persistence.Embeddable;
  4. @Embeddable
  5. public class Address implements Serializable {
  6.     private static final long serialVersionUID = 1L;
  7.     private String city;
  8.     private String zip;
  9.     public String getCity() {
  10.         return city;
  11.     }
  12.     public void setCity(String city) {
  13.         this.city = city;
  14.     }
  15.     public String getZip() {
  16.         return zip;
  17.     }
  18.     public void setZip(String zip) {
  19.         this.zip = zip;
  20.     }
  21. }

Department.java

  1. package examples.entity;
  2. import java.io.Serializable;
  3. import java.util.Set;
  4. import javax.persistence.Entity;
  5. import javax.persistence.Id;
  6. import javax.persistence.OneToMany;
  7. import javax.persistence.Version;
  8. @Entity(name = "Dept")
  9. public class Department implements Serializable {
  10.     private static final long serialVersionUID = -1031433105487668130L;
  11.     @Id
  12.     private int deptno;
  13.     private String dname;
  14.     private String loc;
  15.     @SuppressWarnings("unused")
  16.     @Version
  17.     private int versionNo;
  18.     private boolean active;
  19.     @OneToMany(mappedBy = "department")
  20.     private Set<Employee> employees;
  21.     public Department() {
  22.     }
  23.     public int getDeptno() {
  24.         return this.deptno;
  25.     }
  26.     public void setDeptno(int deptno) {
  27.         this.deptno = deptno;
  28.     }
  29.     public java.lang.String getDname() {
  30.         return this.dname;
  31.     }
  32.     public void setDname(java.lang.String dname) {
  33.         this.dname = dname;
  34.     }
  35.     public java.lang.String getLoc() {
  36.         return this.loc;
  37.     }
  38.     public void setLoc(java.lang.String loc) {
  39.         this.loc = loc;
  40.     }
  41.     public void setVersionNo(int versionNo) {
  42.         this.versionNo = versionNo;
  43.     }
  44.     public boolean isActive() {
  45.         return active;
  46.     }
  47.     public void setActive(boolean active) {
  48.         this.active = active;
  49.     }
  50.     public Set<Employee> getEmployees() {
  51.         return employees;
  52.     }
  53.     public void setEmployees(Set<Employee> employees) {
  54.         this.employees = employees;
  55.     }
  56.     @Override
  57.     public boolean equals(Object other) {
  58.         if (!(other instanceof Department))
  59.             return false;
  60.         Department castOther = (Department) other;
  61.         return this.getDeptno() == castOther.getDeptno();
  62.     }
  63.     @Override
  64.     public int hashCode() {
  65.         return this.getDeptno();
  66.     }
  67. }

Employee.java

  1. package examples.entity;
  2. import java.io.Serializable;
  3. import java.util.Date;
  4. import javax.persistence.Embedded;
  5. import javax.persistence.Entity;
  6. import javax.persistence.Id;
  7. import javax.persistence.JoinColumn;
  8. import javax.persistence.ManyToOne;
  9. import javax.persistence.Temporal;
  10. import javax.persistence.TemporalType;
  11. @Entity(name = "Emp")
  12. public class Employee implements Serializable {
  13.     private static final long serialVersionUID = -5411969211921106291L;
  14.     @Id
  15.     private long empno;
  16.     private String ename;
  17.     private String job;
  18.     private Short mgr;
  19.     @Temporal(TemporalType.DATE)
  20.     private Date hiredate;
  21.     private Float sal;
  22.     private Float comm;
  23.     @Temporal(TemporalType.TIMESTAMP)
  24.     private Date tstamp;
  25.     @ManyToOne
  26.     @JoinColumn(name = "deptno")
  27.     private Department department;
  28.     @Embedded
  29.     private Address address;
  30.     public Employee() {
  31.     }
  32.     public Employee(long empno) {
  33.         this.empno = empno;
  34.     }
  35.     public long getEmpno() {
  36.         return this.empno;
  37.     }
  38.     public void setEmpno(long empno) {
  39.         this.empno = empno;
  40.     }
  41.     public java.lang.String getEname() {
  42.         return this.ename;
  43.     }
  44.     public void setEname(java.lang.String ename) {
  45.         this.ename = ename;
  46.     }
  47.     public java.lang.String getJob() {
  48.         return this.job;
  49.     }
  50.     public void setJob(java.lang.String job) {
  51.         this.job = job;
  52.     }
  53.     public Short getMgr() {
  54.         return this.mgr;
  55.     }
  56.     public void setMgr(Short mgr) {
  57.         this.mgr = mgr;
  58.     }
  59.     public java.util.Date getHiredate() {
  60.         return this.hiredate;
  61.     }
  62.     public void setHiredate(java.util.Date hiredate) {
  63.         this.hiredate = hiredate;
  64.     }
  65.     public Float getSal() {
  66.         return this.sal;
  67.     }
  68.     public void setSal(Float sal) {
  69.         this.sal = sal;
  70.     }
  71.     public Float getComm() {
  72.         return this.comm;
  73.     }
  74.     public void setComm(Float comm) {
  75.         this.comm = comm;
  76.     }
  77.     public Department getDepartment() {
  78.         return this.department;
  79.     }
  80.     public void setDepartment(Department department) {
  81.         this.department = department;
  82.     }
  83.     public Date getTstamp() {
  84.         return this.tstamp;
  85.     }
  86.     public void setTstamp(Date tstamp) {
  87.         this.tstamp = tstamp;
  88.     }
  89.     public Address getAddress() {
  90.         return address;
  91.     }
  92.     public void setAddress(Address address) {
  93.         this.address = address;
  94.     }
  95.     @Override
  96.     public boolean equals(Object other) {
  97.         if (!(other instanceof Employee))
  98.             return false;
  99.         Employee castOther = (Employee) other;
  100.         return this.getEmpno() == castOther.getEmpno();
  101.     }
  102.     @Override
  103.     public int hashCode() {
  104.         return (intthis.getEmpno();
  105.     }
  106. }

DepartmentClient.java

  1. package examples.work;
  2. import org.seasar.framework.container.S2Container;
  3. import org.seasar.framework.container.factory.S2ContainerFactory;
  4. import examples.dao.DepartmentDao;
  5. import examples.dao.DepartmentDaoImpl;
  6. import examples.entity.Department;
  7. public class DepartmentClient {
  8.     private static final String PATH = "app.dicon"
  9.     public static void main(String[] args) { 
  10.          
  11.         S2Container container = S2ContainerFactory.create(PATH); 
  12.         container.init(); 
  13.         try { 
  14.             DepartmentDao dao = (DepartmentDao)container.getComponent(DepartmentDaoImpl.class); 
  15.             Department department =  dao.getDepartment(10);
  16.             System.out.println(department.getLoc());
  17.         } finally { 
  18.             container.destroy(); 
  19.         } 
  20.     } 
  21. }

EntityManagerClient.java

  1. package examples.work;
  2. import javax.ejb.TransactionAttribute;
  3. import javax.ejb.TransactionAttributeType;
  4. import javax.persistence.EntityManager;
  5. import javax.persistence.EntityManagerFactory;
  6. import javax.persistence.EntityTransaction;
  7. import org.hibernate.Query;
  8. import org.hibernate.Session;
  9. import org.hibernate.SessionFactory;
  10. import org.seasar.framework.container.S2Container;
  11. import org.seasar.framework.container.factory.S2ContainerFactory;
  12. import examples.entity.Department;
  13. public class EntityManagerClient {
  14.     private static final String PATH = "app.dicon"
  15.     
  16.     
  17.     public static void main(String[] args) {
  18.         
  19.         S2Container container = S2ContainerFactory.create(PATH);
  20.         container.init();
  21.         try {
  22.             //EntityManager em = (EntityManager) container.getComponent(TxScopedEntityManagerProxy.class);
  23.             //Department department = (Department) em.find(Department.class, 10);
  24.             //System.out.println(department.getDname());
  25.             
  26.             EntityManagerFactory emf = (EntityManagerFactory) container.getComponent(EntityManagerFactory.class);
  27.             EntityManager em = emf.createEntityManager();
  28.             
  29.             Department department = (Department)em.find(Department.class, 10);
  30.             updateDepartment(em, department);
  31.             
  32.             final Session session = Session.class.cast(em.getDelegate());
  33.             department = (Department)session.load(Department.class, 10);
  34.             System.out.println(department.getDname());
  35.             Query query = session.createQuery("from Dept");
  36.             System.out.println(query.list().size());
  37.             
  38.             final SessionFactory sf = session.getSessionFactory();
  39.             System.out.println(sf.getAllClassMetadata().size());
  40.         } finally {
  41.             container.destroy();
  42.         }
  43.     }
  44.     
  45.     @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
  46.     public static void updateDepartment(EntityManager em, Department department){
  47.         
  48.         System.out.println(department.getDname());
  49.         department.setDname(department.getDname() + "XXX");
  50.         EntityTransaction tx = em.getTransaction();
  51.         tx.begin();
  52.         em.persist(department);
  53.         em.flush();
  54.         tx.commit();
  55.     }
  56. }

注意:使用注释掉的代码来获得em时,会报告session已经关闭的错误。

 

EntityManagerFactoryClient.java

  1. package examples.work;
  2. import javax.persistence.EntityManager;
  3. import javax.persistence.EntityManagerFactory;
  4. import org.hibernate.Session;
  5. import org.hibernate.SessionFactory;
  6. import org.seasar.framework.container.S2Container;
  7. import org.seasar.framework.container.factory.S2ContainerFactory;
  8. import org.seasar.framework.jpa.PersistenceUnitManager;
  9. import examples.entity.Department;
  10. public class EntityManagerFactoryClient {
  11.     private static final String PATH = "app.dicon";
  12.     public static void main(String[] args) {
  13.         S2Container container = S2ContainerFactory.create(PATH);
  14.         container.init();
  15.         try {
  16.             EntityManagerFactory emf = (EntityManagerFactory) container.getComponent(EntityManagerFactory.class);
  17.             EntityManager em = emf.createEntityManager();
  18.             Department department = (Department) em.find(Department.class10);
  19.             System.out.println(department.getDeptno());
  20.             
  21.             PersistenceUnitManager pum = PersistenceUnitManager.class.cast(container.getComponent(PersistenceUnitManager.class));
  22.             emf = pum.getEntityManagerFactory("s2hb3jpaUnit");
  23.             em = emf.createEntityManager();
  24.             Session session = Session.class.cast(em.getDelegate());
  25.             SessionFactory sf = session.getSessionFactory();
  26.             System.out.println(sf.getAllClassMetadata().size());
  27.             department = (Department) em.find(Department.class10);
  28.             System.out.println(department.getDeptno());
  29.         } finally {
  30.             container.destroy();
  31.         }
  32.     }
  33. }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值