java spring boot 采坑

2019年2月19日19:25:42

 版本 2.1.3.RELEASE

1,本地开发需要加依赖库,保存实时热更新

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>

 配置是否开启

spring.devtools.add-properties=false

 

 

2,eclipse 格式化代码热键冲突,热键是ctrl+shift+f 如果使用搜狗输入法,在配置里面取消掉

 

3,java代码提示,Window ——> Preferences ——> Java ——> Editor ——> Content Assist 

[auto activation triggers for java]自动补全触发器,默认是".", 这个位置可以设置成26个字母外加'.':.abcdefghijklmnopqrstuvwxyz(不区分大小写)

[auto activation triggers for javadoc]javadoc的触发器,默认是"@#".

 

4,@Controller 和 @RestController

@Controller 在使用模板的时候使用返回 是这个请求

如果只返回body数据在方法加上 @ResponseBody 

如果只返回body数据就直接加上@RestController 注解

 

5,Loading class `com.mysql.jdbc.Driver'. This is deprecated.注意spring boot的版本

application.properties 修改

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

 

6,关于业务分层

     @Service用于标注业务层组件,

     @Controller用于标注控制层组件(如struts中的action),

     @Repository用于标注数据访问组件,即DAO组件,

     @Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注

 

 7,开发手册 ghost win10缺少hh.exe

最简单的方式就是其他原装系统中复制hh.exe(windows目录),hhctrl.ocx,itss.dll,itircl.dll(windows/system32目录)。

1.将里面的hh.exe文件放置电脑 C:\Windows目录下;
2.将 hhctrl.ocx ,itss.dll ,itircl.dll三个文件放置 C:\Windows\System32 目录下;
3.以管理员方式打开cmd,输入:
4.regsvr32 hhctrl.ocx
5.regsvr32 itss.dll
6regsvr32 itircl.dll 提示成功即可

 

8,根据表生产表模型

网页工具:http://java.bejson.com/generator/

eclipse 自带工具jpa工具 mybatis也有类似工具

jpa工具添加

https://blog.csdn.net/xwnxwn/article/details/53304153

https://blog.csdn.net/abc997995674/article/details/80227396

建议使用jpa tools

 

9,freemarker 配置

 

10,设置eclipse设置IDE编码

https://blog.csdn.net/qq_20936333/article/details/81322007

 

11, @getMapping与@postMapping  @RequestMapping

@getMapping与@postMapping
首先要了解一下@RequestMapping注解。

  @RequestMapping用于映射url到控制器类的一个特定处理程序方法。可用于方法或者类上面。也就是可以通过url找到对应的方法。

  @RequestMapping有8个属性。

value:指定请求的实际地址。

method:指定请求的method类型(GET,POST,PUT,DELETE)等。

consumes:指定处理请求的提交内容类型(Context-Type)。

produces:指定返回的内容类型,还可以设置返回值的字符编码。

params:指定request中必须包含某些参数值,才让该方法处理。

headers:指定request中必须包含某些指定的header值,才让该方法处理请求。

 

@getMapping与@postMapping是组合注解。

@getMapping = @requestMapping(method = RequestMethod.GET)。

@postMapping = @requestMapping(method = RequestMethod.POST)。

 12,api返回restful风格的json数据格式,建议直接使用map做数据返回不用写 RequestMapping的一些参数

 

public class ResponseHelper {

    public static Map<String, Object> responseData(int code, String message, Object data) {
        Map<String, Object> objects = new HashMap<String, Object>();
        objects.put("code", code);
        objects.put("message", message);
        objects.put("data", data);
        return objects;
    }

    public static Map<String, Object> responseMessage(int code, String message) {
        Map<String, Object> objects = new HashMap<String, Object>();
        objects.put("code", code);
        objects.put("message", message);
        return objects;
    }

}

使用@RestController 注解,配置

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=Asia/Shanghai

 

13,关于数据存储时间和数据库返回时间不一致比如相差13,14个小时,是因为mysql的配置时区导致的

一般直接设置默认时区加8个小时就oK

[mysqld]

default-time-zone='+8:00'

 

14,数据库主键生成策略

@GeneratedValue(strategy=GenerationType.AUTO)

@GeneratedValue: 
@GeneratedValue 用于标注主键的生成策略,通过strategy 属性指定。默认情况下,JPA 自动选择一个最适合底层数据库的主键生成策略:SqlServer对应identity,MySQL 对应 auto increment。 
在javax.persistence.GenerationType中定义了以下几种可供选择的策略: 
–IDENTITY:采用数据库ID自增长的方式来自增主键字段,Oracle 不支持这种方式; 
–AUTO: JPA自动选择合适的策略,是默认选项; 
–SEQUENCE:通过序列产生主键,通过@SequenceGenerator 注解指定序列名,MySql不支持这种方式 
–TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。

 一般MySQL使用  @GeneratedValue(strategy = GenerationType.IDENTITY)

 

15字段自动更新

启动类加@EnableJpaAuditing
@EnableJpaAuditing

@EntityListeners(AuditingEntityListener.class) 是用于监听实体类添加或者删除操作的。

@JsonIgnoreProperties(value = {"createdAt", "updatedAt"},
allowGetters = true) 这个注解是用于在除了在获取createAt,updateAt属性时进行操作,其他创建和更新操作都由jpa完成

@Column(nullable = false, updatable = false) 其中updatable = false表示不进行更新操作

@CreatedDate 表示该字为创建时间字段,在这个实体被insert时,设置值;@LastModifiedDate同理

 

16:请求参数接收的格式

@RequestParam post 请求不支持json格式

ajax的时候,为了方便可以使用get,但是不安全

 $("#apply_link_form").submit(function(){
        parent.layer.close(index); //再执行关闭
        $.ajax({
            async: false,
            type: "POST",
            url:'${pageContext.request.contextPath}/link/apply',
            contentType : "application/x-www-form-urlencoded; charset=utf-8",
            data:$("#apply_link_form").serialize(),
            dataType: "text",
            success: function () {
              },
            error: function () {
            }
        })
    })
contentType : "application/x-www-form-urlencoded; charset=utf-8",

这个是关键

17:spring-boot @Component和@Bean的区别

@Component 是用在类上的

@Component
public class Student {
private String name = "lkm";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}


@Bean 需要在配置类中使用,即类上需要加上@Configuration注解

@Configuration
public class WebSocketConfig {
@Bean
public Student student(){
return new Student();
}
}

如果你想要将第三方库中的组件装配到你的应用中,在这种情况下,是没有办法在它的类上添加@Component注解的,因此就不能使用自动化装配的方案了,但是我们可以使用@Bean。

18.jpa参考手册

https://blog.csdn.net/qq_37939251/article/details/83052613

https://blog.csdn.net/yswknight/article/details/79257372

 

19,list的在for循环的时候使用add ,remove都会出现java.util.ConcurrentModificationException

解决办法:使用Iterator的add ,remove

 

20,Iterator引起的java.util.NoSuchElementException异常

不论什么情况

一个while里面不能调用两次next,不会边界溢出,异常错误名称很明显

demo

public List<AdminPermission> filterMenu(List<AdminPermission> permissionList, BigInteger adminId) throws Exception {
        List<BigInteger> adminPermission = getAdminPermission(permissionList, adminId);
        System.err.println(adminPermission.toString());

        // 过滤菜单,目前固定三层
        // list的在for循环的时候使用add ,remove都会出现java.util.ConcurrentModificationException
        // 使用Iterator的remove
        Iterator<AdminPermission> itr = permissionList.iterator();

        while (itr.hasNext()) {
            List<AdminPermission> child1 = itr.next().getChild();
            Iterator<AdminPermission> itr1 = child1.iterator();

            while (itr1.hasNext()) {
                List<AdminPermission> child2 = itr1.next().getChild();
                Iterator<AdminPermission> itr2 = child2.iterator();

                while (itr2.hasNext()) {
                    if (!adminPermission.contains(itr2.next().getId())) {
                        itr2.remove();
                    }
                }
                // 必须这样写,不然会溢出边界
                if (child2.size() == 0) {
                    itr1.remove();
                }
            }
            if (child1.size() == 0) {
                itr.remove();
            }

        }

        return permissionList;

 

 

21:getOne 方法出现 org.hibernate.LazyInitializationException: could not initialize proxy [com.zs.logistics.model.New#656] - no Session

主要是因为 数据库模型有些字段懒加载导致的

解决办法:

spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

在操作的实体上加上

@Proxy(lazy = false)

 这个任何使用对加载性能有影响的,自己斟酌,个人建议,配置为主,因为你不知要其他开发人员的开发习惯,规避bug

 

22,freemarker时间,数字格式化

https://blog.csdn.net/pengpengpeng85/article/details/52070602

 

23;PageRequest pageable 翻页问题是从0开始的,但是页面翻页是从1开始,减一就可以,需要添加判断

PageRequest pageRequest = PageRequest.of(pageNo - 1, pageSize, sort);

 

24,com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) 

错误原因json化字段有null的值

发现是实体类中有的字段值为null,所以在json化的时候,fasterxml.jackson将对象转换为json报错

解决办法:

  在实体类上面加上注解 @JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" })

 

25,Spring JPA 使用@CreatedDate、@CreatedBy、@LastModifiedDate、@LastModifiedBy 自动生成时间和修改者

1.实体类加注解
/**
 * 创建时间
 */
@CreatedDate
@Column(name = "create_time")
private Date createTime;

/**
 * 修改时间
 */
@LastModifiedDate
@Column(name = "modify_time")
private Date modifyTime;


2.实体类头加注解

@EntityListeners(AuditingEntityListener.class)

3.SpringBoot启动类加注解

@EnableJpaAuditing

在spring jpa中,支持在字段或者方法上进行注解@CreatedDate、@CreatedBy、@LastModifiedDate、@LastModifiedBy,从字面意思可以很清楚的了解,这几个注解的用处。


@CreatedDate
表示该字段为创建时间时间字段,在这个实体被insert的时候,会设置值
@CreatedBy
表示该字段为创建人,在这个实体被insert的时候,会设置值
@LastModifiedDate、@LastModifiedBy同理

 

 25,添加阿里云镜像

pom.xml

<repositories>
        <repository>
            <id>central</id>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <layout>default</layout>
            <!-- 是否开启发布版构件下载 -->
            <releases>
                <enabled>true</enabled>
            </releases>
            <!-- 是否开启快照版构件下载 -->
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

简单版

<repositories>
        <repository>
            <id>aliyunmaven</id>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        </repository>
    </repositories>

 

26,This compilation unit is not on the build path of java project

.project 文件 加上

<nature>org.eclipse.jdt.core.javanature</nature>

27,editor does not contain a main type

在 解决方法: 对着:src 路径右键 -> Build Path -> Use as Source Folder

28,java.sql.SQLNonTransientConnectionException: Could not create connection to driver: com.mysql.cj.jdbc.Driver

url: jdbc:mysql://localhost:3306/yinliu?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
 
driver: com.mysql.cj.jdbc.Driver


29,com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

mysql配置文件添加
wait_timeout=1814400

 

30 jpa映射 json格式数据

<!-- https://mvnrepository.com/artifact/com.vladmihalcea/hibernate-types-5 -->
<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-5</artifactId>
    <version>2.4.3</version>
</dependency>
并将此行添加到实体

@TypeDef(name = "json", typeClass = JsonStringType.class)
@Type( type = "json" name = "json_value")
   @Column( columnDefinition = "json" )
   private List<String> jsonValue;

 31,mysql tinyint 如果使用unsigned 是1-255,所以映射到jpa不能使用byte 需要int,java没有无符号定义,byte 是-127到128

32,单引号,双引号的区别单引号引的数据 是char类型的——》单引号只能引一个字符(表示单个字符)

双引号引的数据 是String类型的——》而双引号可以引0个及其以上(引用字符串)


char类型的值用单引号引起来的单个字符
如: char a = 'b'
而java中的双引号 表示字符串 一个或多个字符 如 String c = "abc" String d="a" 和char d=‘a’

32,Spring 使用 @Value 取不到值

但是根据网上的例子,我一直获取不到,首先根据spring的例子,
想要使用@Value,必须把当前类加入spring的容器管理, 如果使用注解,就是在类上加入
@Controller @Service @Component 等容器注解,可是我加入了@Component注解,依然不能获取到值,但是如果是在@Controller 下,则可以。翻阅多篇博客论坛后,终于找到原因。
原来,使用@Value的类,在spring中,不能直接通过new 操作符来使用,而是应该通过spring的注解 @Autowired 来使用

 33,mybatis collection association

Mybatis的一对多(collection)和一对一(association)查询

Association:  一对一查询的方式

<resultMap id="TestTwoAll" type="TestTwo">
        <id property="id" column="twoid"/>
        <result property="nickname" column="twonickname"/>
        <result property="oneId" column="one_id"/>
        <association property="testOne" column="one_id" javaType="TestOne">
            <id property="id" column="oneid"/>
            <result property="nickname" column="onenickname"/>
        </association>
    </resultMap>

    <select id="getTotalById" resultMap="TestTwoAll" parameterType="long">
        SELECT
        one.id as oneid,
        one.nickname as onenickname,
        two.id as twoid,
        two.nickname as twonickname,
        two.one_id
        FROM test_one one,test_two two
        where one.id=two.one_id and two.id=#{value}
    </select>

Collection:  一对多查询的方式

<resultMap id="TestOneAll" type="TestOne">
        <result property="id" column="oneid"/>
        <result property="nickname" column="onenickname"/>
        <collection property="testTwos" column="one_id" ofType="TestTwo" javaType="ArrayList">
            <result property="id" column="twoid"/>
            <result property="nickname" column="twonickname"/>
            <result property="oneId" column="one_id"/>
        </collection>
    </resultMap>

    <select id="getTotalById" resultMap="TestOneAll" parameterType="long">
        SELECT
        one.id as oneid,
        one.nickname as onenickname,
        two.id as twoid,
        two.nickname as twonickname,
        two.one_id
        FROM test_one one,test_two two
        where one.id=two.one_id and one.id=#{VALUE }
        order by twoid desc
    </select>

 

34,Mybatis (ParameterType) 如何传递多个不同类型的参数

方法一:不需要写parameterType参数
public List<XXXBean> getXXXBeanList(String xxId, String xxCode);
<select id="getXXXBeanList" resultType="XXBean">

  select t.* from tableName where id = #{0} and name = #{1}

</select>
由于是多参数那么就不能使用parameterType, 改用#{index}是第几个就用第几个的索引,索引从0开始

方法二:基于注解(最简单)
public List<XXXBean> getXXXBeanList(@Param("id")String id, @Param("code")String code);
<select id="getXXXBeanList" resultType="XXBean">

  select t.* from tableName where id = #{id} and name = #{code}

</select>
由于是多参数那么就不能使用parameterType, 这里用@Param来指定哪一个

方法三:Map封装
public List<XXXBean> getXXXBeanList(HashMap map);
<select id="getXXXBeanList" parameterType="hashmap" resultType="XXBean">

  select 字段... from XXX where id=#{xxId} code = #{xxCode}

</select>
其中hashmap是mybatis自己配置好的直接使用就行。map中key的名字是那个就在#{}使用那个,map如何封装就不用了我说了吧。

方法四:List封装
public List<XXXBean> getXXXBeanList(List<String> list);


<select id="getXXXBeanList" resultType="XXBean">
  select 字段... from XXX where id in
  <foreach item="item" index="index" collection="list" open="(" separator="," close=")">
    #{item}
  </foreach>
</select>

 

posted on 2019-02-20 09:29  zh7314  阅读(481)  评论(0编辑  收藏  举报