Skip to content

UpdateByExample Support Improvement #121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,30 @@
* q.where(occupation, isNull()));
* </pre>
*
* <p>You can also do a "count all" with the following code:
* <p>You can implement a "count all" with the following code:
*
* <pre>
* long rows = mapper.countByExample(q -&gt; q);
* </pre>
*
* <p>Or
*
* <pre>
* long rows = mapper.countByExample(MyBatis3CountByExampleHelper.allRows());
* </pre>
*
* @author Jeff Butler
*/
@FunctionalInterface
public interface MyBatis3CountByExampleHelper extends
Function<QueryExpressionDSL<MyBatis3SelectModelAdapter<Long>>, Buildable<MyBatis3SelectModelAdapter<Long>>> {

/**
* Returns a helper that can be used to count every row in a table.
*
* @return the helper that will count every row in a table
*/
static MyBatis3CountByExampleHelper allRows() {
return h -> h;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,30 @@
* q.where(occupation, isNull()));
* </pre>
*
* <p>You can also do a "delete all" with the following code:
* <p>You can implement a "delete all" with the following code:
*
* <pre>
* int rows = mapper.deleteByExample(q -&gt; q);
* </pre>
*
* <p>Or
*
* <pre>
* long rows = mapper.deleteByExample(MyBatis3DeleteByExampleHelper.allRows());
* </pre>

* @author Jeff Butler
*/
@FunctionalInterface
public interface MyBatis3DeleteByExampleHelper extends
Function<DeleteDSL<MyBatis3DeleteModelAdapter<Integer>>, Buildable<MyBatis3DeleteModelAdapter<Integer>>> {

/**
* Returns a helper that can be used to delete every row in a table.
*
* @return the helper that will delete every row in a table
*/
static MyBatis3DeleteByExampleHelper allRows() {
return h -> h;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,33 @@
* .or(occupation, isNull()));
* </pre>
*
* <p>You can also do a "select all" with the following code:
* <p>You can implement a "select all" with the following code:
*
* <pre>
* List&lt;SimpleRecord&gt; rows = mapper.selectByExample(q -&gt; q);
* </pre>
*
* <p>Or
*
* <pre>
* List&lt;SimpleRecord&gt; rows = mapper.selectByExample(MyBatis3SelectByExampleHelper.allRows());
* </pre>
*
* @author Jeff Butler
*/
@FunctionalInterface
public interface MyBatis3SelectByExampleHelper<T> extends
Function<QueryExpressionDSL<MyBatis3SelectModelAdapter<List<T>>>,
Buildable<MyBatis3SelectModelAdapter<List<T>>>> {

/**
* Returns a helper that can be used to select every row in a table.
*
* @param <T> the type of row returned
*
* @return the helper that will select every row in a table
*/
static <T> MyBatis3SelectByExampleHelper<T> allRows() {
return h -> h;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* Copyright 2016-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mybatis.dynamic.sql.util.mybatis3;

import java.util.Objects;
import java.util.function.ToIntFunction;

import org.mybatis.dynamic.sql.SqlTable;
import org.mybatis.dynamic.sql.update.UpdateDSL;
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;

/**
* This class is used to complete an update by example method in the style of MyBatis generator.
*
* @author Jeff Butler
*
* @see MyBatis3UpdateByExampleHelper
*
* @param <T> the type of record that will be updated
*/
public class MyBatis3UpdateByExampleCompleter<T> {
private SqlTable table;
private MyBatis3UpdateByExampleHelper helper;
private ToIntFunction<UpdateStatementProvider> mapper;
private MyBatis3UpdateByExampleValueSetter<T> valueSetter;

private MyBatis3UpdateByExampleCompleter(MyBatis3UpdateByExampleCompleter.Builder<T> builder) {
helper = Objects.requireNonNull(builder.helper);
mapper = Objects.requireNonNull(builder.mapper);
valueSetter = Objects.requireNonNull(builder.valueSetter);
table = Objects.requireNonNull(builder.table);
}

public int usingRecord(T record) {
return valueSetter.andThen(helper)
.apply(record, UpdateDSL.updateWithMapper(p -> mapper.applyAsInt(p), table))
.build()
.execute();
}

public static class Builder<T> {
private SqlTable table;
private MyBatis3UpdateByExampleHelper helper;
private ToIntFunction<UpdateStatementProvider> mapper;
private MyBatis3UpdateByExampleValueSetter<T> valueSetter;

public MyBatis3UpdateByExampleCompleter.Builder<T> withTable(SqlTable table) {
this.table = table;
return this;
}

public MyBatis3UpdateByExampleCompleter.Builder<T> withHelper(MyBatis3UpdateByExampleHelper helper) {
this.helper = helper;
return this;
}

public MyBatis3UpdateByExampleCompleter.Builder<T> withMapper(
ToIntFunction<UpdateStatementProvider> mapper) {
this.mapper = mapper;
return this;
}

public MyBatis3UpdateByExampleCompleter.Builder<T> withValueSetter(
MyBatis3UpdateByExampleValueSetter<T> valueSetter) {
this.valueSetter = valueSetter;
return this;
}

public MyBatis3UpdateByExampleCompleter<T> build() {
return new MyBatis3UpdateByExampleCompleter<>(this);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,36 +32,60 @@
* &#64;UpdateProvider(type=SqlProviderAdapter.class, method="update")
* int update(UpdateStatementProvider updateStatement);
*
* default int updateByExampleSelective(SimpleTableRecord record, MyBatis3UpdateByExampleHelper helper) {
* return helper.apply(UpdateDSL.updateWithMapper(this::update, simpleTable)
* .set(id).equalToWhenPresent(record.getId())
* .set(firstName).equalToWhenPresent(record::getFirstName)
* .set(lastName).equalToWhenPresent(record::getLastName)
* .set(birthDate).equalToWhenPresent(record::getBirthDate)
* .set(employed).equalToWhenPresent(record::getEmployed)
* .set(occupation).equalToWhenPresent(record::getOccupation))
* .build()
* .execute();
* default MyBatis3UpdateByExampleCompleter updateByExampleSelective(MyBatis3UpdateByExampleHelper helper) {
* return new MyBatis3UpdateByExampleCompleter.Builder&lt;SimpleTableRecord&gt;()
* .withHelper(helper)
* .withMapper(this::update)
* .withTable(simpleTable)
* .withValueSetter((record, dsl) -&gt;
* dsl.set(id).equalToWhenPresent(record::getId)
* .set(firstName).equalToWhenPresent(record::getFirstName)
* .set(lastName).equalToWhenPresent(record::getLastName)
* .set(birthDate).equalToWhenPresent(record::getBirthDate)
* .set(employed).equalToWhenPresent(record::getEmployed)
* .set(occupation).equalToWhenPresent(record::getOccupation))
* .build();
* }
* </pre>
*
* <p>And then call the simplified default method like this:
*
* <pre>
* int rows = mapper.updateByExampleSelective(record, q -&gt;
* int rows = mapper.updateByExampleSelective(q -&gt;
* q.where(id, isEqualTo(100))
* .and(firstName, isEqualTo("Joe")));
* .and(firstName, isEqualTo("Joe")))
* .usingRecord(record);
* </pre>
*
* <p>You can also do an "update all" with the following code:
* <p>You can implement an "update all" with the following code:
*
* <pre>
* int rows = mapper.updateByExampleSelective(record, q -&gt; q);
* int rows = mapper.updateByExampleSelective(q -&gt; q)
* .usingRecord(record);
* </pre>
*
* <p>Or
*
* <pre>
* int rows = mapper.updateByExampleSelective(MyBatis3UpdateByExampleHelper.allRows())
* .usingRecord(record);
* </pre>
*
* @see MyBatis3UpdateByExampleCompleter
* @see MyBatis3UpdateByExampleValueSetter
*
* @author Jeff Butler
*/
@FunctionalInterface
public interface MyBatis3UpdateByExampleHelper extends
Function<UpdateDSL<MyBatis3UpdateModelAdapter<Integer>>, Buildable<MyBatis3UpdateModelAdapter<Integer>>> {

/**
* Returns a helper that can be used to update every row in a table.
*
* @return the helper that will update every row in a table
*/
static MyBatis3UpdateByExampleHelper allRows() {
return h -> h;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright 2016-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mybatis.dynamic.sql.util.mybatis3;

import java.util.function.BiFunction;

import org.mybatis.dynamic.sql.update.MyBatis3UpdateModelAdapter;
import org.mybatis.dynamic.sql.update.UpdateDSL;

/**
* Represents a function that can be used to create an "UpdateByExample" method in the style
* of MyBatis Generator. When using this function, you can create a method that will map record fields to
* tables columns to be updated in a common mapper, and then allow a user to set a where clause as needed.
*
* @author Jeff Butler
*
* @see MyBatis3UpdateByExampleHelper
*
* @param <T> the type of record that will be updated
*/
@FunctionalInterface
public interface MyBatis3UpdateByExampleValueSetter<T> extends
BiFunction<T, UpdateDSL<MyBatis3UpdateModelAdapter<Integer>>, UpdateDSL<MyBatis3UpdateModelAdapter<Integer>>> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3CountByExampleHelper;
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3DeleteByExampleHelper;
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3SelectByExampleHelper;
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3UpdateByExampleCompleter;
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3UpdateByExampleHelper;

/**
Expand Down Expand Up @@ -170,30 +171,36 @@ default SimpleTableRecord selectByPrimaryKey(Integer id_) {
.execute();
}

default int updateByExample(SimpleTableRecord record, MyBatis3UpdateByExampleHelper helper) {
return helper.apply(UpdateDSL.updateWithMapper(this::update, simpleTable)
.set(id).equalTo(record.getId())
.set(firstName).equalTo(record::getFirstName)
.set(lastName).equalTo(record::getLastName)
.set(birthDate).equalTo(record::getBirthDate)
.set(employed).equalTo(record::getEmployed)
.set(occupation).equalTo(record::getOccupation))
.build()
.execute();
default MyBatis3UpdateByExampleCompleter<SimpleTableRecord> updateByExample(MyBatis3UpdateByExampleHelper helper) {
return new MyBatis3UpdateByExampleCompleter.Builder<SimpleTableRecord>()
.withHelper(helper)
.withMapper(this::update)
.withTable(simpleTable)
.withValueSetter((record, dsl) ->
dsl.set(id).equalTo(record::getId)
.set(firstName).equalTo(record::getFirstName)
.set(lastName).equalTo(record::getLastName)
.set(birthDate).equalTo(record::getBirthDate)
.set(employed).equalTo(record::getEmployed)
.set(occupation).equalTo(record::getOccupation))
.build();
}

default int updateByExampleSelective(SimpleTableRecord record, MyBatis3UpdateByExampleHelper helper) {
return helper.apply(UpdateDSL.updateWithMapper(this::update, simpleTable)
.set(id).equalToWhenPresent(record.getId())
.set(firstName).equalToWhenPresent(record::getFirstName)
.set(lastName).equalToWhenPresent(record::getLastName)
.set(birthDate).equalToWhenPresent(record::getBirthDate)
.set(employed).equalToWhenPresent(record::getEmployed)
.set(occupation).equalToWhenPresent(record::getOccupation))
.build()
.execute();

default MyBatis3UpdateByExampleCompleter<SimpleTableRecord> updateByExampleSelective(MyBatis3UpdateByExampleHelper helper) {
return new MyBatis3UpdateByExampleCompleter.Builder<SimpleTableRecord>()
.withHelper(helper)
.withMapper(this::update)
.withTable(simpleTable)
.withValueSetter((record, dsl) ->
dsl.set(id).equalToWhenPresent(record::getId)
.set(firstName).equalToWhenPresent(record::getFirstName)
.set(lastName).equalToWhenPresent(record::getLastName)
.set(birthDate).equalToWhenPresent(record::getBirthDate)
.set(employed).equalToWhenPresent(record::getEmployed)
.set(occupation).equalToWhenPresent(record::getOccupation))
.build();
}

default int updateByPrimaryKey(SimpleTableRecord record) {
return UpdateDSL.updateWithMapper(this::update, simpleTable)
.set(firstName).equalTo(record::getFirstName)
Expand Down
Loading