JPA简介
JPA可以自动建表,简单配置就可以实现简单查询,因此可以使用JPA做简单的查询和自动建表,使用JPA自动建表,使用mybatis查询。
(1)JPA依赖如下,放到common-db中,作为所用用到数据库的公共依赖
<!--jpa依赖,用于自动建表-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
(2)在goods-api项目中引用common-db的包,并且创建实体类,此处仅处理实体和对应的数据库名,不连接具体的数据库
@Data
@Table(name = "tb_brand")
@Entity
public class Brand implements Serializable {
// 品牌id
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
// 品牌名称
@Column(name = "name")
private String name;
// 品牌图片地址
@Column(name = "image")
private String image;
// 品牌首字母
@Column(name = "letter")
private String letter;
// 排序
@Column(name = "seq")
private Integer seq;
}
(3)goods-service中引用以上两个依赖,然后配置yml为需要连接的数据库和jpa配置,此时启动service即可自动建表
spring:
application:
name: goods
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://XXXXX:3306/goods?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: XXXX
jpa:
hibernate:
ddl-auto: update
database: MYSQL
show-sql: true
Mybatis
IDEA有很多mybatis的插件,可以做到代码自动生成,此处使用mybatis-generator-plugin
(1)在service的父工程中引入plugin
<build>
<!--插件-->
<plugins>
<!--springboot的maven插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.0</version>
<!--插件设置-->
<configuration>
<!--允许移动生成的文件-->
<verbose>true</verbose>
<!--启用覆盖-->
<overwrite>true</overwrite>
<!--自动生成配置 如果名字是generatorConfig.xml可以省略配置,父工程不指定位置,子工程采用默认配置-->
<!--<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>-->
</configuration>
<dependencies>
<dependency>
<!--此处使用common-db是因为项目的所有数据库相关依赖都在其中,间接依赖即可-->
<groupId>com.changgou</groupId>
<artifactId>changgou-common-db</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
(2)配置generatorConfig.xml
因为pojo已经单独提出,将javaModelGenerator 的路径设置为一个不存在的路径,不保存Dao实体,其中javaClientGenerator 为Mapper对应的Interface的位置,sqlMapGenerator 为mapper的位置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否生成注释代时间戳-->
<property name="suppressDate" value="true"/>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--数据库链接地址账号密码-->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://192.168.1.8:3306/goods?serverTimezone=Asia/Shanghai" userId="root" password="123456">
</jdbcConnection>
<javaTypeResolver>
<!--该属性可以控制是否强制DECIMAL和NUMERIC类型的字段转换为Java类型的java.math.BigDecimal,默认值为false,一般不需要配置。-->
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--生成Model类存放位置-->
<javaModelGenerator targetPackage="com.changgou.goods" targetProject="src/main/java/hhh">
<!--enableSubPackages:如果true,MBG会根据catalog和schema来生成子包。如果false就会直接用targetPackage属性。默认为false。-->
<property name="enableSubPackages" value="true"/>
<!--trimStrings:是否对数据库查询结果进行trim操作,如果设置为true就会生成类似这样public void setUsername(String username) {this.username = username == null ? null : username.trim();}的setter方法。默认值为false。-->
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--生成映射xml文件存放位置-->
<sqlMapGenerator targetPackage="com.changgou.goods" targetProject="src/main/resources/">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!--生成Dao类存放位置(*Mapper.java)-->
<!-- 客户端代码,生成易于使用的针对Model对象和XML配置文件 的代码
type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象
type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象
type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口
-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.changgou.dao" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!--生成对应表及类名-->
<table tableName="tb_brand" domainObjectName="Brand" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false">
<!--useActualColumnNames:如果设置为true,那么MBG会使用从数据库元数据获取的列名作为生成的实体对象的属性。 如果为false(默认值),MGB将会尝试将返回的名称转换为驼峰形式。 在这两种情况下,可以通过 元素显示指定,在这种情况下将会忽略这个(useActualColumnNames)属性。-->
<property name="useActualColumnNames" value="true"/>
<!-- 数据库表主键 -->
<generatedKey column="id" sqlStatement="Mysql" identity="true" />
</table>
</context>
</generatorConfiguration>
(3)点击插件的生成按钮即可生成
FAQ
趟了一遍坑,终于可以使用了
(1)@Mapper与@MapperSCAN注解
如果不添加将出现下面的报错,@Mapper是将单个接口注册未Mapper,@MapperScan(“路径”)是将路径下的接口注册未Mapper
Description:
Field brandMapper in com.changgou.service.Impl.BrandServiceImpl required a bean of type 'com.changgou.dao.BrandMapper' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.changgou.dao.BrandMapper' in your configuration.
(2)mapper.xml中实体对应有错误
报错超级长,仔细看也可以看的出来,“ Cannot find class: com.changgou.goods.Brand”,映射到实体写错了
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'brandController': Unsatisfied dependency expressed through field 'brandService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'brandServiceImpl': Unsatisfied dependency expressed through field 'brandMapper'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'brandMapper' defined in file [D:\Work\Project\changgou\changgou-parent\service\goods-service\target\classes\com\changgou\dao\BrandMapper.class]: Unsatisfied dependency expressed through bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource: 'file [D:\Work\Project\changgou\changgou-parent\service\goods-service\target\classes\com\changgou\dao\BrandMapper.xml]'; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. Cause: org.apache.ibatis.builder.BuilderException: Error resolving class. Cause: org.apache.ibatis.type.TypeException: Could not resolve type alias 'com.changgou.goods.Brand'. Cause: java.lang.ClassNotFoundException: Cannot find class: com.changgou.goods.Brand
(3)mapper.xml中id重复
报错又超级长,仔细查看后发现“Mapped Statements collection already contains value for com.changgou.dao.BrandMapper.updateByPrimaryKey”,说明xml中的id是有重复的
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'brandController': Unsatisfied dependency expressed through field 'brandService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'brandServiceImpl': Unsatisfied dependency expressed through field 'brandMapper'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'brandMapper' defined in file [D:\Work\Project\changgou\changgou-parent\service\goods-service\target\classes\com\changgou\dao\BrandMapper.class]: Unsatisfied dependency expressed through bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource: 'file [D:\Work\Project\changgou\changgou-parent\service\goods-service\target\classes\com\changgou\dao\BrandMapper.xml]'; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. Cause: java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.changgou.dao.BrandMapper.updateByPrimaryKey
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]