最新文章


springboot2.1整合JPA与mybatis
JPA与mybatis作为持久层框架各有各的优点,比如mybatis的灵活易用,JPA可以少写SQL,方便开发者快速开发。 springboot整合JPA与mybatis现在以查询一张学生表为例,用来验证springboot整合JPA与mybatis的整合结果。学生表如下:1、maven依赖<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId></dependency><!-- mysql链接工具 --><dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId></dependency><!-- mybatis --><dependency>    <groupId>org.mybatis.spring.boot</groupId>    <artifactId>mybatis-spring-boot-starter</artifactId>    <version>2.1.0</version></dependency><!-- jpa --><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!--thymeleaf模板引擎 --><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-devtools</artifactId>    <scope>runtime</scope>    <optional>true</optional></dependency><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-test</artifactId>    <scope>test</scope></dependency>2、学生实体类package work.chenchuan.study.mybatisjpa.po;import javax.persistence.*;@Entity@Table(name = "student_test")public class StudentPo {    /**     * 学生编号     */    @Id    @GeneratedValue(strategy = GenerationType.AUTO)    private Integer studentId;    /**     * 学生姓名     */    private String studentName;    /**     * 年龄     */    private String age;    @Override    public String toString() {        return "StudentPo{" +                "studentId=" + studentId +                ", studentName='" + studentName + '\'' +                ", age='" + age + '\'' +                '}';    }    public Integer getStudentId() {        return studentId;    }    public void setStudentId(Integer studentId) {        this.studentId = studentId;    }    public String getStudentName() {        return studentName;    }    public void setStudentName(String studentName) {        this.studentName = studentName;    }    public String getAge() {        return age;    }    public void setAge(String age) {        this.age = age;    }}3、yml配置spring:  datasource:    driver-class-name: com.mysql.cj.jdbc.Driver    url: jdbc:mysql://127.0.0.1/test?characterEncodeing=utf-8&serverTimezone=GMT%2b8    username: root    password: 123  jpa:    show-sql: true #显示执行sqlmybatis:  mapper-locations: classpath:mybatis/**/*.xml #mapper文件存放路径4、整合并验证mybatis1)、创建mapper接口StudentMapper@Repository@Mapperpublic interface StudentMapper {    /**     * 查询所有学生     *     * @return     */    List<StudentPo> findAllStudent();}2)、根据yml配置文件创建在对应路径下创建mapper文件<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.2//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="work.chenchuan.study.mybatisjpa.dao.mapper.StudentMapper">    <!-- 查询所有学生 -->    <select id="findAllStudent" resultType="work.chenchuan.study.mybatisjpa.po.StudentPo">        SELECT          student_id    AS studentId,          student_name  AS studentName,          age           AS age        FROM student_test    </select></mapper>3)、测试@RunWith(SpringRunner.class)@SpringBootTestpublic class SpringbootStudyApplicationTests {    @Autowired    private StudentMapper studentMapper;        @Test    public void findAllStudent() {        System.out.println(studentMapper.findAllStudent());    }}打印结果如下,mybatis整合成功:[StudentPo{studentId=1, studentName='jack', age='12'}, StudentPo{studentId=2, studentName='tom', age='10'}]5、整合并验证JPA1)、创建jpa接口public interface StudentJpaDao extends JpaRepository<StudentPo, Integer> {}2)、测试@RunWith(SpringRunner.class)@SpringBootTestpublic class SpringbootStudyApplicationTests {    @Autowired    private StudentJpaDao studentJpaDao;    @Test    public void findOneStudent() {        System.out.println(studentJpaDao.findById(1));    }}打印结果如下,JPA整合成功:[StudentPo{studentId=1, studentName='jack', age='12'}] 总结本次是将JPA与mybatis同时整合在一个项目里的,需要注意对于同一个实体,JPA的接口与mybatis的接口要分开单独创建才能同时使用,不然会抛异常。
Sep 11, 2019 1:37:00 PM
29
1
springboot2.x文件下载
springboot集成了springMvc,所以springboot的文件上传与springMvc的文件上传方式基本相同。项目构建项目依赖<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId></dependency><!--thymeleaf模板引擎 --><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-devtools</artifactId>    <scope>runtime</scope>    <optional>true</optional></dependency><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-test</artifactId>    <scope>test</scope></dependency> yml配置文件spring:  thymeleaf:    cache: false  servlet:    multipart:      max-file-size: 1MB #文件上传单文件限制大小      max-request-size: 10MB #文件上传一次请求总大小file:  upload_path: D:\F\img\upload-test\ #文件上传目标目录单文件上传上传HTML单个文件上传:<form action="/file/uploadOneFile" method="post" enctype="multipart/form-data">    <input type="file" name="file"/>    <input type="submit" value="上传"/></form> 上传Controller//文件上传路径@Value("${file.upload_path}")private String uploadPath; /** * 当文件上传页面 * * @return */@GetMapping("/oneFilePage")public String oneFilePage() {    return "/file/oneFilePage";}/** * 单文件上传 * * @param file * @return */@PostMapping("/uploadOneFile")@ResponseBodypublic String uploadOneFile(MultipartFile file) {    //判断是否提交文件    if (file.getSize() == 0) {        return "请选择上传文件";    }    File uploadPathObj = new File(uploadPath);    //判断上传目录是否存在    if (!uploadPathObj.exists()) {        uploadPathObj.mkdirs();    }    //获取文件名    String originalFilename = file.getOriginalFilename();    //上传文件全路径名称    String filePathName = uploadPath + originalFilename;    //上传文件对象    File uploadFileObj = new File(filePathName);    try {        //上传文件        file.transferTo(uploadFileObj);    } catch (IOException e) {        e.printStackTrace();        return "上传失败";    }    return "上传成功";} 选择文件后点击“上传”按钮上传文件,上传成功的提示: 多文件上传上传HTML多个文件上传:<form action="/file/uploadFiles" method="post" enctype="multipart/form-data">    文件1 : <input type="file" name="files"/><br/>    文件2 : <input type="file" name="files"/><br/>    <!--文件3 : <input type="file" name="files"/><br/>-->    <input type="submit" value="上传"/></form> 上传Controller//文件上传路径@Value("${file.upload_path}")private String uploadPath; /** * 多文件上传页面 * * @return */@GetMapping("/manyFilePage")public String manyFilePage() {    return "/file/manyFilePage";}/** * 多文件上传 * * @param files * @return */@PostMapping("/uploadFiles")@ResponseBodypublic String uploadFiles(MultipartFile[] files) {    //判断是否提交文件    if (files == null || files.length == 0) {        return "请选择上传文件";    }    File uploadPathObj = new File(uploadPath);    //判断上传目录是否存在    if (!uploadPathObj.exists()) {        uploadPathObj.mkdirs();    }    //遍历上文件传    for (MultipartFile file : files) {        //获取文件名        String originalFilename = file.getOriginalFilename();        //上传文件全路径名称        String filePathName = uploadPath + originalFilename;        //上传文件对象        File uploadFileObj = new File(filePathName);        try {            //上传文件            file.transferTo(uploadFileObj);        } catch (IOException e) {            e.printStackTrace();            return "上传失败";        }    }    return "上传成功";} 选择文件后点击“上传”按钮上传文件,上传成功的提示: 单文件下载下载HTML模拟文件下载:<form action="/file/downloadFile" method="GET">    下载文件:<input type="text" name="file" value="D:\F\img\upload-test\微信截图_20190826143608.png" readonly/><br>    <input type="submit" value="下载"/></form> 下载Controller/** * 单文件下载 * * @param response * @param file * @return */@GetMapping("/downloadFile")@ResponseBodypublic String downloadFile(HttpServletResponse response, String file) {    if (file == null) {        return "不存在的文件";    }    //下载文件对象    File downloadFileObj = new File(file);    //文件名    String fileName = downloadFileObj.getName();    //获取字节输出流    try {        OutputStream outputStream = response.getOutputStream();        // 自动判断下载文件类型        response.setContentType("multipart/form-data");        //相应编码        response.setCharacterEncoding("utf-8");        // 设置文件名称        response.setHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes("gbk"), "iso8859-1"));        //写入输入流        outputStream.write(FileCopyUtils.copyToByteArray(downloadFileObj));        //刷新柳        outputStream.flush();        //关闭流        outputStream.close();    } catch (IOException e) {        e.printStackTrace();        return "下载失败";    }    return "下载成功";}点击“下载”按钮便可以下载对应路径的文件。
Aug 29, 2019 6:37:48 PM
64
2
JSOUP爬虫
jsoup是一款Java的HTML解析器,主要用来对HTML解析。参考文档:https://jsoup.org/https://www.open-open.com/jsoup/ 虽然jsoup支持从某个地址直接去爬取网页源码,但是只支持HTTP,HTTPS协议,支持不够丰富。所以,主要还是用来对HTML进行解析,从HTML中抽取自己想要的数据。 利用jsoup爬取汇博网java职位列表数据1、maven依赖<dependencies>    <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->    <dependency>        <groupId>org.jsoup</groupId>        <artifactId>jsoup</artifactId>        <version>1.12.1</version>    </dependency></dependencies> 2、编码获取java职位列表package work.chenchuan.crawler.jsoup;import org.jsoup.Connection;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class DataFromHuibo {    public static void main(String[] args) {        //职位列表        List<Map<String, Object>> list = new ArrayList<>();        //获取所有职位列表        list = getAllData(1, list);        for (Map<String, Object> cur : list) {            System.out.print(cur.get("companyName"));            System.out.print("     ");            System.out.print(cur.get("name"));            System.out.print("     ");            System.out.print(cur.get("money"));            System.out.print("     ");            System.out.print(cur.get("address"));            System.out.print("     ");            System.out.print(cur.get("exp"));            System.out.print("     ");            System.out.print(cur.get("detaiUrl"));            System.out.print("\n");        }    }    /**     * 获取java职位每页所有列表数据     *     * @param p    当前页码     * @param list 职位列表     * @return     */    public static List<Map<String, Object>> getAllData(int p, List<Map<String, Object>> list) {        //创建并返回URL的连接        Connection connection = Jsoup.connect("https://www.huibo.com/jobsearch/?params=p" + p + "&key=java");        Document document = null;        try {            //获取html文档            document = connection.get();            //获取列表dom节点            Elements elements = document.select("#job_list_table .postIntro");            //遍历节点获取数据并添加职位列表到list            for (Element element : elements) {                String companyName = element.select("div.title>a").attr("title");                Elements infoDoms = element.select(".postIntroList .postIntroL");                for (Element infoDom : infoDoms) {                    String name = infoDom.select(".des_title").text();                    String money = infoDom.select(".money").text();                    String address = infoDom.select(".address").text();                    String exp = infoDom.select(".exp").text();                    String detaiUrl = infoDom.select(".name>a").attr("abs:href");                    Map<String, Object> curInfo = new HashMap<>();                    curInfo.put("companyName", companyName);                    curInfo.put("name", name);                    curInfo.put("money", money);                    curInfo.put("address", address);                    curInfo.put("exp", exp);                    curInfo.put("detaiUrl", detaiUrl);                    list.add(curInfo);                }            }            //当前页公司条数            int curPageSize = elements.size();            //每页职位条数和公司条数不同,当前页公司条数>0查找下一页职位            if (curPageSize > 0) {                p++;                getAllData(p, list);            }        } catch (IOException e) {            e.printStackTrace();        }        return list;    }    /**     * 获取java职位列表首页数据     */    public static void getData() {        //创建并返回URL的连接        Connection connection = Jsoup.connect("https://www.huibo.com/jobsearch/?params=p1&key=java×tamp=1566277536#list");        //获取html文档        Document document = null;        try {            document = connection.get();            //获取列表dom节点            Elements elements = document.select(".postIntroList .clearfix");            //遍历节点获取数据            for (Element element : elements) {                //获取节点相关属性                String name = element.select(".des_title").text();                String money = element.select(".money").text();                String address = element.select(".address").text();                String exp = element.select(".exp").text();                System.out.print(name);                System.out.print("     ");                System.out.print(money);                System.out.print("     ");                System.out.print(address);                System.out.print("     ");                System.out.print(exp);                System.out.print("\n");            }        } catch (IOException e) {            e.printStackTrace();        }    }} 以上程序打印结果如下: 
Aug 21, 2019 2:02:32 PM
45
1
JAVA——lambda表达式
lambda表达式是java8的新特性。为什么使用LambdaLambda是一个可传递的代码块,可以在以后传递一次或多次。Lambda可是对一个接口进行快速实现。使用lambda表达式实现接口注意接口必须是一个函数式接口(只有一个抽象方法需要实现的接口)。设计自己的lambda函数式接口可以在接口上加注解@FunctionInterface。lambda基本语法():写参数列表。->:goes to参数方法连接符。{}:写方法体。简单的例子:1、先定义接口@FunctionalInterfacepublic interface LambdaBase {    int add(int a, int b);}2、测试代码public class LambdaBaseTest {    public static void main(String[] args) {        //lambda表达式        LambdaBase lambdaBase = (a, b) -> {            return a + b;        };        //输出结果        System.out.println(lambdaBase.add(10, 20));    }}3、输出结果为30。lambda语法简化1、准备接口@FunctionalInterfacepublic interface LambdaBase {    int add(int a, int b);}@FunctionalInterfacepublic interface LambdaOneParamNoReturn {    void test(String a);}2、测试代码public class JianHua {    public static void main(String[] args) {        //1、参数只有一个可省略小括号        LambdaOneParamNoReturn lambdaOneParamNoReturn = a -> {            System.out.println("输出" + a);        };        lambdaOneParamNoReturn.test("apple");        //2、如果方法体只有一句,可以省略大括号        LambdaOneParamNoReturn lambdaOneParamNoReturn1 = a -> System.out.println("输出" + a);        lambdaOneParamNoReturn1.test("abc");        //3、如果方法体的唯一一句是返回语句,在省略大括号的同时要省略return关键字        LambdaBase lambdaBase = (a, b) -> a + b;        System.out.println(lambdaBase.add(1, 2));    }}方法引用lambda方法引用是lambda指向的是一个具体的方法。语法:方法隶属者::方法名。(方法隶属者是对象名或类名)。注意:方法的参数列表、返回值必须与接口完全一样。示例如下1、接口@FunctionalInterfacepublic interface LambdaBase {    int add(int a, int b);}2、测试public class FangFaYinYong {    public static void main(String[] args) {        LambdaBase lambdaBase = FangFaYinYong::add;        System.out.println(lambdaBase.add(1, 2));    }    public static int add(int a, int b) {        return a + b;    }}输出结果3。构造器引用语法:构造的对象::new示例:1、对象public class Student {    private String name;    private Integer age;    public Student() {        System.out.println("无参构造器执行了");    }    public Student(String name, Integer age) {        this.name = name;        this.age = age;        System.out.println("有参构造器执行了");    }} 2、接口/** * 无参数接口 */@FunctionalInterfacepublic interface StudentNoParamConstruct {    Student getStudent();}/** * 有参接口 */@FunctionalInterfacepublic interface StudentHaveParamConstruct {    Student getStudent(String name, int age);}3、测试public class ConstructorTest {    public static void main(String[] args) {        //无参构造器引用        StudentNoParamConstruct studentNoParamConstruct = Student::new;        studentNoParamConstruct.getStudent();        //有参构造器引用        StudentHaveParamConstruct studentHaveParamConstruct = Student::new;        studentHaveParamConstruct.getStudent("jack", 20);    }}打印结果:无参构造器执行了有参构造器执行了forEach遍历集合语法:集合.forEach(lambda表达式)。示例public static void main(String[] args) {    List<Integer> list = new ArrayList<>();    Collections.addAll(list, 1, 2, 3, 4, 5, 6);    //打印集合元素    list.forEach(System.out::println);    //处理集合元素(输出大于5的元素)    list.forEach(ele -> {        if (ele > 5) {            System.out.println(ele);        }    });}removeIf作用:删除集合中符合条件的元素。示例public static void main(String[] args) {    List<Integer> list = new ArrayList<>();    Collections.addAll(list, 1, 2, 3, 4, 5, 6);    //删除奇数    list.removeIf(elt -> elt % 2 != 0);    System.out.println(list);}打印结果:[2, 4, 6]线程实现示例public static void main(String[] args) {    //用lambda实例化线程    java.lang.Thread thread = new java.lang.Thread(() -> {        for (int i = 0; i < 10; i++) {            System.out.println(i);        }    });    thread.start();}java常用函数式接口java常用函数式接口参考:https://www.runoob.com/java/java8-functional-interfaces.html闭包闭包会提升包围变量的生命周期(在方法结束后变量不会销毁)。在使用lambda表达式时,在闭包中引用的变量一定是常量,举例说明:public static void main(String[] args) {    int a = 5;    Consumer<Integer> consumer = elt ->        System.out.println(a++); //a++编译出错:Variable used in lambda expression should be final or effectively final    consumer.accept(1);}原因:只要在闭包中使用了某个局部变量值,就会将这个局部变量用final修饰,变量值不可更改。像上面这个例子变量a在编译时会以final int a = 5来编译。
Apr 27, 2019 8:13:50 PM
182
1
JAVA——对象数组排序
Comparable接口Arrays类中的sort方法会对对象数组进行排序,但前提是对象所属的类必须实现了Comparable接口。例:使用Comparable接口对学生对象数组排序(按学生年龄排序)public class ComparableStudent {    public static void main(String[] args) {        //构造三个学生对象放入数组        Student student1 = new Student("小明",12);        Student student2 = new Student("小红",11);        Student student3 = new Student("小刚",14);        Student[] students = {student1,student2,student3};        System.out.println("排序前:\n" + Arrays.toString(students));        //排序        Arrays.sort(students);        System.out.println("排序后:\n" + Arrays.toString(students));    }}class Student implements Comparable<Student> {    private String name;    private Integer age;    public Student(String name, Integer age) {        this.name = name;        this.age = age;    }    @Override    public String toString() {        return "Student{" +                "name='" + name + '\'' +                ", age=" + age +                '}';    }    @Override    public int compareTo(Student o) {        return Integer.compare(age, o.age);    }}打印结果:排序前:[Student{name='小明', age=12}, Student{name='小红', age=11}, Student{name='小刚', age=14}]排序后:[Student{name='小红', age=11}, Student{name='小明', age=12}, Student{name='小刚', age=14}]Comparator接口Arrays.sort()还有第二种用法,就是一个数组和比较器作为参数,比较器必须实现Comparator接口。例:使用Comparator接口对学生对象数组排序(按学生年龄排序)public class ComparatorStudent {    public static void main(String[] args) {        //构造三个学生对象放入数组        Student1 student1 = new Student1("小明", 12);        Student1 student2 = new Student1("小红", 11);        Student1 student3 = new Student1("小刚", 14);        Student1[] students = {student1, student2, student3};        System.out.println("排序前:\n" + Arrays.toString(students));        //排序        Arrays.sort(students, new AgeComparator());        System.out.println("排序后:\n" + Arrays.toString(students));    }}/** * 学生类 */class Student1 {    private String name;    private Integer age;    public Student1(String name, Integer age) {        this.name = name;        this.age = age;    }    @Override    public String toString() {        return "Student1{" +                "name='" + name + '\'' +                ", age=" + age +                '}';    }    public String getName() {        return name;    }    public Integer getAge() {        return age;    }}/** * 比较器 */class AgeComparator implements Comparator<Student1> {    @Override    public int compare(Student1 o1, Student1 o2) {        return o1.getAge() - o2.getAge();    }}打印结果:排序前:[Student1{name='小明', age=12}, Student1{name='小红', age=11}, Student1{name='小刚', age=14}]排序后:[Student1{name='小红', age=11}, Student1{name='小明', age=12}, Student1{name='小刚', age=14}]lambda表达式java8的lambda表达式可以简单快速地实现用比较器的方式对对象数组排序。例:使用lambda表达式接口对学生对象数组排序(按学生年龄排序)public class LambdaStudent {    public static void main(String[] args) {        //构造三个学生对象放入数组        Student2 student1 = new Student2("小明", 12);        Student2 student2 = new Student2("小红", 11);        Student2 student3 = new Student2("小刚", 14);        Student2[] students = {student1, student2, student3};        System.out.println("排序前:\n" + Arrays.toString(students));        //排序        Arrays.sort(students, (s1, s2) -> s1.getAge() - s2.getAge());        System.out.println("排序后:\n" + Arrays.toString(students));    }}class Student2 {    private String name;    private Integer age;    public Student2(String name, Integer age) {        this.name = name;        this.age = age;    }    @Override    public String toString() {        return "Student2{" +                "name='" + name + '\'' +                ", age=" + age +                '}';    }    public String getName() {        return name;    }    public Integer getAge() {        return age;    }}打印结果:排序前:[Student1{name='小明', age=12}, Student1{name='小红', age=11}, Student1{name='小刚', age=14}]排序后:[Student1{name='小红', age=11}, Student1{name='小明', age=12}, Student1{name='小刚', age=14}]
Apr 1, 2019 9:10:46 PM
189
1
个人名片

  欢迎来到“浩瀚星尘”的个人博客!
  首先,该博客用于分享本人的生活事迹与兴趣爱好; 此外,该博客的主要作用便是与广大的小伙伴一起分享探讨开发技术, 希望大家多多关照。

网名: 浩瀚星尘
城市: 重庆
工作: java