Как правильно вернуть StatementResult с функцией транзакции? - PullRequest
0 голосов
/ 03 января 2019

Может быть, самого названия достаточно, чтобы выразить мое замешательство.С одной стороны, я много читал, что использование транзакционных функций является рекомендуемым способом использования Java-драйвера neo4j.

См. Драйвер Java Neo4j

С другой стороны, я вижу примеры кодов, таких как API драйвера Neo4j 1.7 API , где естьнет транзакции (или, может быть, она неявная), и мне нравится идея иметь StatementResult и повторять его.

Так что мне делать?

Есть ли способ использовать итератор для автоматической фиксации перехода в функции транзакции?Должен ли я продолжать использовать функцию execute(), функцию session.writeTransaction()?

Мне кажется, что существует простой способ выполнения простого запроса, но он не может понять, почему или эти методы могут быть немного перепутаны.

I 'Я не очень доволен writeTransaction, если я смогу извлечь из него только строку.

Для этого драйвера также есть примеры GitHub , особенно ResultRetain с объектом «Запись», который ближе к тому, что я ищу, но без итератора.Это позволяет извлекать данные с помощью аксессоров.Другим близким примером является ResultConsume , но все еще без итератора.

На основе этих примеров я написал следующий код, он работает, как и ожидалось, с генератором и геттерами.

import org.neo4j.driver.v1.Record;
import org.neo4j.driver.v1.Session;
import org.neo4j.driver.v1.StatementResult;
import org.neo4j.driver.v1.Transaction;
import org.neo4j.driver.v1.TransactionWork;


public class InitializeUser extends Logger{
  StatementResult result;

  public void getUserForInitialization(){
    try ( Session session = driver.session() )
    {
      result = session.readTransaction( new TransactionWork<StatementResult>()
        {
            @Override
            public StatementResult execute( Transaction tx )
            {
                return tx.run(
                  "MATCH (a{initialized:false}) "+
                  "RETURN a.username as username");
            }
        } );
    }
  }

  public void readGenerator(){
    while (result.hasNext())
    {
        Record record = result.next();
        System.out.println(record.get("username").asString());
    }
  }
}

Я не уверен, что это хуже или лучше, чем следовать примеру ResultRetain или ResultConsume , но в нем есть генератор, геттеры и то, что я считаю функциями транзакций.Я все еще очень открыт для предложений и объяснений.

Если бы кто-то мог немного объяснить механику, стоящую за TransactionWork(), execute(), и в чем разница между readTransaction(), writeTransaction(), run() и beginTransaction(), я был бы рад.


Драйвер Java Neo4j

import org.neo4j.driver.v1.AuthTokens;
import org.neo4j.driver.v1.Driver;
import org.neo4j.driver.v1.GraphDatabase;
import org.neo4j.driver.v1.Session;
import org.neo4j.driver.v1.StatementResult;
import org.neo4j.driver.v1.Transaction;
import org.neo4j.driver.v1.TransactionWork;

import static org.neo4j.driver.v1.Values.parameters;

public class HelloWorldExample implements AutoCloseable
{
    private final Driver driver;

    public HelloWorldExample( String uri, String user, String password )
    {
        driver = GraphDatabase.driver( uri, AuthTokens.basic( user, password ) );
    }

    @Override
    public void close() throws Exception
    {
        driver.close();
    }

    public void printGreeting( final String message )
    {
        try ( Session session = driver.session() )
        {
            String greeting = session.writeTransaction( new TransactionWork<String>()
            {
                @Override
                public String execute( Transaction tx )
                {
                    StatementResult result = tx.run( "CREATE (a:Greeting) " +
                                                     "SET a.message = $message " +
                                                     "RETURN a.message + ', from node ' + id(a)",
                            parameters( "message", message ) );
                    return result.single().get( 0 ).asString();
                }
            } );
            System.out.println( greeting );
        }
    }

    public static void main( String... args ) throws Exception
    {
        try ( HelloWorldExample greeter = new HelloWorldExample( "bolt://localhost:7687", "neo4j", "password" ) )
        {
            greeter.printGreeting( "hello, world" );
        }
    }
}

Драйвер Java Neo4j 1.7 API

import org.neo4j.driver.v1.*;

import static org.neo4j.driver.v1.Values.parameters;

public class SmallExample
{
    // Driver objects are thread-safe and are typically made available application-wide.
    Driver driver;

    public SmallExample(String uri, String user, String password)
    {
        driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password));
    }

    private void addPerson(String name)
    {
        // Sessions are lightweight and disposable connection wrappers.
        try (Session session = driver.session())
        {
            // Wrapping Cypher in an explicit transaction provides atomicity
            // and makes handling errors much easier.
            try (Transaction tx = session.beginTransaction())
            {
                tx.run("MERGE (a:Person {name: {x}})", parameters("x", name));
                tx.success();  // Mark this write as successful.
            }
        }
    }

    private void printPeople(String initial)
    {
        try (Session session = driver.session())
        {
            // Auto-commit transactions are a quick and easy way to wrap a read.
            StatementResult result = session.run(
                    "MATCH (a:Person) WHERE a.name STARTS WITH {x} RETURN a.name AS name",
                    parameters("x", initial));
            // Each Cypher execution returns a stream of records.
            while (result.hasNext())
            {
                Record record = result.next();
                // Values can be extracted from a record by index or name.
                System.out.println(record.get("name").asString());
            }
        }
    }

    public void close()
    {
        // Closing a driver immediately shuts down all open connections.
        driver.close();
    }

    public static void main(String... args)
    {
        SmallExample example = new SmallExample("bolt://localhost:7687", "neo4j", "password");
        example.addPerson("Ada");
        example.addPerson("Alice");
        example.addPerson("Bob");
        example.printPeople("A");
        example.close();
    }
}

Драйвер Java Neo4j ResultRetainExample

import java.util.List;

import org.neo4j.driver.v1.Record;
import org.neo4j.driver.v1.Session;
import org.neo4j.driver.v1.Transaction;
import org.neo4j.driver.v1.TransactionWork;

import static org.neo4j.driver.v1.Values.parameters;
// end::result-retain-import[]

public class ResultRetainExample extends BaseApplication
{
    public ResultRetainExample( String uri, String user, String password )
    {
        super( uri, user, password );
    }

    // tag::result-retain[]
    public int addEmployees( final String companyName )
    {
        try ( Session session = driver.session() )
        {
            int employees = 0;
            List<Record> persons = session.readTransaction( new TransactionWork<List<Record>>()
            {
                @Override
                public List<Record> execute( Transaction tx )
                {
                    return matchPersonNodes( tx );
                }
            } );
            for ( final Record person : persons )
            {
                employees += session.writeTransaction( new TransactionWork<Integer>()
                {
                    @Override
                    public Integer execute( Transaction tx )
                    {
                        tx.run( "MATCH (emp:Person {name: $person_name}) " +
                                "MERGE (com:Company {name: $company_name}) " +
                                "MERGE (emp)-[:WORKS_FOR]->(com)",
                                parameters( "person_name", person.get( "name" ).asString(), "company_name",
                                        companyName ) );
                        return 1;
                    }
                } );
            }
            return employees;
        }
    }

    private static List<Record> matchPersonNodes( Transaction tx )
    {
        return tx.run( "MATCH (a:Person) RETURN a.name AS name" ).list();
    }

    // end::result-retain[]

}

Neo4j Java Driver ResultConsumeExample

import java.util.ArrayList;
import java.util.List;

import org.neo4j.driver.v1.Session;
import org.neo4j.driver.v1.StatementResult;
import org.neo4j.driver.v1.Transaction;
import org.neo4j.driver.v1.TransactionWork;
// end::result-consume-import[]

public class ResultConsumeExample extends BaseApplication
{
    public ResultConsumeExample( String uri, String user, String password )
    {
        super( uri, user, password );
    }

    // tag::result-consume[]
    public List<String> getPeople()
    {
        try ( Session session = driver.session() )
        {
            return session.readTransaction( new TransactionWork<List<String>>()
            {
                @Override
                public List<String> execute( Transaction tx )
                {
                    return matchPersonNodes( tx );
                }
            } );
        }
    }

    private static List<String> matchPersonNodes( Transaction tx )
    {
        List<String> names = new ArrayList<>();
        StatementResult result = tx.run( "MATCH (a:Person) RETURN a.name ORDER BY a.name" );
        while ( result.hasNext() )
        {
            names.add( result.next().get( 0 ).asString() );
        }
        return names;
    }
    // end::result-consume[]

}
...