React Native开发Spring BootJava 杂谈

spring boot restful + react antd

2018-06-05  本文已影响317人  bd6b5cde5ce9

这阵子由于任务要求,使用了spring boot 搭建restful api服务,前端用了tb的antd pro 框架
记录一下其中的几个容易忘的知识点,想到了就记下来 随时补充,主要是为了以后自己随时翻阅的。各位看官看着不痛快就忍忍撒。

关于后端

1、maven 项目中的pom.xml,如果下载的时候不痛快
可以在里面加入阿里的仓库

  <repositories>
    <repository>
      <id>spring-releases</id>
      <url>https://repo.spring.io/libs-release</url>
    </repository>
    <repository>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    </repository>
  </repositories>

2、数据库连接
pom.xml中加入依赖,一是写系统路径,而是mvn安装,下面是第一种

<dependency>
      <groupId>com.oracle</groupId>
      <artifactId>ojdbc6</artifactId>
      <version>11.2.0.1</version>
      <scope>system</scope>
      <systemPath>${basedir}/lib/ojdbc6.jar</systemPath>
    </dependency>

application.properties中

spring.datasource.driver-class-name=oracle.jdbc.OracleDriver //驱动名
spring.datasource.url=jdbc:oracle:thin:@'//ip/数据库名' //格式
spring.datasource.username=用户名
spring.datasource.password=密码
spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect//语言 11g可用这个
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update//是否自动更新
spring.jpa.hibernate.naming.strategy=org.hibernate.cfg.DefaultNamingStrategy//默认命名策略
spring.jmx.enabled=false //禁止jmx

3、打包

<packaging>war</packaging>
....
....
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

intellij idea 中的方法 在右侧边栏tab
打开maven projects
lifecycle - 双击package
在target文件夹中即可找到打包生成的war文件

4、先设计表再生成实体
也可以反过来,都可以的
先表后实体,则利用了Intellij idea 中的persistence这个功能,一般在左侧边栏就有这个tab

5、常用的实体注解表示

    @Id
    @Column(name = "USERID", nullable = false, precision = 0)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "userinfseq")
    @SequenceGenerator(name = "userinfseq", sequenceName =   "SEQ_USERINFID",allocationSize = 1)
    @Basic
    @Column(name = "USERNAME", nullable = true, length = 20)
    @ManyToOne(optional = true, fetch=FetchType.LAZY)
    @JoinColumn(name="ELEMENTS_BELONG_UNIT_ID", nullable = false)
    @OneToMany(mappedBy = "sUnitClassEntity",fetch=FetchType.LAZY,cascade = {CascadeType.PERSIST})
    @JsonBackReference //*****json very important 序列化忽略
    @JsonManagedReference //****反序列化不忽略 一般和@JsonBackReference配对使用
    @JsonIgnore //****均忽略

6、api中常用注解

@CrossOrigin
@RestController
@RequestMapping("/api/download")
@RequestBody FileParams fileParams
@Autowired
@Transactional

附上一个根据文件名下载的api 配合前端iframe 可实现无刷新下载

@RequestMapping(method = RequestMethod.GET)
    public ResponseEntity<byte[]> download(
            @RequestParam(value="filename",required = true,defaultValue="") String filename
    ) throws IOException {
        File file = new File(this.getClass().getResource("/").getPath()+"data/"+filename);
        byte[] body = null;
        InputStream is = new FileInputStream(file);
        body = new byte[is.available()];
        is.read(body);
        HttpHeaders headers = new HttpHeaders();
        int statusCode = HttpStatus.SC_OK;
        headers.add("Content-Disposition", "attchement;filename=" + file.getName());

        return ResponseEntity.ok().headers(headers).body(body);
    }

7、关于jpa数据操作
每个controller里都有这段

    private JpaScoreRepository jpaScoreRepository;

    @Autowired
    public ReportDownLoadApiController(JpaScoreRepository jpaScoreRepository){

        this.jpaScoreRepository = jpaScoreRepository;

    }

jpa的基本增删改可上官网阅读,来个函数感受下。

  public interface JpaProjectAccordingRepository extends JpaRepository<ProjectscoreRefEntity,Integer> {
    Page<ProjectscoreRefEntity> findPProjectscoreRefEntitiesByProjectscoreRefNameContaining(String projectname, Pageable pageable);
}

判断是否存在 新加的

  boolean existsByProjectname(String projectname);

自定义原生sql使用方法

    @Modifying
    @Query(value = "delete from B_PROJECTINF where PROJECTID=?1", nativeQuery = true)
    void deleteProjectinfEntityById( int id);

配合EntityManager可以解决一切你要的
先定一个接口,里面返回的类型都可以自定义,但不用生成到表里,常规的类就可以,有时候需要你加上初始化函数,Page这里我是自定义的 copy jpa

public class Page<T> {
    private int current;
    private int pageSize;
    private Long total;
    private List<T> results;

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setCurrent(int current) {
        this.current = current;
    }

    public int getCurrent() {
        return current;
    }

    public List<T> getResults() {
        return results;
    }

    public void setResults(List<T> results) {
        this.results = results;
    }

    public long getTotal() {
        return total;
    }

    public void setTotal(long total) {
        this.total = total;
    }
}
public interface SunitClass {
    void saveSunitClass(SUnitClassEntity sUnitClassEntity);
    Page<ProjectScore> findProjectScoreBy(String projectname, int userid, int pass, int pagesize, int currentpage);
    Page<ProjectScoreSort> findProjectScoreSortBy(int pagesize, int currentpage);
    Page<ProjectScore> findMyProjectScoreBy(String projectname, int userid, int pass,int pagesize, int currentpage);
    List<ReportData> findProjectScoreByProjectname(String projectname);
}

实现它,注意这个命名 必须是对应repository后面加Impl 自定义的话需要相关设置

public class JpaScoreRepositoryImpl implements SunitClass {
    @PersistenceContext
    private EntityManager em;

    @Override
    public void saveSunitClass(SUnitClassEntity sUnitClassEntity) {
        SUnitClassEntity sUnitClassEntity1 = new SUnitClassEntity();
        sUnitClassEntity1.setUnitName(sUnitClassEntity.getUnitName());
        sUnitClassEntity1.setUnitScore(sUnitClassEntity.getUnitScore());
        sUnitClassEntity1.setUnitBelongProId(sUnitClassEntity.getUnitBelongProId());
        sUnitClassEntity1.setUnitNote(sUnitClassEntity.getUnitNote());
        sUnitClassEntity1.setUnitWeights(sUnitClassEntity.getUnitWeights());
        sUnitClassEntity1.setUnitPerson(sUnitClassEntity.getUnitPerson());
        sUnitClassEntity1.setUnitOk(sUnitClassEntity.getUnitOk());
        em.persist(sUnitClassEntity1);
        for(SElementsUnitEntity seu:sUnitClassEntity.getsElementsUnitEntitySets()){
            SElementsUnitEntity sElementsUnitEntity = new SElementsUnitEntity(seu.getElementsName(),seu.getElementsScore(),sUnitClassEntity1);
            em.persist(sElementsUnitEntity);
            for(SSubelementsElementsEntity ssub:seu.getsSubelementsElementsEntities()){
                SSubelementsElementsEntity sSubelementsElementsEntity = new SSubelementsElementsEntity(ssub.getSubelementsName(),ssub.getSubelementsScore(),sElementsUnitEntity);
                sElementsUnitEntity.getsSubelementsElementsEntities().add(sSubelementsElementsEntity);
            }
            sUnitClassEntity1.getsElementsUnitEntitySets().add(sElementsUnitEntity);

        }
    }
    ..........

Repository头部加入SunitClass,ok,可以使用了

public interface JpaScoreRepository extends JpaRepository<SUnitClassEntity,Integer>,SunitClass {

    boolean existsByunitBelongProIdAndUnitName(int unitBelongProId,String UnitName );

    boolean existsByUnitBelongProIdAndUnitPerson(int unitBelongProId, int UnitPerson);

    void deleteByUnitBelongProIdAndUnitPerson(int unitBelongProId, int UnitPerson);

    List<SUnitClassEntity> findAllByunitBelongProIdAndUnitPerson(int unitBelongProId, int UnitPerson);

    List<SUnitClassEntity> findAllByunitBelongProId(int unitBelongProId);

}

Spring boot 是自动调用jackson进行序列号化的,了解了上面几个知识点,稍加研究即可生产一套完整的restful api

关于前端

antd不得不说封装的控件很漂亮。
1、登录它的官网,照着下载个demo即可使用
2、以用户信息为例基本流程
首先进行common 文件夹下的menu route 配置 路由及菜单(自动注册了model)
然后models文件夹下创建路由菜单所关联的model

import { queryUser, removeUser, addUser } from '../services/api';
//不用太困惑 这里就说antd中dva封装的方法 你可以用自己的redux
export default {
  namespace: 'userinf',

  state: {
    data: {
      list: [],
      pagination: {},
    },
  },

  effects: { //异步调用 所有的均通过这调用
    *fetch({ payload }, { call, put }) {
      const response = yield call(queryUser, payload); //异步以同步的方式执行,reponse返回了才会进行下一步
      yield put({ //调用更新state
        type: 'save',
        payload: response,
      });
    },
    *add({ payload, callback }, { call, put }) {
      const response = yield call(addUser, payload);
      yield put({
        type: 'save',
        payload: response,
      });
      if (callback) callback(); //如果有回调 则进行回调
    },
    *remove({ payload, callback }, { call, put }) {
      const response = yield call(removeUser, payload);
      yield put({
        type: 'save',
        payload: response,
      });
      if (callback) callback();
    },
  },

然后创建用户界面的组件routes文件夹下,比较重要的是一定要进行connect关联

@connect(({ userinf, loading }) => ({
  userinf,
  loading: loading.models.userinf,
}))
@Form.create()
export default class TableList extends PureComponent {
componentDidMount() {
    const { dispatch } = this.props;
    dispatch({
      type: 'userinf/fetch',
    });
  }
.............

然后写services 下 api,request 是 antd封装好的fetch,也可以自己进行调用

export async function getAccountLogin(params) {
  return request(url, {
    method: 'POST',
    body: params,
  });
}
fetch(url,{credentials: 'omit'})
          .then(response => response.json())
          .then((body) => {
            if(body.code=="0"){
              const data = body.result.map(project => ({
                text: `${project.PROJECTNAME}`,
                value: `${project.PROJECTNAME}`,
              }));       
              this.setState({
                result: data,
              });
            }
          });

然后获取返回的data,根据组件的api可以进行使用

  const { userinf: { data }, loading } = this.props;//这里利用了es6语法,react很多,可以学习一下 

ok,我们可以写一个react 页面了

部署

安装tomcat和jdk就不记录了,需要的时候搜索一大堆。
要点主要是几个路径变量的配置
来个连接 https://www.linuxidc.com/Linux/2015-01/112030.htm 亲测有效
在tomcat的logs文件夹下可以查看日志记录 #这个很重要# nano catalina.out
数据库驱动要放到正确位置。
把打包生成的war放到webapps下就可以了,再配置一下你的域名
通过server.xml配置域名

     <Host name="你的域名"  appBase="webapps"
           unpackWARs="true" autoDeploy="true">

       <!-- SingleSignOn valve, share authentication between web applications
            Documentation at: /docs/config/valve.html -->
       <!--
       <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
       -->

       <!-- Access log processes all example.
            Documentation at: /docs/config/valve.html
            Note: The pattern used is equivalent to using pattern="common" -->
       <Context docBase="你的包名" path="/" reloadable="true" debug="0" privileged="true"/>

antd 直接运行 npm run build 生成dist 部署到你的web应用服务器就可以了,纯js+html
附上新鲜出炉的系统截图一张


屏幕快照 2018-06-05 下午5.44.11.png
上一篇下一篇

猜你喜欢

热点阅读