文章目录
- 前言
- 一、引入jar包依赖
- 二、配置 application.properties
- 三、Mybatis Neo4j分页插件
- 四、Mybatis Neo4j自定义转换器handler
- 五、Mybatis+Neo4j代码示例
- 总结
前言
MyBatis是一个基于Java语言的持久层框架,它通过XML描述符或注解将对象与存储过程或SQL语句进行映射,并提供了普通SQL查询、存储过程和高级映射等操作方式,使得操作数据库变得非常方便。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
Neo4j 是一个高性能的NOSQL 图数据库,它将结构化数据存储在图中而不是表中。它非常适合于表示和查询高度连接的数据,例如社交网络、推荐系统和知识图谱等。
Neo4j数据模型和查询语言 Cypher 与传统的关系型数据库有很大的不同。因此原生MyBatis 并不支持 Neo4j,需要引入第三方jar包,并通过配置和编码的方式进行集成。
一、引入jar包依赖
POM.XML 添加依赖neo4j-jdbc-driver mybatis-spring-boot-starter
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-jdbc-driver</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
二、配置 application.properties
######## neo4j图数据源
spring.datasource.neo4j.username=neo4j
spring.datasource.neo4j.password=xxxxx
spring.datasource.neo4j.url=jdbc:neo4j:http://192.168.3.179:7474
spring.datasource.neo4j.driver-class-name=org.neo4j.jdbc.http.HttpDriver
#spring.datasource.neo4j.url=jdbc:neo4j:bolt://localhost:7687
#spring.datasource.neo4j.driver-class-name=org.neo4j.jdbc.bolt.BoltDriver
spring.datasource.neo4j.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.target-names=neo4j
创建mapper文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="neo4jExampleMapper" >
<!-- 自定义结果集-->
<resultMap id="userMap" type="example.neo4j.ExampleUserModel">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
</resultMap>
<select id="getAll" resultMap="userMap">
match
(u:user)
return
id(u) as id,u.name as name,u.age as age,u.sex as sex
</select>
<select id="getById" resultMap="userMap">
match
(u:user)
where
id(u) = #{id}
return
id(u) as id,u.name as name,u.age as age,u.sex as sex
</select>
<insert id="add" parameterType="example.neo4j.ExampleUserModel">
create(u:user{name:#{name},age:#{age},sex:#{sex}})
</insert>
<update id="update">
match (u:user)
where id(u) = #{id}
set u.name = #{name},u.age = #{age},u.sex = #{sex}
</update>
</mapper>
三、Mybatis Neo4j分页插件
public class Neo4jDialect extends PageDialect {
@Override
public boolean supportsLimit() {
return true;
}
@Override
public String getLimitString(String sql, int offset, int limit) {
return getLimitString(sql, offset, Integer.toString(offset), Integer.toString(limit));
}
private String getLimitString(final String sql,
final int offset,
final String offsetPlaceholder,
final String limitPlaceholder) {
StringBuilder stringBuilder = new StringBuilder(getLineSql(sql));
if (offset > 0) {
stringBuilder.append(" skip ").append(offsetPlaceholder).append(" limit ").append(limitPlaceholder);
} else {
stringBuilder.append(" limit ").append(limitPlaceholder);
}
return stringBuilder.toString();
}
@Override
public String getCountString(String sql) {
String newsql;
if (CountHelper.containOrder(sql) && !CountHelper.containOver(sql)) {
newsql = getNonOrderByPart(sql);
} else {
newsql = sql;
}
return "call { " + newsql.trim() + "} return count(*) as tmp_count";
}
protected String getLineSql(String sql) {
return sql.replaceAll("[\r\n]", " ").replaceAll("\\s{2,}", " ");
}
private static String getNonOrderByPart(String sql) {
return CountHelper.removeOrders(sql);
}
}
四、Mybatis Neo4j自定义转换器handler
/**
* 将查询结果中的json格式的字段进行转换的自定义转换器,转换为实体类的JSONObject属性
*/
@MappedTypes(JSONObject.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class JSONObjectTypeHandler extends BaseTypeHandler<JSONObject> {
/**
* 设置非空参数
* @param ps
* @param i
* @param parameter
* @param jdbcType
* @throws SQLException
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, JSONObject parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, String.valueOf(parameter.toJSONString()));
}
/**
* 根据列名,获取可以为空的结果
* @param rs
* @param columnName
* @return
* @throws SQLException
*/
@Override
public JSONObject getNullableResult(ResultSet rs, String columnName) throws SQLException {
String sqlJson = rs.getString(columnName);
if (null != sqlJson){
return JSONObject.parseObject(sqlJson);
}
return null;
}
/**
* 根据列索引,获取可以为空的结果
* @param rs
* @param columnIndex
* @return
* @throws SQLException
*/
@Override
public JSONObject getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String sqlJson = rs.getString(columnIndex);
if (null != sqlJson){
return JSONObject.parseObject(sqlJson);
}
return null;
}
@Override
public JSONObject getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String sqlJson = cs.getString(columnIndex);
if (null != sqlJson){
return JSONObject.parseObject(sqlJson);
}
return null;
}
}
五、Mybatis+Neo4j代码示例
对Neo4j的增改查
public class Neo4jExampleService {
@Resource
private MybatisSqlSession mybatisSqlSession;
@Resource
private DataSource datasource;
public ExampleUserModel getUserInfo(String userid) {
ExampleUserModel user=mybatisSqlSession.selectById("neo4jExampleMapper.getById", userid);
return user;
}
public List<ExampleUserModel> getAllUser() {
List<ExampleUserModel> userList=mybatisSqlSession.selectByParams("neo4jExampleMapper.getAll", null);
return userList;
}
@SuppressWarnings("unchecked")
public DataPaging getPageUser(Integer page) {
PageRequest pageRequest = new PageRequest(page, 4, null);
DataPaging pageing=mybatisSqlSession.selectPaging("neo4jExampleMapper.getAll", pageRequest);
return pageing;
}
public void insert( ExampleUserModel model) {
//MATCH (n:user) return n
mybatisSqlSession.insert("neo4jExampleMapper.add", model);
}
@Transactional(rollbackFor = Exception.class)
public void addAndUpdate( ExampleUserModel model) {
//MATCH (n:user) return n
System.out.println("before insert "+datasource);
mybatisSqlSession.insert("neo4jExampleMapper.add", model);
System.out.println("after insert");
ExampleUserModel updateUser=new ExampleUserModel();
updateUser.setId(1237L);
updateUser.setName("dTest");
updateUser.setAge(20);
mybatisSqlSession.update("neo4jExampleMapper.update", updateUser);
}
总结
以上只是摘取了框架中的一部分代码,本文只是提供了一些具体设计思路,其它部分需要自行完善。