GVKun编程网logo

laravel5.5 + react完成简单的CRUD(laravel action)

15

本篇文章给大家谈谈laravel5.5+react完成简单的CRUD,以及laravelaction的知识点,同时本文还将给你拓展004,elasticsearch简单的集群管理和CRUD操作、120

本篇文章给大家谈谈laravel5.5 + react完成简单的CRUD,以及laravel action的知识点,同时本文还将给你拓展004,elasticsearch 简单的集群管理和 CRUD 操作、120行代码手写一个简单的MyBatis实现简单的CRUD、es-for-Laravel: Composer 包安装, Laravel 最简单的方式操作 Elasticsearch、java – 如何设计一个简单的CRUD REST API等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

laravel5.5 + react完成简单的CRUD(laravel action)

laravel5.5 + react完成简单的CRUD(laravel action)

laravel5.5 + react完成简单的CRUD

在这篇文章中,我想和大家分享如何在PHP Laravel框架中使用js来创建crud(Create Read Update Delete)应用程序。在这个例子中,您可以学习如何为laravel reactjs应用程序构建设置,我还使用axios post请求,获取请求,放入请求和删除请求来插入更新删除应用程序。

教程大概分为如下9步

  • 1.1) 第1步:安装Laravel 5.5
  • 1.2) 第2步:数据库配置
  • 1.3) 第3步:创建产品表格和模型
  • 1.4) 第4步:创建Web路由和API路由
  • 1.5) 第5步:创建ProductController
  • 2.0) 第6步:安装ReactJS的配置
  • 3.0) 第7步:创建React组件文件
  • 4.0) 第8步:创建视图文件
  • 5.0) 第9步:运行项目

1. 安装laravel5.5

1.1 创建项目

composer create-project laravel/laravel laravel-react --prefer-dist

1.2 修改数据库配置

创建数据库并修改配置文件

cd laravel-react

vim .env

1.3 创建文章迁移表及模型

PHP artisan make:model Post -m

这样就创建好了Post模型以及posts

当然你也可以分两步执行

// 创建Post 模型
PHP artisan make:model Post
// 创建posts表
PHP artisan make:migration create_posts_table

修改迁移文件的up方法
database/migrations/2018_01_23_021301_create_posts_table.PHP

public function up()
    {
        Schema::create('posts',function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('content');
            $table->timestamps();
        });
    }

执行迁移

PHP artisan migrate

修改app/Post.PHP

<?PHP

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $fillable = [
        'title','body'
    ];
}

1.4 创建web路由和api路由

routes/web.PHP

Route::get('/',function () {
    return view('welcome');
});

routes/api.PHP

Route::resource('posts','PostController');

1.5 创建PostController

PHP artisan make:controller PostController --resource
--resource 会默认创建以下方法
1) index()
2) store()
3) edit()
4) update()
5) destory()
6) show() 这里暂时我们不需要这个方法

修改 app/Http/PostController.PHP

<?PHP

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Post;

class PostController extends Controller
{
    /**
     * display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $data = Post::all();
        return response()->json($data);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create(Request $request)
    {
        $data = new Post([
          'title' => $request->get('title'),'content' => $request->get('content')
        ]);
        $data->save();

        return response()->json('添加成功 :)');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $data = new Post([
          'title' => $request->get('title'),'content' => $request->get('content')
        ]);
        $data->save();

        return response()->json('保存成功 :)');
    }

    /**
     * display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $data = Post::find($id);
        return response()->json($data);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request,$id)
    {
        $data = Post::find($id);
        $data->title = $request->get('title');
        $data->content = $request->get('content');
        $data->save();

        return response()->json('修改成功 :)');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $data = Post::find($id);
        $data->delete();

        return response()->json('删除成功 :)');
    }
}

2. 安装ReactJS

修改前端预置

PHP artisan preset react

npm 安装

npm install

运行

npm run dev

安装react router

npm install react-router@2.8.1

3. 创建React组件文件

我们需要创建的文件列表如下:

  • 1)app.js
  • 2)bootstrap.js
  • 3)组件/ CreatePost.js
  • 4)组件/ displayPost.js
  • 5)组件/ MasterPost.js
  • 6)组件/ MyGlobleSetting.js
  • 7)组件/ TableRow.js
  • 8)组件/ UpdatePost.js

resources/assets/js/app.js

require('./bootstrap');
import React from 'react';
import { render } from 'react-dom';
import { Router,Route,browserHistory } from 'react-router';


import Master from './components/Master';
import CreatePost from './components/CreatePost';
import displayPost from './components/displayPost';
import UpdatePost from './components/UpdatePost';


render(
  <Router history={browserHistory}>
      <Route path="/" component={Master} >
        <Route path="/add-item" component={CreatePost} />
        <Route path="/display-item" component={displayPost} />
        <Route path="/edit/:id" component={UpdatePost} />
      </Route>
    </Router>,document.getElementById('crud-app'));

resources/assets/js/bootstrap.js

window._ = require('lodash');


try {
    window.$ = window.jQuery = require('jquery');


    require('bootstrap-sass');
} catch (e) {}


window.axios = require('axios');


window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

let token = document.head.querySelector('Meta[name="csrf-token"]');

if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

resources/assets/js/components/CreatePost.js

import React,{Component} from 'react';
import {browserHistory} from 'react-router';
import MyGlobleSetting from './MyGlobleSetting';


class CreatePost extends Component {
  constructor(props){
    super(props);
    this.state = {postTitle: '',postContent: ''};


    this.handleChange1 = this.handleChange1.bind(this);
    this.handleChange2 = this.handleChange2.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);


  }
  handleChange1(e){
    this.setState({
      postTitle: e.target.value
    })
  }
  handleChange2(e){
    this.setState({
      postContent: e.target.value
    })
  }
  handleSubmit(e){
    e.preventDefault();
    const posts = {
      title: this.state.postTitle,content: this.state.postContent
    }
    let uri = MyGlobleSetting.url + '/api/posts';
    axios.post(uri,posts).then((response) => {
      browserHistory.push('/display-item');
    });
  }


    render() {
      return (
      <div>
        <h1>Create Post</h1>
        <form onSubmit={this.handleSubmit}>
          <div className="row">
            <div className="col-md-6">
              <div className="form-group">
                <label>Post Title:</label>
                <input type="text" className="form-control" onChange={this.handleChange1} />
              </div>
            </div>
            </div>
            <div className="row">
              <div className="col-md-6">
                <div className="form-group">
                  <label>Post Content:</label>
                  <textarea className="form-control col-md-6" onChange={this.handleChange2}></textarea>
                </div>
              </div>
            </div><br />
            <div className="form-group">
              <button className="btn btn-primary">Add Post</button>
            </div>
        </form>
  </div>
      )
    }
}
export default CreatePost;

resources/assets/js/components/displayPost.js

import React,{Component} from 'react';
import axios from 'axios';
import { Link } from 'react-router';
import TableRow from './TableRow';
import MyGlobleSetting from './MyGlobleSetting';
class displayPost extends Component {
  constructor(props) {
    super(props);
    this.state = {value: '',posts: ''};
  }
  componentDidMount(){
   axios.get(MyGlobleSetting.url + '/api/posts')
   .then(response => {
     this.setState({ posts: response.data });
   })
   .catch(function (error) {
     console.log(error);
   })
  }
  tabrow(){
   if(this.state.posts instanceof Array){
     return this.state.posts.map(function(object,i){
        return <TableRow obj={object} key={i} />;
     })
   }
  }


  render(){
    return (
      <div>
        <h1>Post</h1>


        <div className="row">
          <div className="col-md-10"></div>
          <div className="col-md-2">
            <Link to="/add-item">Create Post</Link>
          </div>
        </div><br />


        <table className="table table-hover">
            <thead>
            <tr>
                <td>ID</td>
                <td>Post Title</td>
                <td>Post Content</td>
                <td width="200px">Actions</td>
            </tr>
            </thead>
            <tbody>
              {this.tabrow()}
            </tbody>
        </table>
    </div>
    )
  }
}
export default displayPost;

resources/assets/js/components/Master.js

import React,{Component} from 'react';
import { Router,Link } from 'react-router';


class Master extends Component {
  render(){
    return (
      <div className="container">
        <nav className="navbar navbar-default">
          <div className="container-fluid">
            <div className="navbar-header">
              <a className="navbar-brand" href="https://www.bear777.com">bear777.com</a>
            </div>
            <ul className="nav navbar-nav">
              <li><Link to="/">Home</Link></li>
              <li><Link to="add-item">Create Post</Link></li>
              <li><Link to="display-item">Post List</Link></li>
            </ul>
          </div>
      </nav>
          <div>
              {this.props.children}
          </div>
      </div>
    )
  }
}
export default Master;

resources/assets/js/components/MyGlobleSetting.js

class MyGlobleSetting {
  constructor() {
    this.url = 'http://localhost:8000';
  }
}
export default (new MyGlobleSetting);

resources/assets/js/components/TableRow.js

import React,{ Component } from 'react';
import { Link,browserHistory } from 'react-router';
import MyGlobleSetting from './MyGlobleSetting';


class TableRow extends Component {
  constructor(props) {
      super(props);
      this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleSubmit(event) {
    event.preventDefault();
    let uri = MyGlobleSetting.url + `/api/posts/${this.props.obj.id}`;
    axios.delete(uri);
      browserHistory.push('/display-item');
  }
  render() {
    return (
        <tr>
          <td>
            {this.props.obj.id}
          </td>
          <td>
            {this.props.obj.title}
          </td>
          <td>
            {this.props.obj.content}
          </td>
          <td>
          <form onSubmit={this.handleSubmit}>
            <Link to={"edit/"+this.props.obj.id} className="btn btn-primary">Edit</Link>
           <input type="submit" value="Delete" className="btn btn-danger"/>        
         </form>
          </td>
        </tr>
    );
  }
}


export default TableRow;

resources/assets/js/components/UpdatePost.js

import React,{Component} from 'react';
import axios from 'axios';
import { Link } from 'react-router';
import MyGlobleSetting from './MyGlobleSetting';


class UpdatePost extends Component {
  constructor(props) {
      super(props);
      this.state = {title: '',content: ''};
      this.handleChange1 = this.handleChange1.bind(this);
      this.handleChange2 = this.handleChange2.bind(this);
      this.handleSubmit = this.handleSubmit.bind(this);
  }


  componentDidMount(){
    axios.get(MyGlobleSetting.url + `/api/posts/${this.props.params.id}/edit`)
    .then(response => {
      this.setState({ title: response.data.title,content: response.data.content });
    })
    .catch(function (error) {
      console.log(error);
    })
  }
  handleChange1(e){
    this.setState({
      title: e.target.value
    })
  }
  handleChange2(e){
    this.setState({
      content: e.target.value
    })
  }


  handleSubmit(event) {
    event.preventDefault();
    const posts = {
      title: this.state.title,content: this.state.content
    }
    let uri = MyGlobleSetting.url + '/api/posts/'+this.props.params.id;
    axios.patch(uri,posts).then((response) => {
          this.props.history.push('/display-item');
    });
  }
  render(){
    return (
      <div>
        <h1>Update Post</h1>
        <div className="row">
          <div className="col-md-10"></div>
          <div className="col-md-2">
            <Link to="/display-item" className="btn btn-success">Return to Post</Link>
          </div>
        </div>
        <form onSubmit={this.handleSubmit}>
            <div className="form-group">
                <label>Post Title</label>
                <input type="text"
                  className="form-control"
                  value={this.state.title}
                  onChange={this.handleChange1} />
            </div>


            <div className="form-group">
                <label name="post_content">Post Content</label>
                <textarea className="form-control"
                  onChange={this.handleChange2} value={this.state.content}></textarea>  
            </div>


            <div className="form-group">
                <button className="btn btn-primary">Update</button>
            </div>
        </form>
    </div>
    )
  }
}
export default UpdatePost;

4. 创建主视图文件

resources/views/welcome.blade.PHP

<!DOCTYPE html>
<html>
    <head>
        <Meta charset="utf-8">
        <Meta http-equiv="X-UA-Compatible" content="IE=edge">
        <Meta name="viewport" content="width=device-width,initial-scale=1">
        <title>Laravel 5.5 ReactJS CRUD Example</title>
        <link href="{{asset('css/app.css')}}" rel="stylesheet" type="text/css">
    </head>
    <body>
        <div id="crud-app"></div>
        <script src="{{asset('js/app.js')}}" ></script>
    </body>
</html>

为了避免Laravel CSRF报错
我们在视图文件head加入

<Meta name="csrf-token" content="{{ csrf_token() }}">

<script>
window.Laravel = <?PHP echo json_encode([
    'csrftoken' => csrf_token(),]); ?>
</script>

完整视图
resources/views/welcome.blade.PHP

<!DOCTYPE html>
<html>
    <head>
        <Meta charset="utf-8">
        <Meta http-equiv="X-UA-Compatible" content="IE=edge">
        <Meta name="viewport" content="width=device-width,initial-scale=1">
        <Meta name="csrf-token" content="{{ csrf_token() }}">
        <title>Laravel 5.5 ReactJS CRUD Example</title>
        <link href="{{asset('css/app.css')}}" rel="stylesheet" type="text/css">
        <script>
        window.Laravel = <?PHP echo json_encode([
            'csrftoken' => csrf_token(),]); ?>
        </script>
    </head>
    <body>
        <div id="crud-app"></div>
        <script src="{{asset('js/app.js')}}" ></script>
    </body>
</html>

5. 编译&运行

编译

npm run dev

artisan运行项目

PHP artisan serve

访问 http://localhost:8000 即可

效果图

主要参考资料 Laravel 5.5 ReactJS Tutorial

本教程翻译于 Laravel 5 - Simple CRUD Application Using ReactJS

github地址 https://github.com/pandoraxm/laravel-react-curd

原文链接 https://www.bear777.com/blog/laravel5-5-react-crud

004,elasticsearch 简单的集群管理和 CRUD 操作

004,elasticsearch 简单的集群管理和 CRUD 操作

 

    面向文档的意思:文档里边的数据结构和对象的数据结构完全一样。不像关系数据库,存储的是扁平的数据,需要将一个复杂对象拆开成多张表。

 

1、document 数据格式

面向文档的搜索分析引擎

(1)应用系统的数据结构都是面向对象的,复杂的
(2)对象数据存储到数据库中,只能拆解开来,变为扁平的多张表,每次查询的时候还得还原回对象格式,相当麻烦
(3)ES 是面向文档的,文档中存储的数据结构,与面向对象的数据结构是一样的,基于这种文档数据结构,es 可以提供复杂的索引,全文检索,分析聚合等功能
(4)es 的 document 用 json 数据格式来表达

 

2,简单的集群管理

(1)快速检查集群的健康状况       

            GET /_cat/health?v

            es 提供了一套 api,叫做 cat api,可以查看 es 中各种各样的数据

            

            如何快速了解集群的健康状况?green、yellow、red?

                green:每个索引的 primary shard 和 replica shard 都是 active 状态的
                yellow:每个索引的 primary shard 都是 active 状态的,但是部分 replica shard 不是 active 状态,处于不可用的状态
                red:不是所有索引的 primary shard 都是 active 状态的,部分索引有数据丢失了

 

(2)快速查看集群中有哪些索引

                GET  /_cat/indices?v

 

(3)简单的索引操作,创建索引

                PUT /test_index

 

 

3、商品的 CRUD 操作

(1)新增商品:新增文档,建立索引,语法:

        PUT /index/type/id
        {
              "json 数据"
        }

        注意:es 会自动建立 index 和 type,不需要提前创建,而且 es 默认会对 document 每个 field 都建立倒排索引,让其可以被搜索

 

(2)查询商品:检索文档,

        GET /index/type/id

 

(3)修改商品:替换文档,【全部替换】

        PUT /index/type/id
        {
              "json 数据"
        }

 

(4)修改商品:更新文档,【覆盖更新】

        POST /index/type/id/_update
        {
          "doc": {
                "json 数据"
          }
        }

 

(5)删除商品:删除文档,

        DELETE /index/type/id

 

 

120行代码手写一个简单的MyBatis实现简单的CRUD

120行代码手写一个简单的MyBatis实现简单的CRUD

首发于Enaium的个人博客


不用XML只用注解

首先需要创建6个注解

SQL用于输入SQL语句

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQL {
    String[] value();
}

用来表示这个方法是Update

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Update {
}

用来表示这个方法是Select

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Select {
}

用来表示这个方法是Insert

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Insert {
}

用来表示这个方法是Delete

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Delete {
}

用来表示方法参数名

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Param {
    String value();
}

好了注解写完了

开始写主类

用map实现简单的配置,然后读取配置连接数据库,然后程序关闭的时候关闭连接。

public class Satis {
    private final Statement statement;

    public Satis(Map<String, String> config) throws Exception {
        Class.forName(config.get("driver"));
        Connection connection = DriverManager.getConnection(config.get("url"), config.get("username"), config.get("password"));
        statement = connection.createStatement();
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                statement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }));
    }
}

创建getMapper方法。

public <T> T getMapper(Class<?> mapper) {

}

使用动态代理。

public <T> T getMapper(Class<?> mapper) {
    Object instance = Proxy.newProxyInstance(mapper.getClassLoader(), new Class<?>[]{mapper}, new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return null;
        }
    };
    return (T) instance;
}

遍历方法获取方法是否有SQL这个注解。

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (method.isAnnotationPresent(SQL.class)) {

    }
    return null;
}

创建4个方法,分别获取方法是否有这几个注解。

private boolean isSelect(Method method) {
    return method.isAnnotationPresent(Select.class);
}
private boolean isDelete(Method method) {
    return method.isAnnotationPresent(Delete.class);
}
private boolean isInsert(Method method) {
    return method.isAnnotationPresent(Insert.class);
}
private boolean isUpdate(Method method) {
    return method.isAnnotationPresent(Update.class);
}

遍历SQL注解的值。

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (method.isAnnotationPresent(SQL.class)) {
        SQL sql = method.getAnnotation(SQL.class);
        for (String value : sql.value()) {
            
        }
    }
    return null;
}

获取方法上是否有SelectDelete注解,是的话把SQL参数的值(获取参数的Param注解的值)替换为调用方法时的参数。

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (method.isAnnotationPresent(SQL.class)) {
        SQL sql = method.getAnnotation(SQL.class);
        for (String value : sql.value()) {
            if (isSelect(method) || isDelete(method)) {
                int index = 0;
                for (Parameter parameter : method.getParameters()) {
                    if (parameter.isAnnotationPresent(Param.class)) {
                        Param param = parameter.getAnnotation(Param.class);
                        value = value.replace("#{" + param.value() + "}", args[index].toString());
                    }
                    index++;
                }
            }
        }
    }
    return null;
}

如果是InsertUpdate注解,获取第一个参数,获取这个参数的所有方法并获取值。

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (method.isAnnotationPresent(SQL.class)) {
        SQL sql = method.getAnnotation(SQL.class);
        for (String value : sql.value()) {
            if (isInsert(method) || isUpdate(method)) {
                Class<?> parameterType = method.getParameterTypes()[0];
                for (Field declaredField : parameterType.getDeclaredFields()) {
                    value = value.replace("#{" + declaredField.getName() + "}", "\"" + parameterType.getMethod(getGetMethodName(declaredField.getName())).invoke(args[0]).toString() + "\"");
                }
            }
        }
    }
    return null;
}

简单的获取方法名的方法。

private String getSetMethodName(String name) {
    return "set" + name.substring(0, 1).toUpperCase(Locale.ROOT) + name.substring(1);
}
private String getGetMethodName(String name) {
    return "get" + name.substring(0, 1).toUpperCase(Locale.ROOT) + name.substring(1);
}

执行SQL语句,如果有返回值那就返回实例化。

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (method.isAnnotationPresent(SQL.class)) {
        SQL sql = method.getAnnotation(SQL.class);
        for (String value : sql.value()) {
            String typeName = method.getGenericReturnType().getTypeName();
            ResultSet resultSet = statement.executeQuery(value);
            if (!typeName.equals("void")) {
                return toEntity(resultSet, typeName);
            }
        }
    }
    return null;
}

将返回值实例化。

private <T> T toEntity(ResultSet resultSet, String className) throws SQLException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException {
    boolean list = className.contains("<");//是不是列表
    if (list) {
        className = className.substring(className.indexOf("<") + 1, className.lastIndexOf(">"));//获取列表的泛型
    }
    Class<?> klass = Class.forName(className);
    HashMap<String, Class<?>> fieldNameList = new HashMap<>();
    for (int i = 0; i < resultSet.getMetaData().getColumnCount(); i++) {//获取字段和参数
        fieldNameList.put(resultSet.getMetaData().getColumnName(i + 1), Class.forName(resultSet.getMetaData().getColumnClassName(i + 1)));
    }
    List<Object> objectList = new ArrayList<>();
    while (resultSet.next()) {
        Object instance = klass.newInstance();//实例化
        for (Map.Entry<String, Class<?>> entry : fieldNameList.entrySet()) {//遍历字段
            //调用set方法赋值
            klass.getMethod(getSetMethodName(entry.getKey()), entry.getValue()).invoke(instance, resultSet.getObject(entry.getKey(), entry.getValue()));
        }
        objectList.add(instance);//添加到列表
    }
    resultSet.close();//关闭
    if (objectList.isEmpty()) {
        return null;//如果列表为空返回null
    }
    return list ? (T) objectList : (T) objectList.get(0);//判断是否为列表,如果是直接返回,如果不是取第一个
}

好了已经写完了。

现在来测试

实体

@Data
@AllArgsConstructor
public class AccountEntity {
    private Long id;
    private String name;
    private Integer age;

    public AccountEntity() {//用了lombok就不会自动生成无参构造方法了

    }
}

接口

public interface AccountMapper {
    @Select
    @SQL("select * from account")
    List<AccountEntity> getAll();

    @Select
    @SQL("select * from account where id = #{id}")
    AccountEntity getById(@Param("id") Serializable id);

    @Delete
    @SQL("delete from account where id = #{id}")
    void deleteById(@Param("id") Serializable id);

    @Insert
    @SQL("insert into account(id, name, age) values (#{id}, #{name}, #{age})")
    void insert(AccountEntity accountEntity);

    @Update
    @SQL("update account set name=#{name}, age=#{age} where id=#{id}")
    void update(AccountEntity accountEntity);
}

主类

public class Main {
    public static void main(String[] args) throws Exception {
        Satis satis = new Satis(ImmutableMap.of(
                "url", "jdbc:mariadb://localhost:3306/enaium?useUnicode=true&characterEncoding=UTF-8",
                "driver", "org.mariadb.jdbc.Driver",
                "username", "root",
                "password", "root"));//使用guava
        AccountMapper mapper = satis.getMapper(AccountMapper.class);//获取Mapper
        System.out.println(mapper.getById(1));//获取ID为1的Account
        mapper.getAll().forEach(System.out::println);//获取所有Account
        mapper.insert(new AccountEntity(0L, "Enaium", 1));//插入一个新的Account
        mapper.getAll().forEach((it) -> {//把所有Account的Age都改为0
            it.setAge(0);
            mapper.update(it);
        });
    }
}

源码

es-for-Laravel: Composer 包安装, Laravel 最简单的方式操作 Elasticsearch

es-for-Laravel: Composer 包安装, Laravel 最简单的方式操作 Elasticsearch

composer 安装:composer require ethansmart/es-for-laravel
github 地址:https://github.com/roancsu/es-for-laravel

ES for Laravel

Usage EsBuilder 有两种模式

  1. ES ORM Client (ORM模式):支持Model映射
  2. ES Client (非ORM模式):支持原生ES

使用 ES ORM Client 首先创建ORM Model


use Ethansmart\EsBuilder\Model\EsModel;

/**
 * Class AtPerson
 * $host ES IP或URL地址
 * $port ES 端口
 * $index ES 索引名称
 * $type ES 索引 type名称
 * @package Ethan\EsBuilder\Model
 */

class AtPerson extends EsModel
{
    protected $host = "127.0.0.1";
    protected $port = "32800";
    protected $index = "accounts";
    protected $type = "person";
}

然后使用Model对ES进行CURD操作

搜索


try {
    $result = AtPerson::build()
              ->select("user")
              ->where("user",''=='',"chengluo")
              ->where("title,desc","like","AI")
              ->where("create_time","<","2018-10-05")
              ->get();

} catch (\Exception $e) {
    return [''code''=>-1, ''msg''=>$e->getMessage()];
}

return $result;

新增


try {
    $id = 5;
    $data = [
       ''id''=>$id,
       ''params''=>[
            ''user''=>''Ethan Cheng'',
            ''title''=>''AI ''.str_random(8),
            ''desc''=>''AI ''.str_random(12)
       ]
    ];
    $result = AtPerson::build()->create($data);
} catch (\Exception $e) {
    return [''code''=>-1, ''msg''=>$e->getMessage()];
}

return $result;

更新


try {
    $id = 5;
    $data = [
        ''id''=>$id,
        ''params''=>[
             ''user''=>''Ethan Cheng'',
             ''title''=>''AI ''.str_random(8),
             ''desc''=>''AI ''.str_random(12)
        ]
    ];
    $result = AtPerson::build()->update($data);
} catch (\Exception $e) {
    return [''code''=>-1, ''msg''=>$e->getMessage()];
}

return $result;

删除


try {
    $id = 5;
    $result = AtPerson::build()->delete($id);
} catch (\Exception $e) {
    throw $e;
}
     
return $result;

使用 ES Client 首先构建 Client


private $client ;

public function __construct()
{
     $host = "127.0.0.1";
     $port = "32800";
     $this->client = EsClientBuilder::create()
         ->setHosts($host)
         ->setPort($port)
         ->build();
}

调用Client中的方法对ES进行CURD操作


$data = [
     ''index''=>''accounts'',
     ''type''=>''person'',
     ''body''=>[
          "query"=>[
               "bool"=>[
                   "must"=>[
                         "match"=>[
                              "user"=>"ethan"
                         ]
                   ]
               ]
          ]
     ],
];

try {
    $result = $this->client->search($data);
} catch (\Exception $e) {
    return [''code''=>-1, ''msg''=>$e->getMessage()];
}
return $result;

其他方法类似

创建Laravel Job 同步数据到 ES

use Ethansmart\EsBuilder\Builder\EsClientBuilder;

class EsService
{
    private $client ;
    public function __construct()
    {
        $host = "127.0.0.1";
        $port = "32800";
        $this->client = EsClientBuilder::create()
            ->setHosts($host)
            ->setPort($port)
            ->build();
    }

    public function create($id)
    {
        $data = [
            ''index''=>''accounts'',
            ''type''=>''person'',
            ''id''=>$id,
            ''body''=>[
                ''user''=>str_random(6),
                ''title''=>str_random(12),
                ''desc''=>str_random(16),
            ]
        ];
        try {
            $result =  $this->client->create($data);
        } catch (\Exception $e) {
            return [''code''=>-1, ''msg''=>$e->getMessage()];
        }

        return $result;
    }
}

Q: 在使用 composer 安装过程中会出现 如下异常: [InvalidArgumentException] Could not find a version of package ethansmart/es-for-laravel matching your minimum-stability (stable). Require it with an explicit version constraint allowing its desired stability. 解决方法: 在项目composer.json文件中加入:

"repositories": [
        {
            "packagist.org": false
        },
        {
            "type": "composer",
            "url": "https://packagist.org"
        }
    ],

将国内的composer镜像换成 packagist.org 就可以了。

java – 如何设计一个简单的CRUD REST API

java – 如何设计一个简单的CRUD REST API

我正在设计一个简单的CRUD REST API.这是我的第一次,所以我想得到一些关于我的设计是否有意义的反馈.

我正在使用HTTP方法:GET,POST,DELETE和UPDATE. API将以JSON格式使用和获取数据.示例网址将如下所示:

GET (list): curl http://<domain>/myapp/rest/v1/colors
POST: curl -XPOST http://<domain>/myapp/rest/v1/colors -d '{
       "name": "red","shade": "light"
      }'
GET (single item): curl http://<domain>/myapp/rest/v1/colors/2
DELETE: curl -XDELETE http://<domain>/myapp/rest/v1/colors/2
etc...

POST请求后,将在数据库中创建一条记录.那么,POST请求是否应该返回新创建的记录的ID?那么ID可以在UPDATE,DELETE和GET(单项)中使用?

解决方法

HTTP specification为POST定义了以下内容:

If a resource has been created on the origin server,the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource,and a Location header (see section 14.30).

所以这基本上意味着:

>您应该返回201 Created as status code>您应返回Location标头,指向新创建的资源的URI>您可以选择在POST响应正文中包含资源的表示,以使客户端不必针对从Location标头获取的值发出另一个GET请求.

今天的关于laravel5.5 + react完成简单的CRUDlaravel action的分享已经结束,谢谢您的关注,如果想了解更多关于004,elasticsearch 简单的集群管理和 CRUD 操作、120行代码手写一个简单的MyBatis实现简单的CRUD、es-for-Laravel: Composer 包安装, Laravel 最简单的方式操作 Elasticsearch、java – 如何设计一个简单的CRUD REST API的相关知识,请在本站进行查询。

本文标签: