Jhipster

1.简介

JHipster或者称Java Hipster,是一个应用代码产生器,能够创建Spring Boot + AngularJS的应用。开源项目地址:JHipster/Github。

JHipster使用Node.js和Yeoman产生Java应用代码,使用Maven(Gradle)运行产生的代码,产生代码有如下关键特征:

  • src/main/java 目录有Spring Boot 配置类在config包中,
  • JHipster使用Spring的Java 配置,没有XML配置。
  • JPA实体或MongoDB文档类是在domain包. JPA实体使用缓存和auto-generated 主键配置. 如果你使用JHipster产生你的JPA实体, 可以创建1:N和N:N关系。
  • 在repostiory包中是Spring Data 仓储.
  • 可选,你有通常@Service-beans 在服务层. 这些服务通常是配置为事务的 安全的业务对象。
  • REST 端点存在web.rest 包中, 支持Spring MVC的REST
  • JHipster也产生 Liquibase 改变日志文件,用来处理数据库更新,增加一个实体将创建特定的schema更新,这将会版本化,当应用重启时可被执行。
  • 集成Spring的 Test 上下文测试支持.
  • JHipster 创建完整可用的Angular 前端,使用CRUD来管理你产生的实体。

2.技术简介

####客户端技术栈

  • 单页面Web应用:
    • 响应式页面设计
    • HTML5 Boilerplate
    • Responsive Web Design with Twitter Bootstrap
    • Angular 4 or AngularJS v1.x
    • 兼容 IE11+ 和其他现代浏览器
    • 完整的国际化支持,基于 Angular Translate
    • 可选 Sass 用于 CSS 设计
    • 可选 Spring Websocket 来实现 WebSocket
  • 强大的 Yeoman 开发工作流:
    • 使用 Yarn or Bower 可以轻松的安装 JavaScript 类库
    • 使用 Webpack or Gulp.js 构建, 优化项目, 支持 live reload
    • 使用 Karma, Headless Chrome and Protractor进行测试
      那么,如果单页面应用不能满足你的需求呢?
    • 支持 Thymeleaf 模板引擎, 用于在服务端渲染页面

####服务端技术栈

  • 一个完整的 Spring 应用:
    • Spring Boot 用于简化应用配置
    • Maven 或者 Gradle 用于构建,测试和运行应用
    • “development” 和 “production” 配置文件 (支持 Maven 和 Gradle)
    • Spring Security
    • Spring MVC REST + Jackson
    • 可选的 WebSocket 支持 – 基于 Spring Websocket
    • Spring Data JPA + Bean 验证
    • 使用 Liquibase 实现数据库自动更新
    • Elasticsearch 支持对数据库的搜索功能
    • 支持像MongoDB 这样的 document-oriented NoSQL 数据库
    • 支持像Cassandra 这样的 column-oriented NoSQL 数据库
  • 支持生产环境:
    • Monitoring with Metrics 监控运行状态
    • 支持 ehcache (本地缓存) 或者 hazelcast (分布式缓存)
    • 可选的 HTTP session 集群 – 基于 hazelcast
    • 优化的静态资源(gzip filter, HTTP cache headers)
    • 日志管理 Logback, 可在运行时配置
    • HikariCP 连接池,用于性能优化
    • 可以将应用构建成一个标准的 WAR 文件或者一个可执行的 JAR 文件
    • Full Docker and Docker Compose support

3.其他

##需要安装的环境

  • JDK8+
  • Maven或者Gradle
  • NodeJS
  • MySQL
  • GIT
  • IDE

构建方式

使用yarn命令进行安装
安装 Yeoman: yarn global add yo@1.8.5
安装 JHipster: yarn global add generator-jhipster

Java面试题

什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?

Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java虚拟机执行的字节码文件。
Java被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独重写或者是重新编译。Java虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特性。

JDK和JRE的区别是什么?

Java运行时环境(JRE)。它包括Java虚拟机、Java核心类库和支持文件。它不包含开发工具(JDK)–编译器、调试器和其他工具。
Java开发工具包(JDK)是完整的Java软件开发包,包含了JRE,编译器和其他的工具(比如:JavaDoc,Java调试器),可以让开发者开发、编译、执行Java应用程序。

”static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?

“static”关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。
Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。
java中也不可以覆盖private的方法,因为private修饰的变量和方法只能在当前类中使用,如果是其他的类继承当前类是不能访问到private变量或方法的,当然也不能覆盖。

是否可以在static环境中访问非static变量?

static变量在Java中是属于类的,它在所有的实例中的值是一样的。当类被Java虚拟机载入的时候,会对static变量进行初始化。如果你的代码尝试不用实例来访问非static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。

Java支持的数据类型有哪些?什么是自动拆装箱?

Java语言支持的8种基本数据类型是:
byte
short
int
long
float
double
boolean
char
自动装箱是Java编译器在基本数据类型和对应的对象包装类型之间做的一个转化。比如:把int转化成Integer,double转化成Double,等等。反之就是自动拆箱。

Java支持的数据类型包括两种:一种是基本数据类型,包含byte,char,short, boolean ,int , long, float,double;另一种是引用类型:如String等,其实是对象的引用,JVM中虚拟栈中存的是对象的地址,创建的对象实质在堆中,通过地址来找到堆中的对象的过程,即为引用类型。自动装箱就是Java编译器在基本数据类型和对应的对象包装类型间的转化,即int转化为Integer,自动拆箱是Integer调用其方法将其转化为int的过程

Java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思?

Java中的方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。与此相对,方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。覆盖者可能不会限制它所覆盖的方法的访问。

Java中,什么是构造方法?什么是构造方法重载?什么是复制构造方法?

当新对象被创建的时候,构造方法会被调用。每一个类都有构造方法。在程序员没有给类提供构造方法的情况下,Java编译器会为这个类创建一个默认的构造方法。
Java中构造方法重载和方法重载很相似。可以为一个类创建多个构造方法。每一个构造方法必须有它自己唯一的参数列表。
Java不支持像C++中那样的复制构造方法,这个不同点是因为如果你不自己写构造方法的情况下,Java不会创建默认的复制构造方法。

Java支持多继承么?

Java中类不支持多继承,只支持单继承(即一个类只有一个父类)。 但是java中的接口支持多继承,,即一个子接口可以有多个父接口。(接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能,当类实现接口时,类就扩展了相应的功能)。

接口和抽象类的区别是什么?

Java提供和支持创建抽象类和接口。它们的实现有共同点,不同点在于:
接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
类可以实现很多个接口,但是只能继承一个抽象类
类可以不实现抽象类和接口声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
抽象类可以在不提供接口方法实现的情况下实现接口。
Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量。
Java接口中的成员函数默认是public的。抽象类的成员函数可以是private,protected或者是public。
接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包含main方法的话是可以被调用的。
也可以参考JDK8中抽象类和接口的区别。

什么是值传递和引用传递?

值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量.
引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。
一般认为,java内的传递都是值传递. java中实例对象的传递是引用传递

进程和线程的区别是什么?

进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程。线程又叫做轻量级进程。
线程的划分小于进程,线程隶属于某个进程。 进程是程序的一种动态形式,是CPU、内存等资源占用的基本单位,而线程是不能占有这些资源的。 进程之间相互独立,通信比较困难,而线程之间共享一块内存区域,通信比较方便。 进程在执行的过程中,包含比较固定的入口,执行顺序,出口,而线程的这些过程会被应用程序所控制。

创建线程有几种不同的方式?你喜欢哪一种?为什么?

有4种方式可以用来创建线程:
继承Thread类
实现Runnable接口
应用程序可以使用Executor框架来创建线程池
实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。
还有一种方式是实现Callable接口

概括的解释下线程的几种可用状态。
  1. 新建( new ):新创建了一个线程对象。
  2. 可运行( runnable ):线程对象创建后,其他线程(比如 main 线程)调用了该对象 的 start ()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取 cpu 的使用权 。
  3. 运行( running ):可运行状态( runnable )的线程获得了 cpu 时间片( timeslice ) ,执行程序代码。
  4. 阻塞( block ):阻塞状态是指线程因为某种原因放弃了 cpu 使用权,也即让出了 cpu timeslice ,暂时停止运行。直到线程进入可运行( runnable )状态,才有 机会再次获得 cpu timeslice 转到运行( running )状态。阻塞的情况分三种:
    (一). 等待阻塞:运行( running )的线程执行 o . wait ()方法, JVM 会把该线程放 入等待队列( waitting queue )中。
    (二). 同步阻塞:运行( running )的线程在获取对象的同步锁时,若该同步锁 被别的线程占用,则 JVM 会把该线程放入锁池( lock pool )中。
    (三). 其他阻塞: 运行( running )的线程执行 Thread . sleep ( long ms )或 t . join ()方法,或者发出了 I / O 请求时, JVM 会把该线程置为阻塞状态。 当 sleep ()状态超时、 join ()等待线程终止或者超时、或者 I / O 处理完毕时,线程重新转入可运行( runnable )状态。
  5. 死亡( dead ):线程 run ()、 main () 方法执行结束,或者因异常退出了 run ()方法,则该线程结束生命周期。死亡的线程不可再次复生。
同步方法和同步代码块的区别是什么?

区别:
同步方法默认用this或者当前类class对象作为锁;
同步代码块可以选择以什么来加锁,比同步方法要更细颗粒度,我们可以选择只同步会发生同步问题的部分代码而不是整个方法;
同步方法使用关键字 synchronized修饰方法,而同步代码块主要是修饰需要进行同步的代码,用 synchronized(object){代码内容}进行修饰;

在监视器(Monitor)内部,是如何做线程同步的?程序应该做哪种级别的同步?

监视器和锁在Java虚拟机中是一块使用的。监视器监视一块同步代码块,确保一次只有一个线程执行同步代码块。每一个监视器都和一个对象引用相关联。线程在获取锁之前不允许执行同步代码。

什么是死锁(deadlock)?

所谓死锁是指多个进 程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。死锁产生的4个必要条件:
互斥条件:进程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某 资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放)。
请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
循环等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被 链中下一个进程所请求。

如何确保N个线程可以访问N个资源同时又不导致死锁?

使用多线程的时候,一种非常简单的避免死锁的方式就是:指定获取锁的顺序,并强制线程按照指定的顺序获取锁。因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。

Java集合类框架的基本接口有哪些?

集合类接口指定了一组叫做元素的对象。集合类接口的每一种具体的实现类都可以选择以它自己的方式对元素进行保存和排序。有的集合类允许重复的键,有些不允许。
Java集合类提供了一套设计良好的支持对一组对象进行操作的接口和类。Java集合类里面最基本的接口有:
Collection:代表一组对象,每一个对象都是它的子元素。
Set:不包含重复元素的Collection。
List:有顺序的collection,并且可以包含重复元素。
Map:可以把键(key)映射到值(value)的对象,键不能重复。

阿里巴巴校招

开放式问题

  • 1、请介绍一项你最热爱、最擅长的专业领域,并且介绍你在这个领域的学习经历和未来的学习规划。
    Please introduce to us the academic field that you like most and are best at. Please include your past experience and future plan in this area.

  • 2、请介绍你参与的印象最深刻的一个项目,为什么?并且介绍你在项目中的角色和发挥的作用。
    Please tell us the most impressive project you participated in the past, and why? Please include your role during the project in detail.

  • 3、你最期望在阿里巴巴工作(或实习)的部门或项目是什么?请介绍下你对该部门的了解和希望加入的原因。
    Which department or project do you prefer most?Please tell us what you know about this department or project and why you want to be a part of this department or project.

学校项目整理

恒丰人才库管理系统(企业内部项目)

  • 简介:
    系统采用B/S三层架构设计思想,根据集团需要,对该系统进行开发,实现了通知公告、在职人员管理、离职人员管理、培训管理、多条件查找及综合查询、图表展示等功能,采用图表的形式对人员进行汇总,形成表格,配合扇形图、折线图来更加直观的展示了公司人员的情况。采用数据字段的形式来对所有下拉框进行动态管理,并且可以随时导出最新的hta文件来采集有关人员的信息。
  • 开发周期:2016/05-2016/07
  • 责任描述:参与需求调研、系统设计、数据库设计、代码编写、程序调试、项目上线。
  • 服务器部署地址:恒丰集团人才库管理系统,测试用用户名:admin,密码:admin

柳州市党外代表人士信息管理系统(政府内部系统)

  • 简介:系统采用MVC开发模式、B/S三层架构,综合运用SSH以及Ajax技术,以Java为开发工具、MySQL为数据库管理系统,采用了DWZ前台框架,加入了Ztree、Echarts、kindeditor等插件,界面友好,操作方便。该系统对全市各领域的党外代表人士、各级别的党外干部、各层次的党外人大代表和党外政协委员的各类信息进行全面收集、综合分析、归类入档、定期更新,形成分类分层人才库,可以使统战部门全面、有效地管理复杂繁琐的人员信息,实时跟踪人员变动,节省工作时间,大幅提高管理效能和服务质量,从而投入更多的精力致力于战略规划和催动其战略目标的实现。由于DWZ框架样式集成度高,集成其他插件导致了不兼容等情况,深究DWZ的源码和其他组件的源码使其达到了较好的兼容。同时实现了必填项设置,下拉菜单形成数据字典,避免了因为小改动而改动源码的麻烦。
  • 开发周期:2016/07-2016/08
  • 责任描述:参与需求调研、系统设计、数据库设计、代码编写、程序调试、项目上线。
  • 服务器部署地址:柳州市党外代表人士信息管理系统,测试用用户名:admin,密码:admin888

恒丰集团经营指标管理系统(企业内部项目)

  • 简介:系统遵循MVC设计思想,以SSH为基础框架、jQuery等其他技术手段,按照“智能查询、分类汇总、综合分析”的建设要求,来实现总公司对全国27家分公司的效益指标管理。针对多表映射关系,系统采用Hibernate这一对象关系映射框架进行多表关系映射,进而通过表格和Echarts图形插件及表格展示了各个分公司的数据。其中所有指标均可动态添加,动态修改,充分体现了系统的通用性。为了阅读的方便性,自己通过js和jqury代码实现了table同时固定行和列,滚动时只有数据滚动,提高了指标数据的可读性。
  • 责任描述:后期功能添加、服务器维护。

基于 Spring MVC+Spring+Mybatis+Apache Shiro的后台管理系统(练习项目)

  • 简介:系统采用Spring MVC开发,集成Apache Shiro实现精确到按钮的权限控制,采用Maven架构,使用IDEA开发,前端采用基于Bootstrap的H-UI。拥有角色管理、组织机构管理、权限管理、菜单管理、用户管理等功能。系统模块化开发,可作为脚手架进行后续系统开发。
  • 开发周期:2017/01-2017/03
  • 责任描述:参与系统设计、数据库设计、代码编写、程序调试、服务器部署。
  • Github开源地址:lmy_admin
  • 服务器部署地址:后台管理系统,测试用用户名:admin,密码:admin

约学约行APP开发(参赛项目)

  • 简介:系统采用新型技术架构,利用最新H5技术+安卓WebView快速开发完成,服务端和后台采用Java主流框架 Spring+Spring MVC+Mybatis整合开发,数据库采用MySql进行数据存储。
  • 主要功能介绍:安卓、微信、Web端同步更新。微信端通过对微信公众号进行二次服务端开发Web端采用H5+Zepto进行开发。使用了高德地图的API进行附近信息展示。集成阿里百川即时通讯服务,方便预约前用户之间交流,保证预约质量。学生可绑定学校教务系统账号,获取学生课程信息,通过上课地点和上课时间、时长进行学生上课签到、平时成绩统计和约束学生学习功能。引入云之迅手机验证平台,注册、找回密码均采用手机验证。引入七牛云存储,存储用户图片信息,保障图片数据安全。引入图灵机器人API,在微信端可直接发送消息与其进行聊天,也可以在后台配置其微信回复内容。软件后台使用SSM主流开发框架。后台集成Apache Shiro实现精确到按钮的权限管理,并且拥有完善的组织机构和灵活的角色管理,基于阿里Druid连接池的数据分析,可以直接通过后台配置微信、图灵、云之迅等接口信息,方便平台接口更换。后台前端采用基于Bootstrap的H-UI,增加后台管理人员的使用体验。
  • 开发周期:2017/05-2017/06
  • 责任描述:参与系统设计、数据库设计、代码编写、程序调试、服务器部署。
  • 服务器部署地址:后台地址,测试用户名:admin,密码admin手机端地址,测试用户名:17853481294,密码123456
  • 微信端二维码:simple_learn_wechat

德州经信工作交流群微信开发(政府内部项目)

  • 简介:系统后端主要采用Spring MVC+Spring+Mybatis,前端使用weui进行开发,托管微信服务端到本地服务器,拦截微信发送的事件和信息进行相应的处理。并且对权限不完整的订阅号进行功能扩展。系统主要功能是通知公告列表,管理员可以发布通知公告,并且可以对公告进行无限次的循环叠加评论,普通用户只能查看到自己的评论内容。
  • 开发周期:2017/05-2017/06
  • 责任描述:参与需求调研、系统设计、数据库设计、代码编写、程序调试、项目上线。
  • 服务器部署地址:接口
  • 微信端二维码:qrcode_for_gh_56499b6b7fe3_258

德州学院教学工作量管理系统(学校内部)

  • 简介:系统采用Spring MVC开发,Mybatis进行数据操作,使用Apache Shiro进行单角色的权限控制,前台使用了layui前端框架和DataTables等组件。系统采用Excel的模式,对教学工作量进行导入导出和后台信息的统计。
  • 开发周期:2017/05-2017/06
  • 责任描述:参与需求调研、系统设计、数据库设计、代码编写、程序调试、项目上线。
  • 服务器部署地址:教学工作量管理系统测试用户名:admin,密码admin

一本日记(安卓练习性项目)

  • 简介:本软件安卓端采用Google Material Design设计风格,Android Studio作为开发工具,集成okhttp、easy permission、CompactCalendarViewToolbar、BGAPhotoPicker-Android、Glide等开源组件。后台采用PHP语言使用TinkPHP框架进行开发,数据之间的交互使用JSON进行数据传输。
  • 主要功能描述:(1)注册登录。用户进行注册登录,注销登录。(2)日记管理。用户对日记的添加、删除、编辑、查看,图片上传。(3)个人信息修改。用户修改昵称,个人简介,修改密码。(4)分类管理。分类添加,分类删除,分类查看。
  • 开发周期:2017/06-2017/07
  • 责任描述:参与系统设计、数据库设计、安卓端代码编写、程序调试、服务器部署。
  • Github开源地址:一本日记
  • APP下载地址:一本日记APP

Java利用Zxing生成二维码

Maven 依赖

1
2
3
4
5
<dependency>  
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>2.0</version>
</dependency>

二维码的生成

  • 利用Maven将Zxing-core.jar 包加入到项目中。
  • 二维码的生成需要借助MatrixToImageWriter类,该类是由Google提供的,可以将该类拷贝到源码中,这里我将该类的源码贴上,可以直接使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import com.google.zxing.common.BitMatrix;  
import javax.imageio.ImageIO;
import java.io.File;
import java.io.OutputStream;
import java.io.IOException;
import java.awt.image.BufferedImage;


public final class MatrixToImageWriter {

private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;

private MatrixToImageWriter() {}


public static BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
}
}
return image;
}


public static void writeToFile(BitMatrix matrix, String format, File file)
throws IOException {
BufferedImage image = toBufferedImage(matrix);
if (!ImageIO.write(image, format, file)) {
throw new IOException("Could not write an image of format " + format + " to " + file);
}
}


public static void writeToStream(BitMatrix matrix, String format, OutputStream stream)
throws IOException {
BufferedImage image = toBufferedImage(matrix);
if (!ImageIO.write(image, format, stream)) {
throw new IOException("Could not write an image of format " + format);
}
}

}

编写生成二维码的实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
try {  

String content = "http://www.baidu.com";
String path = "C:/Users/Administrator/Desktop/testImage";

MultiFormatWriter multiFormatWriter = new MultiFormatWriter();

Map hints = new HashMap();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 400, 400,hints);
File file1 = new File(path,"测试打开百度.jpg");
MatrixToImageWriter.writeToFile(bitMatrix, "jpg", file1);

} catch (Exception e) {
e.printStackTrace();
}

现在运行后即可生成一张二维码图片

二维码的解析

  • 利用Maven将Zxing-core.jar 包加入到项目中。
  • 和生成一样,我们需要一个辅助类( BufferedImageLuminanceSource),同样该类Google也提供了,这里我同样将该类的源码贴出来,可以直接拷贝使用个,省去查找的麻烦
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
BufferedImageLuminanceSource   
import com.google.zxing.LuminanceSource;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;

public final class BufferedImageLuminanceSource extends LuminanceSource {

private final BufferedImage image;
private final int left;
private final int top;

public BufferedImageLuminanceSource(BufferedImage image) {
this(image, 0, 0, image.getWidth(), image.getHeight());
}

public BufferedImageLuminanceSource(BufferedImage image, int left, int top, int width, int height) {
super(width, height);

int sourceWidth = image.getWidth();
int sourceHeight = image.getHeight();
if (left + width > sourceWidth || top + height > sourceHeight) {
throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
}

for (int y = top; y < top + height; y++) {
for (int x = left; x < left + width; x++) {
if ((image.getRGB(x, y) & 0xFF000000) == 0) {
image.setRGB(x, y, 0xFFFFFFFF); // = white
}
}
}

this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY);
this.image.getGraphics().drawImage(image, 0, 0, null);
this.left = left;
this.top = top;
}

@Override
public byte[] getRow(int y, byte[] row) {
if (y < 0 || y >= getHeight()) {
throw new IllegalArgumentException("Requested row is outside the image: " + y);
}
int width = getWidth();
if (row == null || row.length < width) {
row = new byte[width];
}
image.getRaster().getDataElements(left, top + y, width, 1, row);
return row;
}

@Override
public byte[] getMatrix() {
int width = getWidth();
int height = getHeight();
int area = width * height;
byte[] matrix = new byte[area];
image.getRaster().getDataElements(left, top, width, height, matrix);
return matrix;
}

@Override
public boolean isCropSupported() {
return true;
}

@Override
public LuminanceSource crop(int left, int top, int width, int height) {
return new BufferedImageLuminanceSource(image, this.left + left, this.top + top, width, height);
}

@Override
public boolean isRotateSupported() {
return true;
}

@Override
public LuminanceSource rotateCounterClockwise() {

int sourceWidth = image.getWidth();
int sourceHeight = image.getHeight();

AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth);

BufferedImage rotatedImage = new BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY);

Graphics2D g = rotatedImage.createGraphics();
g.drawImage(image, transform, null);
g.dispose();

int width = getWidth();
return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), getHeight(), width);
}

}

编写解析二维码的实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
try {  
MultiFormatReader formatReader = new MultiFormatReader();
String filePath = "C:/Users/Administrator/Desktop/testImage/test.jpg";
File file = new File(filePath);
BufferedImage image = ImageIO.read(file);;
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Map hints = new HashMap();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
Result result = formatReader.decode(binaryBitmap,hints);

System.out.println("result = "+ result.toString());
System.out.println("resultFormat = "+ result.getBarcodeFormat());
System.out.println("resultText = "+ result.getText());

} catch (Exception e) {
e.printStackTrace();
}

现在运行后可以看到控制台打印出了二维码的内容

hibernate-configuration

1
2
3
4
5
6
7
8
9
10
11
12
13
<hibernate-configuration>
<session-factory>
<propertyname="connection.driver_class">com.mysql.jdbc.Driver</property>
<propertyname="connection.url">jdbc:mysql://localhost:3306/hibernate-1</property>
<propertyname="connection.username">root</property>
<propertyname="connection.password">root</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<propertyname="show_sql">true</property>
<propertyname="format_sql">true</property>
<propertyname="hbm2ddl.auto">create</property>
<mappingresource="com/yuan/model/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>

hibernate级联操作

1
2
3
4
5
6
7
8
9
<many-to-one name="category" class="Category" cascade="save-update">
<!-- 映射的字段 -->
<column name="categoryId"/>
</many-to-one>
cascade
none;//默认
save-update;
delete;
all;

Hibernate关系映射

多对一单向映射 –> hibernate=-4

1
2
3
4
 <many-to-onename="category"class="com.yuan.hibernate.Category"fetch="join">
<columnname="CATEGORYID"/>
</many-to-one>
privateCategorycategory;

多对一双向映射 –> hibernate-5

1
2
3
<many-to-onename="category"class="com.yuan.hibernate.Category"fetch="join">
<columnname="CATEGORY"/>
</many-to-one>

1
2
3
4
5
6
7
  <setname="book"table="BOOK"inverse="false"lazy="true">
<key>
<columnname="ID"/>
</key>
<one-to-manyclass="com.yuan.hibernate.Book"/>
</set>
privateSet<Book>book;

一对一主键关系映射 –> hibernate-6

1
2
3
4
<one-to-onename="user"class="com.yuan.model.User"></one-to-one>
<one-to-onename="idCard"class="com.yuan.model.IdCard"></one-to-one>
privateUseruser;
privateIdCardidCard;

一对一主键外键关系映射 – > hibernate-7

1
2
<many-to-onename="idCard"update="true"/>
privateIdCardidCard;

多对多关系映射 – > hibernate-8

1
2
3
4
5
6
7
<setname="students"table="STUDENT_COURSE"inverse="false"lazy="true">
<key>
<columnname="COURSEID"/>
</key>
<many-to-manyclass="com.yuan.model.Student"column="STUDENTID"/>
</set>
```







privateSetstudents;
privateSetcourses;
```

HibernateUtil.save

1
2
3
4
5
6
7
8
9
10
11
12
Sessionsession=null;
try{
session=HibernateUtil.getSession();
session.beginTransaction();
session.save(customer);
session.getTransaction().commit();
}catch(Exceptione){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtil.closeSession();
}

HibernateUtil

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package com.yuan.hibernate;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistryBuilder;

public class HibernateUtil {
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static SessionFactory sessionFactory = null; // SessionFactory对象
// 静态块
static {
try {
Configuration cfg = new Configuration().configure(); // 加载Hibernate配置文件
sessionFactory = cfg
.buildSessionFactory(new ServiceRegistryBuilder().applySettings(cfg.getProperties())
.buildServiceRegistry());
} catch (Exception e) {
System.err.println("创建会话工厂失败");
e.printStackTrace();
}
}

/**
* 获取Session
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession()
: null;
threadLocal.set(session);
}
return session;
}

/**
* 重建会话工厂
*/
public static void rebuildSessionFactory() {
try {
Configuration cfg = new Configuration().configure(); // 加载Hibernate配置文件
sessionFactory = cfg
.buildSessionFactory(new ServiceRegistryBuilder().applySettings(cfg.getProperties())
.buildServiceRegistry());
} catch (Exception e) {
System.err.println("创建会话工厂失败");
e.printStackTrace();
}
}

/**
* 获取SessionFactory对象
*
* @return SessionFactory对象
*/
public static SessionFactory getSessionFactory() {
return sessionFactory;
}

/**
* 关闭Session
*
* @throws HibernateException
*/
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close(); // 关闭Session
}
}
}