本文向大家介紹對JDBC簡單的封裝,自定義mini-mapper趁蕊,希望以此加深大家對此技術(shù)的理解宵距。
一、JDBC簡介
? ? ? JDBC(Java DataBase Connectivity,java數(shù)據(jù)庫連接)是一種用于執(zhí)行SQL語句的Java API鹿蜀,可以為多種關(guān)系數(shù)據(jù)庫提供統(tǒng)一訪問箕慧,它由一組用Java語言編寫的類和接口組成。JDBC提供了一種基準(zhǔn)茴恰,據(jù)此可以構(gòu)建更高級的工具和接口颠焦,使數(shù)據(jù)庫開發(fā)人員能夠編寫數(shù)據(jù)庫應(yīng)用程序。
? ? ? Java 具有堅固往枣、安全伐庭、易于使用、易于理解和可從網(wǎng)絡(luò)上自動下載等特性婉商,是編寫數(shù)據(jù)庫應(yīng)用程序的杰出語言似忧。所需要的只是 Java應(yīng)用程序與各種不同數(shù)據(jù)庫之間進行對話的方法渣叛。
? ? 數(shù)據(jù)庫是實現(xiàn)持久化的一種途徑丈秩,而JDBC則是通向數(shù)據(jù)庫的橋梁。
二淳衙、環(huán)境準(zhǔn)備
1蘑秽、引入maven依賴
<dependency>
? <groupId>mysql</groupId>
? <artifactId>mysql-connector-java</artifactId>
? <version>${mysql-connector.version}</version>
? <scope>runtime</scope>
</dependency>
<!-- 引入lombok,去除冗余代碼 -->
<dependency>
? <groupId>org.projectlombok</groupId>
? <artifactId>lombok</artifactId>
? <version>${lombok.version}</version>
? <scope>provided</scope>
</dependency>
<dependency>
? <groupId>junit</groupId>
? <artifactId>junit</artifactId>
? <version>4.12</version>
? <scope>test</scope>
</dependency>
2箫攀、引入配置文件jdbc.properties
jdbc.driveClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mini_mapper?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&verifyServerCertificate=false&useSSL=false&useAffectedRows=true&zeroDateTimeBehavior=convertToNull
jdbc.username=root
jdbc.password=pf1234
3肠牲、新建測試數(shù)據(jù)表
CREATE TABLE `t_user` (
? `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
? `name` varchar(255) DEFAULT '' COMMENT '姓名',
? `age` tinyint(3) unsigned DEFAULT '0' COMMENT '年齡',
? `birthday` date DEFAULT NULL COMMENT '生日',
? PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
三、封裝MiniJdbcTemplate
? ? ? MiniJdbcTemplate提供對數(shù)據(jù)庫表的增刪改查操作
1靴跛、定義JdbcUtil
? ? ? 獲取數(shù)據(jù)庫鏈接缀雳,關(guān)閉數(shù)據(jù)庫鏈接,放在JdbcUtil里維護
public final class JdbcUtil {
? ? /**
? ? * 數(shù)據(jù)庫鏈接
? ? */
? ? private static String url = null;
? ? /**
? ? * 用戶名
? ? */
? ? private static String username = null;
? ? /**
? ? * 密碼
? ? */
? ? private static String password = null;
? ? static {
? ? ? ? try (
? ? ? ? ? ? InputStream inputStream = JdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties")
? ? ? ? ) {
? ? ? ? ? ? Properties properties = new Properties();
? ? ? ? ? ? properties.load(inputStream);
? ? ? ? ? ? String driveClassName = properties.getProperty("jdbc.driveClassName");
? ? ? ? ? ? Class.forName(driveClassName);
? ? ? ? ? ? url = properties.getProperty("jdbc.url");
? ? ? ? ? ? username = properties.getProperty("jdbc.username");
? ? ? ? ? ? password = properties.getProperty("jdbc.password");
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? throw new RuntimeException("加載驅(qū)動異常", e);
? ? ? ? }
? ? }
? ? private JdbcUtil() {
? ? }
? ? /**
? ? * 獲取數(shù)據(jù)庫鏈接
? ? */
? ? public static Connection getConnection() throws SQLException {
? ? ? ? return DriverManager.getConnection(url, username, password);
? ? }
? ? /**
? ? * 關(guān)閉鏈接
? ? */
? ? public static void close(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) throws SQLException {
? ? ? ? if (resultSet != null) {
? ? ? ? ? ? resultSet.close();
? ? ? ? }
? ? ? ? if (preparedStatement != null) {
? ? ? ? ? ? preparedStatement.close();
? ? ? ? }
? ? ? ? if (connection != null) {
? ? ? ? ? ? connection.close();
? ? ? ? }
? ? }
}
2梢睛、定義常量
public interface Constant {
? ? String COMMA = ",";
? ? String UNDERSCORE = "_";
? ? char CHAR_UNDERSCORE = '_';
? ? String ASTERISK = "*";
? ? String SPACE = " ";
? ? String QUESTION_MARK = "?";
? ? String EQ = "=";
? ? String LEFT_BRACKET = "(";
? ? String RIGHT_BRACKET = ")";
}
3肥印、定義數(shù)據(jù)轉(zhuǎn)換策略接口
@FunctionalInterface
public interface RowMapper<T> {
? ? /**
? ? * 將結(jié)果集轉(zhuǎn)為指定的Bean
? ? */
? ? T mapRow(ResultSet rs) throws SQLException;
}
4、基于策略查詢集合
? ? /**
? ? * 基于策略查詢集合
? ? */
? ? public static <T> List<T> queryForList(String sql, List<Object> params, RowMapper<T> rowMapper) throws SQLException {
? ? ? ? //獲取鏈接
? ? ? ? Connection conn = JdbcUtil.getConnection();
? ? ? ? //獲取執(zhí)行平臺
? ? ? ? PreparedStatement preparedStatement = getPreparedStatement(sql, params, conn);
? ? ? ? //獲取結(jié)果集
? ? ? ? ResultSet rs = preparedStatement.executeQuery();
? ? ? ? List<T> list = new ArrayList<T>();
? ? ? ? while (rs.next()) {
? ? ? ? ? ? //將結(jié)果集轉(zhuǎn)為指定的Bean
? ? ? ? ? ? T bean = rowMapper.mapRow(rs);
? ? ? ? ? ? list.add(bean);
? ? ? ? }
? ? ? ? //釋放鏈接
? ? ? ? JdbcUtil.close(conn, preparedStatement, rs);
? ? ? ? return list;
? ? }
Junit測試
@Test
? ? public void testQueryRowMapper() throws SQLException {
? ? ? ? String sql = "select * from t_user where id = ?";
? ? ? ? List<Object> params = Collections.singletonList(1);
? ? ? ? List<User> list = MiniJdbcTemplate.queryForList(sql, params, rs -> {
? ? ? ? ? ? User user = new User();
? ? ? ? ? ? user.setId(rs.getInt("id"));
? ? ? ? ? ? user.setName(rs.getString("name"));
? ? ? ? ? ? user.setAge(rs.getInt("age"));
? ? ? ? ? ? user.setBirthday(rs.getDate("birthday"));
? ? ? ? ? ? return user;
? ? ? ? });
? ? ? ? System.out.println(list);
? ? }
結(jié)果: [User(id=1, name=張三, age=19, birthday=2003-05-02)]
5绝葡、基于反射查詢集合
? /**
? ? * 基于反射查詢集合
? ? */
? ? public static <T> List<T> queryForList(String sql, List<Object> params, Class<T> tClass) throws Exception {
? ? ? ? //獲取鏈接
? ? ? ? Connection conn = JdbcUtil.getConnection();
? ? ? ? //獲取執(zhí)行平臺
? ? ? ? PreparedStatement preparedStatement = getPreparedStatement(sql, params, conn);
? ? ? ? //獲取結(jié)果集
? ? ? ? ResultSet rs = preparedStatement.executeQuery();
? ? ? ? List<T> list = new ArrayList<T>();
? ? ? ? while (rs.next()) {
? ? ? ? ? ? T bean = tClass.newInstance();
? ? ? ? ? ? ResultSetMetaData metaData = rs.getMetaData();
? ? ? ? ? ? int columnCount = metaData.getColumnCount();
? ? ? ? ? ? for (int i = 0; i < columnCount; i++) {
? ? ? ? ? ? ? ? //獲取列名
? ? ? ? ? ? ? ? String columnName = metaData.getColumnName(i + 1);
? ? ? ? ? ? ? ? //獲取屬性名
? ? ? ? ? ? ? ? String fieldName = CommonUtil.getFieldName(columnName);
? ? ? ? ? ? ? ? Field field = tClass.getDeclaredField(fieldName);
? ? ? ? ? ? ? ? Object value;
? ? ? ? ? ? ? ? //mysql依賴包不支持傳入date類型解析
? ? ? ? ? ? ? ? if (field.getType().equals(Date.class)) {
? ? ? ? ? ? ? ? ? ? value = rs.getDate(columnName);
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? value = rs.getObject(columnName, field.getType());
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? field.setAccessible(true);
? ? ? ? ? ? ? ? field.set(bean, value);
? ? ? ? ? ? }
? ? ? ? ? ? list.add(bean);
? ? ? ? }
? ? ? ? JdbcUtil.close(conn, preparedStatement, rs);
? ? ? ? return list;
? ? }
Junit測試
@Test
? ? public void testQuery() throws Exception {
? ? ? ? String sql = "select * from t_user where id = ?";
? ? ? ? List<Object> params = Collections.singletonList(1);
? ? ? ? List<User> list = MiniJdbcTemplate.queryForList(sql, params, User.class);
? ? ? ? System.out.println(list);
? ? }
結(jié)果: [User(id=1, name=張三, age=19, birthday=2003-05-02)]
6深碱、增刪改方法
? /**
? ? * 增刪改操作
? ? */
? ? public static int update(String sql, List<Object> params) throws SQLException {
? ? ? ? //獲取鏈接
? ? ? ? Connection conn = JdbcUtil.getConnection();
? ? ? ? //獲取執(zhí)行平臺
? ? ? ? PreparedStatement preparedStatement = getPreparedStatement(sql, params, conn);
? ? ? ? //執(zhí)行更新(增刪改)
? ? ? ? int row = preparedStatement.executeUpdate();
? ? ? ? //釋放鏈接
? ? ? ? JdbcUtil.close(conn, preparedStatement, null);
? ? ? ? return row;
? ? }
Junit測試
@Test
? ? public void insert() throws SQLException {
? ? ? ? String sql = "insert into t_user(name,age,birthday) values(?,?,?)";
? ? ? ? List<Object> params = Arrays.asList("李四", 0, new Date());
? ? ? ? int row = MiniJdbcTemplate.update(sql, params);
? ? ? ? System.out.println(row);
? ? }
結(jié)果: 1
四、定義LambdaQueryWrapper
? ? ? 仿照maybatis-plus藏畅,通過Lambda表達式獲取數(shù)據(jù)庫字段敷硅,LambdaQueryWrapper職責(zé)是構(gòu)建篩選條件
1、定義支持序列化的Function
@FunctionalInterface
public interface ConditionFunction<T, R> extends Function<T, R>, Serializable {
}
2愉阎、定義Lambda解析工具類
public final class LambdaUtils {
? ? private static final Pattern GET_PATTERN = Pattern.compile("^get[a-zA-Z].*");
? ? private LambdaUtils() {
? ? }
? ? /**
? ? * 獲取字段名
? ? */
? ? public static <T> String fnToColumnName(ConditionFunction<T, ?> fn) {
? ? ? ? try {
? ? ? ? ? ? Method method = fn.getClass().getDeclaredMethod("writeReplace");
? ? ? ? ? ? method.setAccessible(Boolean.TRUE);
? ? ? ? ? ? SerializedLambda serializedLambda = (SerializedLambda) method.invoke(fn);
? ? ? ? ? ? String methodName = serializedLambda.getImplMethodName();
? ? ? ? ? ? if (GET_PATTERN.matcher(methodName).find()) {
? ? ? ? ? ? ? ? methodName = methodName.substring(3);
? ? ? ? ? ? }
? ? ? ? ? ? return CommonUtil.getColumnName(methodName);
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? throw new RuntimeException("獲取屬性名異常", e);
? ? ? ? }
? ? }
}
3绞蹦、定義相關(guān)條件model
/**
* 共享查詢字段
*/
@Data
public class SharedString implements Serializable {
? ? private static final long serialVersionUID = -8841176360027140318L;
? ? private String stringValue;
}
/**
* 查詢的條件參數(shù)
*/
@Builder
@Data
public class SqlParam implements Serializable {
? ? private static final long serialVersionUID = 3693478483795808202L;
? ? /**
? ? * 數(shù)據(jù)庫字段
? ? */
? ? private String columnName;
? /**
? ? * 屬性值
? ? */
? ? private Object value;
? ? /**
? ? * 數(shù)據(jù)庫關(guān)鍵字
? ? */
? ? private String sqlKeyword;
}
4、LambdaQueryWrapper
? ? ? LambdaQueryWrapper目前就提供如下幾種查詢條件的構(gòu)建榜旦,特別復(fù)雜的就不寫了
public class LambdaQueryWrapper<T> {
? ? private static final String LIKE = "LIKE";
? ? private static final String NOT_LIKE = "NOT LIKE";
? ? private static final String EQ = "=";
? ? private static final String IN = "IN";
? ? private static final String NOT_IN = "NOT IN";
? ? private static final String GT = ">";
? ? private static final String LT = "<";
? ? /**
? ? * 查詢字段
? ? */
? ? private SharedString sqlSelect = new SharedString();
? ? /**
? ? * 條件參數(shù)
? ? */
? ? private List<SqlParam> sqlParamList = new ArrayList<>();
? ? public LambdaQueryWrapper<T> eq(ConditionFunction<T, ?> fn, Object value) {
? ? ? ? addCondition(fn, value, EQ);
? ? ? ? return this;
? ? }
? ? public LambdaQueryWrapper<T> like(ConditionFunction<T, ?> fn, Object value) {
? ? ? ? addCondition(fn, value, LIKE);
? ? ? ? return this;
? ? }
? ? public LambdaQueryWrapper<T> notLike(ConditionFunction<T, ?> fn, Object value) {
? ? ? ? addCondition(fn, value, NOT_LIKE);
? ? ? ? return this;
? ? }
? ? public LambdaQueryWrapper<T> in(ConditionFunction<T, ?> fn, Object... values) {
? ? ? ? addCondition(fn, Arrays.asList(values), IN);
? ? ? ? return this;
? ? }
? ? public LambdaQueryWrapper<T> notIn(ConditionFunction<T, ?> fn, Object... values) {
? ? ? ? addCondition(fn, Arrays.asList(values), NOT_IN);
? ? ? ? return this;
? ? }
? ? public LambdaQueryWrapper<T> gt(ConditionFunction<T, ?> fn, Object value) {
? ? ? ? addCondition(fn, value, GT);
? ? ? ? return this;
? ? }
? ? public LambdaQueryWrapper<T> lt(ConditionFunction<T, ?> fn, Object value) {
? ? ? ? addCondition(fn, value, LT);
? ? ? ? return this;
? ? }
? ? public LambdaQueryWrapper<T> select(ConditionFunction<T, ?>... fns) {
? ? ? ? if (!CommonUtil.isEmpty(fns)) {
? ? ? ? ? ? String stringValue = Arrays.stream(fns).map(LambdaUtils::fnToColumnName).collect(Collectors.joining(Constant.COMMA));
? ? ? ? ? ? sqlSelect.setStringValue(stringValue);
? ? ? ? }
? ? ? ? return this;
? ? }
? ? /**
? ? * 添加條件
? ? */
? ? private void addCondition(ConditionFunction<T, ?> fn, Object value, String sqlKeyword) {
? ? ? ? SqlParam sqlParam = SqlParam.builder()
? ? ? ? ? ? ? ? .columnName(LambdaUtils.fnToColumnName(fn))
? ? ? ? ? ? ? ? .value(value)
? ? ? ? ? ? ? ? .sqlKeyword(sqlKeyword)
? ? ? ? ? ? ? ? .build();
? ? ? ? sqlParamList.add(sqlParam);
? ? }
? ? public String getSqlSelect() {
? ? ? ? return CommonUtil.isBank(sqlSelect.getStringValue()) ? Constant.ASTERISK : sqlSelect.getStringValue();
? ? }
? ? public List<SqlParam> getSqlParamList() {
? ? ? ? return sqlParamList;
? ? }
}
五幽七、定義AbstractBaseMapper
? ? 有了上面的鋪墊,最后就是組裝sql了章办,AbstractBaseMapper職責(zé)是通過LambdaQueryWrapper來組裝sql和參數(shù)列表锉走,傳遞給MiniJdbcTemplate
1.定義TableName
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {
? ? String value();
}
2滨彻、AbstractBaseMapper
public abstract class AbstractBaseMapper<T> {
? ? private static final String INSERT_SQL = "INSERT INTO %s(%s) values(%s)";
? ? private static final String UPDATE_SQL = "UPDATE %s SET ";
? ? private static final String QUERY_SQL = "SELECT %s FROM %s";
? ? private static final String AND = "AND";
? ? private static final String WHERE = "WHERE";
? ? private Class<T> beanClass;
? ? private String tableName;
? ? public AbstractBaseMapper() {
? ? ? ? //獲取泛型的class
? ? ? ? beanClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
? ? ? ? //獲取表名
? ? ? ? tableName = beanClass.getAnnotation(TableName.class).value();
? ? }
? ? /**
? ? * 新增
? ? */
? ? public int insertSelective(T bean) throws IllegalAccessException, SQLException {
? ? ? ? List<Object> params = new ArrayList<>();
? ? ? ? List<String> columns = new ArrayList<>();
? ? ? ? List<String> values = new ArrayList<>();
? ? ? ? Field[] fields = beanClass.getDeclaredFields();
? ? ? ? for (Field field : fields) {
? ? ? ? ? ? field.setAccessible(Boolean.TRUE);
? ? ? ? ? ? Object value = field.get(bean);
? ? ? ? ? ? if (value == null) {
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? }
? ? ? ? ? ? params.add(value);
? ? ? ? ? ? columns.add(CommonUtil.getColumnName(field.getName()));
? ? ? ? ? ? values.add(Constant.QUESTION_MARK);
? ? ? ? }
? ? ? ? String sql = String.format(INSERT_SQL, tableName, String.join(Constant.COMMA, columns), String.join(Constant.COMMA, values));
? ? ? ? return MiniJdbcTemplate.update(sql, params);
? ? }
? ? /**
? ? * 修改
? ? */
? ? public int updateSelective(T bean, LambdaQueryWrapper<T> wrapper) throws IllegalAccessException, SQLException {
? ? ? ? List<Object> params = new ArrayList<>();
? ? ? ? List<String> setParams = new ArrayList<>();
? ? ? ? Field[] fields = beanClass.getDeclaredFields();
? ? ? ? for (Field field : fields) {
? ? ? ? ? ? field.setAccessible(Boolean.TRUE);
? ? ? ? ? ? Object value = field.get(bean);
? ? ? ? ? ? if (value == null) {
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? }
? ? ? ? ? ? params.add(value);
? ? ? ? ? ? setParams.add(CommonUtil.getColumnName(field.getName()) + Constant.EQ + Constant.QUESTION_MARK);
? ? ? ? }
? ? ? ? StringBuilder condition = new StringBuilder();
? ? ? ? handleSqlParam(wrapper, condition, params);
? ? ? ? String sql = String.format(UPDATE_SQL, tableName) + String.join(Constant.COMMA, setParams) +
? ? ? ? ? ? ? ? condition.toString();
? ? ? ? return MiniJdbcTemplate.update(sql, params);
? ? }
? ? /**
? ? * 查詢
? ? */
? ? public List<T> list(LambdaQueryWrapper<T> wrapper) throws Exception {
? ? ? ? List<Object> params = new ArrayList<>();
? ? ? ? StringBuilder condition = new StringBuilder();
? ? ? ? handleSqlParam(wrapper, condition, params);
? ? ? ? String sql = String.format(QUERY_SQL, wrapper.getSqlSelect(), tableName) + condition.toString();
? ? ? ? return MiniJdbcTemplate.queryForList(sql, params, beanClass);
? ? }
? ? /**
? ? * 處理條件
? ? */
? ? private void handleSqlParam(LambdaQueryWrapper<T> wrapper, StringBuilder condition, List<Object> params) {
? ? ? ? List<SqlParam> sqlParamList = wrapper.getSqlParamList();
? ? ? ? if (CommonUtil.isNotEmpty(sqlParamList)) {
? ? ? ? ? ? condition.append(Constant.SPACE).append(WHERE).append(Constant.SPACE);
? ? ? ? ? ? for (int i = 0; i < sqlParamList.size(); i++) {
? ? ? ? ? ? ? ? SqlParam sqlParam = sqlParamList.get(i);
? ? ? ? ? ? ? ? if (i > 0) {
? ? ? ? ? ? ? ? ? ? condition.append(Constant.SPACE).append(AND).append(Constant.SPACE);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? StringBuilder value = new StringBuilder();
? ? ? ? ? ? ? ? Object paramValue = sqlParam.getValue();
? ? ? ? ? ? ? ? if (paramValue instanceof List) {
? ? ? ? ? ? ? ? ? ? value.append(Constant.LEFT_BRACKET);
? ? ? ? ? ? ? ? ? ? List<Object> valueList = (List<Object>) paramValue;
? ? ? ? ? ? ? ? ? ? for (int j = 0; j < valueList.size(); j++) {
? ? ? ? ? ? ? ? ? ? ? ? Object obj = valueList.get(j);
? ? ? ? ? ? ? ? ? ? ? ? params.add(obj);
? ? ? ? ? ? ? ? ? ? ? ? if (j > 0) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? value.append(Constant.COMMA);
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? value.append(Constant.QUESTION_MARK);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? value.append(Constant.RIGHT_BRACKET);
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? value.append(Constant.QUESTION_MARK);
? ? ? ? ? ? ? ? ? ? params.add(paramValue);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? condition.append(sqlParam.getColumnName()).append(Constant.SPACE).append(sqlParam.getSqlKeyword()).append(Constant.SPACE).append(value.toString());
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
3、Junit測試
@TableName("t_user")
@Data
public class User {
? ? /**
? ? * 主鍵
? ? */
? ? private Integer id;
? ? /**
? ? * 姓名
? ? */
? ? private String name;
? ? /**
? ? * 年齡
? ? */
? ? private Integer age;
? ? /**
? ? * 生日
? ? */
? ? private Date birthday;
}
public class UserMapper extends AbstractBaseMapper<User> {
}
測試insertSelective
@Test
? ? public void insertTest() throws SQLException, IllegalAccessException {
? ? ? ? UserMapper userMapper = new UserMapper();
? ? ? ? User user = new User();
? ? ? ? user.setName("王五");
? ? ? ? user.setAge(0);
? ? ? ? user.setBirthday(new Date());
? ? ? ? int row = userMapper.insertSelective(user);
? ? ? ? System.out.println(row);
? ? }
結(jié)果: 1
測試updateSelective
@Test
? ? public void updateTest() throws SQLException, IllegalAccessException {
? ? ? ? UserMapper userMapper = new UserMapper();
? ? ? ? User user = new User();
? ? ? ? user.setAge(12);
? ? ? ? int row = userMapper.updateSelective(user, new LambdaQueryWrapper<User>().eq(User::getId, 3));
? ? ? ? System.out.println(row);
? ? }
結(jié)果: 1
測試查詢
@Test
? ? public void queryTest() throws Exception {
? ? ? ? UserMapper userMapper = new UserMapper();
? ? ? ? List<User> userList = userMapper.list(new LambdaQueryWrapper<User>()
? ? ? ? ? ? ? ? .select(User::getId, User::getName, User::getAge)
? ? ? ? ? ? ? ? .in(User::getId, 3, 4)
? ? ? ? ? ? ? ? .gt(User::getAge,1)
? ? ? ? ? ? ? ? .eq(User::getName, "王五"));
? ? ? ? System.out.println(userList);
? ? }
結(jié)果: [User(id=3, name=王五, age=12, birthday=null)]
六挪蹭、總結(jié)
? ? ? 大家在實際開發(fā)中還是使用業(yè)界成熟的框架亭饵,不要自己手動實現(xiàn),mini-mapper只是實現(xiàn)了一些最基本的功能梁厉,代碼實現(xiàn)還存在瑕疵辜羊,目的是加深技術(shù)的理解,起一個拋磚引玉的作用词顾。