Springboot链接SqlServer配置并通过JPA操作实战

springboot链接sqlserver和其他数据库基本一致,当然因为每个数据库的数据类型有些不同,所以在数据库方言需要配置一下

文章为Springboot链接SqlServer2012,其他的SqlServer版本基本一致

一、配置

  • maven依赖

    如果下载不下来,那么手动在maven仓库下载并安装到本地maven仓库中,就可以正常引入,不过无法下载,可以使用第二个依赖,亲测可以直接下载。

    
    <dependency>
    	<groupId>com.microsoft.sqlservergroupId>
    	<artifactId>sqljdbc4artifactId>
    	<version>4.0version>
    dependency>
    
    
    <dependency>
      <groupId>com.microsoft.sqlservergroupId>
      <artifactId>mssql-jdbcartifactId>
      <version>6.1.0.jre8version>
    dependency>
    
    
  • properties配置

    配置数据源,yml文件也是一样的

    # sqlServer链接驱动
    spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
    # 配置数据库链接ip端口,以及指定库的名称
    spring.datasource.url=jdbc:sqlserver://localhost:1433;DatabaseName=test
    spring.datasource.username=root
    spring.datasource.password=123456
    
    # 指定数据库schema
    spring.jpa.properties.hibernate.default_schema = dbo
    # 自定义策略转换表名大小写(这个是一个自定义的类用来指定sql中的表名大小写)
    spring.jpa.hibernate.naming.physical-strategy=com.ford.configuration.UpperTableStrategy
    # 配置数据库方言(这个比较重要,自定义类用来指定sqlServer的方言配置)
    spring.jpa.database-platform=com.ford.configuration.SqlServerDialect
    

    上面就是链接sqlServer数据库的配置,其中有2个配置是自定义的,当然如果你的表名都是小写,那么不需要配置将hibernate的sql中的表名转换为大写,无须配置该属性spring.jpa.hibernate.naming.physical-strategy=com.ford.configuration.UpperTableStrategy

  • UpperTableStrategy 配置类
    因为数据库中的表名是大写的,但是Hibernate会将映射的表名在生成Sql的时候转换为小写,导致无法查询到相应的数据表,所以需要此配置转换表名大小写

    /**
     * 转换表名小写为大写
     */
    public class UpperTableStrategy extends PhysicalNamingStrategyStandardImpl {
        private static final long serialVersionUID = 1383021413247872469L;
    
        @Override
        public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
            // 将表名全部转换成大写
            String tableName = name.getText().toUpperCase();
            return Identifier.toIdentifier(tableName);
        }
    }
    
  • SqlServerDialect 配置类

    /**
     * 自定义方言类,处理使用原生Sql查询,数据类型和hibernate对应关系
     	 
     	 继承SQLServer2012Dialect,如果sqlServer版本是2008则继承
     	 SQLServer2008Dialect,其他版本继承各自的版本
     
     */
    public class SqlServerDialect extends SQLServer2012Dialect {
    
        /**
         * 设置sql server 数据库方言转换
         */
        public SqlServerDialect() {
            registerHibernateType(Types.NCHAR, StandardBasicTypes.CHARACTER.getName());
            registerHibernateType(Types.NCHAR, 1, StandardBasicTypes.CHARACTER.getName());
            registerHibernateType(Types.NCHAR, 255, StandardBasicTypes.STRING.getName());
            registerHibernateType(Types.NVARCHAR, StandardBasicTypes.STRING.getName());
            registerHibernateType(Types.LONGNVARCHAR, StandardBasicTypes.TEXT.getName());
            registerHibernateType(Types.NCLOB, StandardBasicTypes.CLOB.getName());
        }
    }
    

二、JPA使用

springData JPA好的就是将不同的数据库方法都统一封装,使用方式基本一致,只需要配置不同的数据源和方言即可

  • Repository为例

    public interface DataRepository extends JpaRepository<TestData,String>, JpaSpecificationExecutor<TestData> {
    
    		/**
    		 * 使用原生sql查询
    		 */
        @Query(value = "select top(100) * from [test].[dbo].[test_table] where flag = '0'", nativeQuery = true)
        List<TestData> getDataWithNotPushed();
    
    		/**
    		 * 使用原生sql更新
    		 */
        @Modifying
        @Query(value = "update [test].[dbo].[test_table] set flag = '1' where id = :id", nativeQuery = true)
        void updateFlag(@Param("id") String id);
        
        /**
    		 * 如果不想用原生sql,可以直接使用方法名的方式或者jpa接口的通用方法
    		 	 
    		 	  根据方法名查询,findByXX,传入参数即可,表示查询flag=参数的数据
    		 */
    		List<TestData> findByFlag(String flag);
    }
    

三、链接SqlServer问题总结

  1. No Dialect mapping for JDBC type: -9

    在使用自定义sql查询的时候,报这个错误,大概是因为在数据表中有字段的类型为nvarchar,然后无法对应到Hibernate的String类型,所以报错。

    • 解决方案:

      第一种

      如果实体类不多的话,可以直接使用@Column注解的columnDefinition属性

      /**
       * columnDefinition用于指定该列的类型,并指定长度
       */
      @Column(name = "flag", columnDefinition = "nvarchar(20)")
      private String flag;
      
      @Column(name = "orders", , columnDefinition = "nvarchar(100)")
      private Integer orders;
      

      第二种

      通过配置文件中的:spring.jpa.database-platform=com.ford.configuration.SqlServerDialect 配置sqlServer的方言(SqlServerDialect类的具体配置见上面的代码)

  2. Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 对象名 ‘xx.xxxxx’ 无效

    这个问题一般是表的schema或者表名错误导致的问题

    这里的问题是由于hibernate在生成sql的时候会将表名小写,无论在@Table中指定的表名是否小写,都会转换为小写

    • 解决方案:

      在配置文件中:spring.jpa.hibernate.naming.physical-strategy=com.ford.configuration.UpperTableStrategy 自定义策略,将生成sql中的表名转换为大写(UpperTableStrategy类的配置代码见上面)

  3. java.lang.UnsupportedOperationException: query result offset is not supported

    这个问题是在使用JPA的分页查询时出现,无法封装结果集

    刚开始自定义方言配置类(spring.jpa.database-platform后面配置的自定义方言类)继承SQLServerDialect类,出现这个问题,然后不使用自定义方言类,直接使用SQLServer2012Dialect——> 即spring.jpa.database-platform=org.hibernate.dialect.SQLServer2012Dialect,这样又有问题,原生Sql无法使用,报第一个错误。

    解决:

    自定义方法类:

    spring.jpa.database-platform=com.ford.configuration.SqlServerDialect

    (和最上面的SqlServerDialect配置类的配置一致即可)

    然后让自定义的SqlServerDialect类继承SQLServer2012Dialect

你可能感兴趣的:(Java,java,数据库,sqlserver,sqlserver链接问题)