驼峰命名?Java系统开发从入门到精通第三讲(文字版)驼峰命名法规范,驼峰命名法和帕斯卡命名法

下来我们进入数据持久化的部分,对于一个真实的业务系统,能够正常的运转离不开数据的持久化。在数据持久化这块,目前主流的还是关系型数据库(RDBMS),NoSQL(NewSQL)也有了长足发展,特别在大数据领域。JDBC数据持久化这块,javaEE推出了JDBC规范,基于JDBC规范,只要不同的数据库支持对应协议,业务系统就能和数据库服务器(MySQL、Oracle、DB2等)交互

JPAJPA(Java Persistence API)用于对象持久化的 API,是 Java EE 5.0 平台标准的 ORM 规范,使得应用程序以统一的方式访问持久层。Hibernate 是符合 JPA 规范的,而 MyBatis 却不符合,因为 MyBatis 还是需要写 SQL 的

MyBatisMyBatis是一个不屏蔽SQL且提供动态SQL、接口式编程和简易SQL绑定POJO的半自动化框架,它的使用十分简单,而且能非常容易定制SQL,以提高网站性能,因此在移动互联网兴起的时代,它占据了强势的地位。MyBatis的基本概念:数据库表对应的java对象(POJO)、Mapper(映射器,一些绑定映射语句的接口)、映射语句(XML和注解两种方式,过去XML方式更为流行)、Mybatis配置
  • 数据表结构
CREATE TABLE `tz_user` ( `user_id` varchar(36) NOT NULL DEFAULT '' COMMENT 'ID', `nick_name` varchar(50) DEFAULT NULL COMMENT '用户昵称', `real_name` varchar(50) DEFAULT NULL COMMENT '真实姓名', `user_mail` varchar(100) DEFAULT NULL COMMENT '用户邮箱', `login_password` varchar(255) DEFAULT NULL COMMENT '登录密码', `pay_password` varchar(50) DEFAULT NULL COMMENT '支付密码', `user_mobile` varchar(50) DEFAULT NULL COMMENT '手机号码', `modify_time` datetime NOT NULL COMMENT '修改时间', `user_regtime` datetime NOT NULL COMMENT '注册时间', `user_regip` varchar(50) DEFAULT NULL COMMENT '注册IP', `user_lasttime` datetime DEFAULT NULL COMMENT '最后登录时间', `user_lastip` varchar(50) DEFAULT NULL COMMENT '最后登录IP', `user_memo` varchar(500) DEFAULT NULL COMMENT '备注', `sex` char(1) DEFAULT 'M' COMMENT 'M(男) or F(女)', `birth_date` char(10) DEFAULT NULL COMMENT '例如:2009-11-27', `pic` varchar(255) DEFAULT NULL COMMENT '头像图片路径', `status` int(1) NOT NULL DEFAULT '1' COMMENT '状态 1 正常 0 无效', `score` int(11) DEFAULT NULL COMMENT '用户积分', PRIMARY KEY (`user_id`), UNIQUE KEY `ud_user_mail` (`user_mail`), UNIQUE KEY `ud_user_unique_mobile` (`user_mobile`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';
  • 实体类(示例)
@Data public class User implements Serializable { private String userId;//id private String realName;//用户名 private String loginPassword;//密码 }这是实体对象,和数据表字段一一对应(并且属性名称和数据表字段名称存在规则映射,例如:user_id 为 userId)这里也体现了”约定“的威力,基于约定很多事情处理都变得异常简单
  • Mapper XML
<?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="com.easycloud.daomall.show.dao.UserMapper"> <resultMap id="userMap" type="User"> <id property="userId" column="user_id"></id> <result property="realName" column="real_name" /> <result property="loginPassword" column="login_password" /> </resultMap> <select id="findAll" resultMap="userMap"> SELECT * FROM tz_user </select> </mapper> 这是Mybatis中的核心:因为SQL命名规范(多以”_“连接)和java(多以驼峰)命名规范不一致,所以通过resultMap标签来做java属性和数据表字段的对应关系;关于映射,Mybatis提供了三种处理方式:1、如上代码所示,手动指定(麻烦);2、SQL语句设置别名(稍显麻烦),例如:SELECT user_id as userId, real_name as realName3、设置开启驼峰命名map-underscore-to-camel-case: true(基于“约定”的处理);select标签中的resultMap属性,描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素,它和resultMap标签中的id属性保持一致;sql标签,可被其它语句引用的可重用语句块; insert标签,映射插入语句; update标签,映射更新语句; delete标签,映射删除语句; select标签,映射查询语句;对应SQL的CRUD
  • Mapper接口
@Mapper public interface UserMapper { public List<User> findAll(); }
  • MyBatis配置
  • 使用Spring Boot,Mybatis配置非常简单
  • #mybatis的相关配置
    mybatis:
    #mapper配置文件
    mapper-locations: classpath:mapper/*.xml
    type-aliases-package: com.easycloud.daomall.show.model
    #开启驼峰命名
    configuration:
    map-underscore-to-camel-case: true
  • 其中type-aliases-package指定实体类所在的包,这样在设置”type、parameterType、resultType“属性值时可只用类名。
  • api暴露
然后按照前面讲的Spring RESTful service暴露,就可以查看访问数据库的效果了

MyBatis-Plushttps://baomidou.com在实际的业务编写中,你会发现要写大量的CRUD Mapper XML和对应的接口定义,但其实对于数据表的操作基本可以抽象为CRUD(包括分页和高级检索)这几种类型,MyBatis-Plus就应运而生。使用MyBatis-Plus后,我们看看可以省略哪些代码:
  • application.yml中的MyBatis配置
  • Mapper XML文件
  • Mapper java接口中的方法定义,然后继承baseMapper
  • public interface UserMapper extends baseMapper<User> {
  • 内置方法说明参见:https://baomidou.com/pages/49cc81/
  • 调用Mapper的地方改为selectList(null)
  • 实体类名和数据表名不存在规则一致性的话,需要加上TableName注解(例如我们的代码示例)
  • @Data
    @TableName("tz_user")
    public class User implements Serializable {
  • MyBatis-Plus处处体现了”约定优于配置“的原则
分页实现分页插件,在实际的业务中,分页是一个常见的场景,使用MyBatis-Plus分页,需要启用分分页插件@Configuration public class MyBatisConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }分页代码IPage<User> page = new Page<User>(start, rows); return userMapper.selectPage(page,null).getRecords();其中Page对象,第一个参数表示是第几页,第二个参数表示每页有几条数据条件构造https://baomidou.com/pages/10c804/MyBatis-Plus中使用Wrapper实现,支持查询、更新的where条件。使用Lambda 表达式更加的简洁。QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.lambda().eq(User::getUserId, "111");上面就是查询userId为111的用户其它特性作为一个可扩展的设计,数据表ID不应该使用数据库自增ID(例如:分库分表就会出现ID重复问题),所以MyBatis-Plus提供了ID生成的增强
  • 注解使用ID生成策略
@TableId() private String userId;不做任何设置,使用其默认内置的雪花算法它还支持其他几种模式,非必要使用默认方式足矣ASSIGN_ID(雪花算法) 如果不设置类型值,默认则使用IdType.ASSIGN_ID策略(自3.3.0起)。该策略会使用雪花算法自动生成主键ID,主键类型为长或字符串(分别对应的MySQL的表字段为BIGINT和VARCHAR)ASSIGN_UUID(排除中划线的UUID) 如果使用IdType.ASSIGN_UUID策略,并重新自动生成排除中划线的UUID作为主键。主键类型为String,对应MySQL的表分段为VARCHAR(32)AUTO(数据库ID自增)INPUT(插入前自行设置主键值)无(无状态) 如果使用IdType.NONE策略,表示未设置主键类型(注解里等于跟随上下,左右里约等于INPUT)策略全局设置mybatis-plus.global-config.db-config.id-type=值
  • 调用
User user = new User(); user.setUserRegtime(LocalDateTime.now()); user.setModifyTime(LocalDateTime.now()); userService.save(user);其他前置知识JavaLambda我们知道java8是一个大改动的版本,也让java的能力有了更进一步的提升,并且很多新特性应用广泛,Lambda表达式就是其中之一,在MyBatis章节我们就有使用Lambda表达式,第一感觉就是书写更加的方便,非常的强大。下来我们就对Lambda表达式做一定的了解。Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑。Lambda 表达式的语法格式如下:(parameters) -> expression 或 (parameters) ->{ statements; }Lambda 表达式的简单例子:// 1. 不需要参数,返回值为 5 () -> 5 // 2. 接收一个参数(数字类型),返回其2倍的值 x -> 2 * x // 3. 接受2个参数(数字),并返回他们的差值 (x, y) -> x – y // 4. 接收2个int型整数,返回他们的和 (int x, int y) -> x + y // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void) (String s) -> System.out.print(s)在 LambdaTester.java 文件输入以下代码:package com.easycloud.javacase.lambda; public class LambdaShow { public static void main(String args[]){ LambdaShow tester = new LambdaShow(); // 类型声明 MathOperation addition = (int a, int b) -> a + b; // 不用类型声明 MathOperation subtraction = (a, b) -> a - b; // 大括号中的返回语句 MathOperation multiplication = (int a, int b) -> { return a * b; }; // 没有大括号及返回语句 MathOperation division = (int a, int b) -> a / b; System.out.println("10 + 5 = " + tester.operate(10, 5, addition)); System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction)); System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication)); System.out.println("10 / 5 = " + tester.operate(10, 5, division)); // 不用括号 GreetingService greetService1 = message -> System.out.println("Hello " + message); // 用括号 GreetingService greetService2 = (message) -> System.out.println("Hello " + message); greetService1.sayMessage("Runoob"); greetService2.sayMessage("Google"); } interface MathOperation { int operation(int a, int b); } interface GreetingService { void sayMessage(String message); } private int operate(int a, int b, MathOperation mathOperation){ return mathOperation.operation(a, b); } } 使用 Lambda 表达式需要注意以下两点:
  • Lambda 表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口。在上面例子中,我们使用各种类型的Lambda表达式来定义MathOperation接口的方法。然后我们定义了sayMessage的执行。
  • Lambda 表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力。
我们来看一下,引入Lambda表达式对以前以前繁琐写法的改进,例如常见的排序算法:java8以前:// 使用 java 7 排序 private void sortUsingJava7(List<String> names){ Collections.sort(names, new Comparator<String>() { @Override public int compare(String s1, String s2) { return s1.compareTo(s2); } }); }java8的Lambda:// 使用 java 8 排序 private void sortUsingJava8(List<String> names){ Collections.sort(names, (s1, s2) -> s1.compareTo(s2)); }再例如(多线程编程):java8以前:Runnable r2 = new Runnable(){ public void run(){ System.out.println("Hello World 2"); } }; //执行Runnable方法 public static void process(Runnable r){ r.run(); } //打印 "Hello World 1" process(r1); //打印 "Hello World 2" process(r2);java8的Lambda:Runnable r1 = () -> System.out.println("Hello World 1"); Runnable r2 = () -> System.out.println("Hello World 2");另外我们在Mybatis的QueryWrapper中使用了”方法引用“,用一对冒号::代表方法引用,使语言调用更加紧凑简洁,减少冗余代码。 queryWrapper.lambda().eq(User::getUserId, "111")和Lambda配合使用的场景很多,上面演示的接口sayMessage()和Runnable接口,都是函数式接口(Functional Interface)函数式接口函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 lambda 表达式。Lambda 表达式和方法引用(实际上也可认为是Lambda表达式)上。JDK 1.8 之前已有的函数式接口:
  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.security.PrivilegedAction
  • java.util.Comparator
  • java.io.FileFilter
  • java.nio.file.PathMatcher
  • java.lang.reflect.InvocationHandler
  • java.beans.PropertyChangeListener
  • java.awt.event.ActionListener
  • javax.swing.event.ChangeListener
JDK 1.8 新增加的函数接口:
  • java.util.function
我们再来看一个具体的示例:Predicate <T> 接口是一个函数式接口,它接受一个输入参数 T,返回一个布尔值结果。该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非)。该接口用于测试对象是 true 或 false。 import java.util.Arrays; import java.util.List; import java.util.function.Predicate; public class Java8Tester { public static void main(String args[]){ List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); // Predicate<Integer> predicate = n -> true // n 是一个参数传递到 Predicate 接口的 test 方法 // n 如果存在则 test 方法返回 true System.out.println("输出所有数据:"); // 传递参数 n eval(list, n->true); // Predicate<Integer> predicate1 = n -> n%2 == 0 // n 是一个参数传递到 Predicate 接口的 test 方法 // 如果 n%2 为 0 test 方法返回 true System.out.println("输出所有偶数:"); eval(list, n-> n%2 == 0 ); // Predicate<Integer> predicate2 = n -> n > 3 // n 是一个参数传递到 Predicate 接口的 test 方法 // 如果 n 大于 3 test 方法返回 true System.out.println("输出大于 3 的所有数字:"); eval(list, n-> n > 3 ); } public static void eval(List<Integer> list, Predicate<Integer> predicate) { for(Integer n: list) { if(predicate.test(n)) { System.out.println(n + " "); } } } }

本文经授权 由答答网发布,转载联系作者并注明出处:http://www.dadazzz.com:6443/sh/show-86161.html

如对文章、图片、字体等版权有疑问,请联系我们。

相关推荐

企业微信
运营大叔公众号