Может быть, самого названия достаточно, чтобы выразить мое замешательство.С одной стороны, я много читал, что использование транзакционных функций является рекомендуемым способом использования 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[]
}