GVKun编程网logo

Spring Data JPA如何提供数据访问接口而不是休眠数据访问层(spring data jpa调用存储过程)

21

这篇文章主要围绕SpringDataJPA如何提供数据访问接口而不是休眠数据访问层和springdatajpa调用存储过程展开,旨在为您提供一份详细的参考资料。我们将全面介绍SpringDataJPA

这篇文章主要围绕Spring Data JPA如何提供数据访问接口而不是休眠数据访问层spring data jpa调用存储过程展开,旨在为您提供一份详细的参考资料。我们将全面介绍Spring Data JPA如何提供数据访问接口而不是休眠数据访问层的优缺点,解答spring data jpa调用存储过程的相关问题,同时也会为您带来(六)SpringBoot与数据访问、.net数据访问层组件Data Abstract下载及介绍、ASP.NET 一个数据访问层的封装、asp.net/wingtip/创建数据访问层的实用方法。

本文目录一览:

Spring Data JPA如何提供数据访问接口而不是休眠数据访问层(spring data jpa调用存储过程)

Spring Data JPA如何提供数据访问接口而不是休眠数据访问层(spring data jpa调用存储过程)

当探究hibernate
JPA实现时,我想到了使用hibernate和创建数据访问层以将数据读取和插入数据库以及从数据库插入数据的想法。现在我在项目中使用spring +
spring数据JPA +
Hibernate进行某些CRUD操作。我想到了数据JPA的作用是为数据库访问提供CRUD存储库而不是hibernateDAO。我这样使用CRUD存储库,

package com.central.repository;import java.util.List;import org.springframework.data.jpa.repository.Query;import org.springframework.data.repository.CrudRepository;import com.central.model.*;public interface DriverRepository extends CrudRepository<Driver, Integer> {Driver findById(Integer id);}

在这里,我从数据JPA的“
CrudRepository”存储库扩展而来。当我使用它时,数据JPA如何为我的界面提供存储库?它们是如何内置的,为我提供findAll(),save()和delete()存储库方法?实际上,我对JPA数据如何为我的界面提供存储库的作用感到怀疑?以及Data
JPA如何与hibernate通信以提供这些存储库实现?有人可以指导解决Data JPA与Hibernate JPA实现通信的核心概念吗?

答案1

小编典典

Spring Data为接口创建代理,并且为每种方法尝试不同的策略以查找/创建方法的实现。

的方法CrudRepository是在的SimpleJpaRepository其他方法对象中基于注释,参数和返回类型以及方法名称创建的,然后由代理调用。

有一篇有关基本概念的Wiki文章可能会有所帮助。

(六)SpringBoot与数据访问

(六)SpringBoot与数据访问

1、JDBC

 

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

 

1 spring:
2   datasource:
3     username: root
4     password: 123456
5     url: jdbc:mysql://192.168.1.104:3306/jdbc
6     driver-class-name: com.mysql.jdbc.Driver

效果:

  默认使用org.apache.tomcat.jdbc.pool.DataSource作为数据源;

  数据源的相关配置都在DataSourceProperties里面;

自动配置原理:

org.springframework.boot.autoconfigure.jdbc:

1、参考DataSourceConfiguration,根据配置创建数据源,默认使用Tomcat连接池;可以使用spring.datasource.type指定自定义的数据源类型;

2、SpringBoot默认可以支持;

org.apache.tomcat.jdbc.pool.DataSource、HikariDataSource、BasicDataSource

3、自定义数据源类型

/**
* Generic DataSource configuration.
*/
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type")
static class Generic {

    @Bean
    public DataSource dataSource(DataSourceProperties properties) {
        //使用DataSourceBuilder创建数据源 ,利用反射创建响应type的数据源,并且绑定相关属性         
        return properties.initializeDataSourceBuilder().build();
    }

}

4、DataSourceInitializer:ApplicationListener

  作用:

    1)、runSchemaScripts();运行建表语句;

       2)、runDataScripts();运行插入数据的sql语句;

默认只需要将文件命名为:

schema-*.sql、data-*.sql
默认规则:schema.sql,schema-all.sql;
可以使用   
    schema:
      - classpath:department.sql
      指定位置

5、操作数据库:自动配置jdbcTemplate操作数据库

2、整合Druid数据源

导入Druid数据源

 1 @Configuration
 2 public class DruidConfig {
 3 
 4     @ConfigurationProperties(prefix = "spring.datasource")
 5     @Bean
 6     public DataSource druid(){
 7         return new DruidDataSource();
 8     }
 9 
10     //配置Druid的监控
11     //1、配置一个管理后台的Servlet
12     @Bean
13     public ServletRegistrationBean statViewServlet(){
14         ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
15         Map<String,String> initParams = new HashMap<>();
16         initParams.put("loginUsername","admin");
17         initParams.put("loginPassword","123456");
18         initParams.put("allow","");//默认允许所有访问
19         initParams.put("deny","192.168.1.102");
20         bean.setInitParameters(initParams);
21         return bean;
22     }
23 
24     //2、配置一个web监控的filter
25     @Bean
26     public FilterRegistrationBean webStatFilter(){
27         FilterRegistrationBean bean = new FilterRegistrationBean();
28         bean.setFilter(new WebStatFilter());
29         Map<String,String> initParams = new HashMap<>();
30         initParams.put("exclusions","*.js,*.css,/druid/*");
31         bean.setInitParameters(initParams);
32         bean.setUrlPatterns(Arrays.asList("/*"));
33         return bean;
34     }
35 
36 }

3、整合Mybatis

1 <dependency>
2     <groupId>org.mybatis.spring.boot</groupId>
3     <artifactId>mybatis-spring-boot-starter</artifactId>
4     <version>1.3.2</version>
5 </dependency>

 

步骤:

  1)、配置数据源相关属性(见上一节Druid)

  2)、给数据库建表

  3)、创建JavaBean

1)、注解版

//指定这是一个操作数据库的mapper
@Mapper
public interface DepartmentMapper {

    @Select("select * from department where id=#{id}")
    Department getDeptById(Integer id);

    @Delete("delete from department where id=#{id}")
    int deleteDeptById(Integer id);

    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into department(departmentName) values (#{departmentName})")
    int insertDept(Department department);

    @Update("update department set departmentName=#{departmentName} where id=#{id}")
    int updateDept(Department department);

}

问题:

自定义MyBatis的配置规则,给容器中添加一个ConfigurationCustomizer;

@org.springframework.context.annotation.Configuration
public class MyBatisConfig {

    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return new ConfigurationCustomizer() {
            @Override
            public void customize(Configuration configuration) {
                configuration.setMapUnderscoreToCamelCase(true);
            }
        };
    }

}

 

使用MapperScan批量扫描所有的Mapper接口;
@MapperScan(value = "com.young.springboot.mapper")
@SpringBootApplication
public class SpringBoot06DataMybatisApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBoot06DataMybatisApplication.class, args);
    }
}

 

2)、配置文件版

mybatis:
  config-location: classpath:mybatis/mybatis-config.xml 指定全局配置文件的位置
  mapper-locations: classpath:mybatis/mapper/*.xml  指定sql映射文件的位置

 

4、整合SpringData JPA

1)、SpringData简介

 

2)、整合SpringData JPA

JPA:ORM(Object Relational Mapping)对象关系映射

1)、编写一个实体类(bean)和数据表进行映射,并且配置好映射关系;

 

//使用JPA注解配置映射关系
@Entity//告诉JPA这是一个实体类(和数据表映射的类)
@Table(name = "tbl_user")//@Table来指定和哪个数据表对应;如果省略默认表名就是user
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)//自增主键
    private Integer id;

    @Column(name = "last_name",length = 50)//这是和数据表对应的一个列
    private String lastName;

    @Column //省略默认列名就是属性名
    private String email;

 

2)、编写一个Dao接口来操作实体类对应的数据表(Repository)

//继承JpaRepository来完成对数据库的操作
public interface UserRepository extends JpaRepository<User,Integer>{
}

3)、基本的配置

spring:
  jpa:
    hibernate:
#     更新或者创建数据表结构
      ddl-auto: update
#   控制台显示SQL
    show-sql: true

 

.net数据访问层组件Data Abstract下载及介绍

.net数据访问层组件Data Abstract下载及介绍

原文来自龙博方案网http://www.fanganwang.com/product/1321转载请注明出处

Data Abstract是最好的多层次框架,它提供端到端的解决方案,同时也可以很轻松地建立起可扩展的数据库方案以满足如今的分布式系统要求。

概况特性

·         为.NET,Mono,32/64位的Windows以及Linux建立可扩展的、跨平台的多层次数据库解决方案。

·         使用一个通用的代码库处理不同的数据库设计或数据库系统。

·         使用RAD Schema Modeler模拟你的数据结构,以让其在中间层以及客户端层透明。

·         完全没有部署授权费用。

·         完全支持C#、Oxygene、Visual Basic .NET (.NET版本) 以及 Object Pascal (Delphi 版本)。

·         支持Silverlight web客户端。

库特性

·         完全抽象不同的数据库类型:只需编写一组代码即可访问任何支持的后台数据库类型。

·         完全抽象不同的数据库设计:使用一个单一的中间层服务器来处理不同的数据库设计,比如一个传统的数据库和一个新的、精心设计的替代数据库。

·         建立一个“无国籍”的、可扩展的、无缝集成的应用程序。

·         轻松建立自己的数据访问驱动用于扩展支持的数据库。

·         支持正则表达式的客户端数据验证。

·         Strongly Typed Data Tables通过面向对象的代码允许你从代码里访问你的数据表。

·         Business Helper Classes允许你封装业务逻辑和规则。

·         Let Data Abstract自动生成所有的SQL代码或提供手写SQL代码以满足特殊的需求。

·         使用Data Abstract的宏处理器可以最小化共享SQL代码与SQL语句的差异。

·         完全可重用的Reconcile Dialog体系,允许你为你的终端用户提供错误信息的反馈。

·         针对客户端数据存储的高性能的内存数据表组件(仅限Delphi/FPC;.NET利用现有的DataSet类)。

·         Rich Business Rules Scripting使用RemObjects Pascal Script.(仅限Delphi)。

·         完全本地化以及具有特定平台的实施,专为个人平台设计。

·         提供完整的源码,并且允许修改和再编译。

数据访问特性

·         在请求数据、分页或合并数据时一次性的整合数据。

·         自动同步远程数据源。

·         强大的业务处理器让你对你的业务更新有更多的控制。

·         跨数据库的AutoInc以及生成器支持基于整形的主键和外键。

·         完全支持无状态的主/明细事务更新。

·         广泛的跨数据库数据类型包括:XML,GUID以及Decimal类型。

·         利用最新DynamicWhere和DynamicSelect功能,可以纵向或横向过滤从客户端得到的数据子集。

·         Reduced Delta模式可以在更新时只发送关键字段或改变字段以优化网络流量。

·         在你的架构中定义联合表然后以一个整体的数据表发送到你的客户端。

·         使用DA SQL和DA LINQ从客户端灵活地查询数据(仅限.NET)。

Schema Modeler特性

·         利用Schema Modeler以一种创新的RAD方式设计你的数据访问层。

·         使用数据浏览器可以查看数据库系统的实时视图。

·         通过拖拽创建和定义数据表以及命令。

·         使用更新规则无需一行代码即可设计复杂的更新队列。

·         Validation Wizard可以保证你的结构100%的匹配数据库。

·         为不同的数据库设计定义列映射。

IDE整合特性

·         与支持的IDE完全整合。

·         项目模板和新建项目向导帮助你创建新的项目。

·         Schema Modeler项目与IDE整合,允许你在IDE项目系统(.NET)或窗体设计器(Delphi)中编辑你的服务定义。

·         第一次安装后显示新的欢迎页面,以帮助新用户熟悉产品。

RemObjects SDK特性

Data Abstract基于RemObjects SDK并包括了RemObjects SDK;请参考RemObjects SDK的特性以便对Data Abstract更加了解,这对你的DA项目很有好处。

支持的数据库系统
支持的数据库系统包括:

·         微软SQL Server 2000 and 2005

·         Microsoft SQL Server Compact Edition

·         Oracle

·         DB2

·         InterBase/Firebird

·         Sybase

·         PostgreSQL

·         MySQL

·         SQLite

·         NexusDB(仅限Delphi)

·         Borland Database Engine for dBase, Paradox(仅限Delphi)

Data Abstract(Delphi)支持的第三方数据访问组件

·         dbGo (ADO Express)

·         DBX

·         DBX4(Delphi2007及以后)

·         IBX

·         AnyDAC*

·         SDAC, ODAC, MyDAC 和 IBDAC by CoreLabs*

·         MySQLDAC 和 PostresDAC by microOLAP*

·         IBObjects*

·         DBISAM*

·         ZEOS

·         SQLite by Aducom (Data Abstract自带)

 








Data Abstract免费下载由龙博方案网www.fanganwang.com提供

Data Abstract 试用版  (39 MB)

试用版下载

Data Abstract 相关文章

  • Data Abstract 的详细描述

Data Abstract 相关新闻

  • 数据访问层组件Data Abstract加强对移动平台的支持
  • Data Abstract 控件介绍

ASP.NET 一个数据访问层的封装

ASP.NET 一个数据访问层的封装

刚通过开通写博客的申请,向博客园的大佬致敬,由于一直以来都在网上搜索大家的思想,也有翻遍整个百度都有的找不到的时候,作为一个网民理应为互联网贡献一点东西。

下面是我工作后受一个师傅的影响对数据库访问层的封装,多年以来一直都在使用,用的特别爽,请看下面的代码:

第一步、需要编写一个通用的用于查询的数据库存储过程,这个存储过程接受“表名、查询字段、排序、页大小、页码”:

CREATE PROCEDURE [dbo].[P_Pagination] 
    @tblName varchar(5000), -- 表名
    @strGetFields varchar(1000) = ''*'', -- 需要返回的列
    @strWhere varchar(1500) = '''', -- 查询条件(注意: 不要加 where)
    @OrderSql varchar(255) = '''', -- 排序语句(注意: 不要加 order by)
    @PageSize int = 0, -- 页尺寸
    @PageIndex int = 1, -- 页码
    @doCount bit = 0 -- 返回记录总数,非 0 值则返回
AS
BEGIN
    declare @strSQL varchar(5000) -- 主语句

    if @doCount <> 0
    begin
        if @strWhere <> ''''
            set @strSQL = ''select count(*) as Total from '' + @tblName + '' where '' + @strWhere
        else
            set @strSQL = ''select count(*) as Total from '' + @tblName + ''''
    end
    --以上代码的意思是如果@doCount传递过来的不是0,就执行总数统计。以下的所有代码都是@doCount为0的情况
    else
    begin
        if @PageSize = 0 --返回所有记录集
        begin
            if @strWhere <> ''''
                set @strSQL = ''select '' + @strGetFields + '' from '' + @tblName + '' where '' + @strWhere + '' order by '' + @OrderSql
            else
                set @strSQL = ''select '' + @strGetFields + '' from '' + @tblName + '' order by '' + @OrderSql
        end
        else 
        begin
            if @PageIndex = 1
            begin
                if @strWhere <> ''''
                    set @strSQL = ''select top '' + str(@PageSize) + '' '' + @strGetFields + '' from '' + @tblName + '' where '' + @strWhere + '' order by '' + @OrderSql
                else
                    set @strSQL = ''select top '' + str(@PageSize) + '' '' + @strGetFields + '' from '' + @tblName + '' order by '' + @OrderSql
                --如果是第一页就执行以上代码,这样会加快执行速度
            end
            else
            begin
                --以下代码赋予了@strSQL以真正执行的SQL代码
                if @strWhere = ''''
                    set @strSQL = ''select top '' + str(@PageSize) + '' tblTmp.* from ''
                        + ''(select ROW_NUMBER() OVER(order by '' + @OrderSql + '') AS RowNum,'' + @strGetFields + '' from '' + @tblName + '') tblTmp where tblTmp.[RowNum] > ''
                            + ''(select max([RowNum]) from ''
                                + ''(select top '' + str((@PageIndex - 1) * @PageSize) + '' ROW_NUMBER() OVER(order by '' + @OrderSql + '') AS RowNum from '' + @tblName + '') as tblTmp1)''
                else
                    set @strSQL = ''select top '' + str(@PageSize) + '' tblTmp.* from ''
                        + ''(select ROW_NUMBER() OVER(order by '' + @OrderSql + '') AS RowNum,'' + @strGetFields + '' from '' + @tblName + '' where '' + @strWhere + '') tblTmp where tblTmp.[RowNum] > ''
                            + ''(select max([RowNum]) from ''
                                + ''(select top '' + str((@PageIndex - 1) * @PageSize) + '' ROW_NUMBER() OVER(order by '' + @OrderSql + '') AS RowNum from '' + @tblName + '' where '' + @strWhere + '') as tblTmp1)''
            end
        end
    end
    exec (@strSQL);
END

第二步、封装数据库访问层,该层实现执行存储过程或SQL语句返回 DataTable、SqlDataReader、受影响行数:

namespace Ant.DAL
{
    /// <summary>
    /// 存储过程返回值
    /// </summary>
    public class ProcResultValue
    {
        /// <summary>
        /// @Result 字符串返回值
        /// </summary>
        public string ResultValueStr { get; set; }

        /// <summary>
        /// Return 任意类型返回值
        /// </summary>
        public int ReturnValueInt { get; set; }

        /// <summary>
        /// 存储过程异常实体信息返回
        /// </summary>
        public string ReturnValue
        {
            get
            {
                if (ReturnValueInt <= 0)
                    return ResultValueStr;
                else
                    return "";
            }
        }
    }

    /// <summary>
    /// 数据库基础操作类
    /// </summary>
    public class Database
    {
        // 测试用Sql连接字符串
        private static string SqlConn_Debug = System.Configuration.ConfigurationManager.ConnectionStrings["ConnDB"].ToString();/// <summary>
        /// 数据库基础操作类 构造函数
        /// </summary>
        public Database()
        {
        }

        /// <summary>
        /// 获得数据库连接数据
        /// </summary>
        /// <returns>数据库连接信息</returns>
        protected SqlConnection GetConn()
        {
            SqlConnection ConnDB = new SqlConnection(SqlConn_Debug);
            ConnDB.StateChange += new StateChangeEventHandler(ConnDB_StateChange);
            ConnDB.Open();
            return ConnDB;
        }

        /// <summary>
        /// 数据库链接状态改变事件
        /// </summary>
        protected void ConnDB_StateChange(object sender, StateChangeEventArgs e)
        {
            if (e.CurrentState == ConnectionState.Closed)
            {
                ((SqlConnection)sender).Dispose(); // 释放资源
                GC.Collect(); // 释放资源
            }
        }

        /// <summary>
        /// 获得对应表序列的新ID
        /// </summary>
        /// <param name="TableName">表名</param>
        /// <param name="TableCol">表ID列名</param>
        /// <param name="TableWhere">查询条件(注意:不添加''where'')</param>
        /// <returns>返回:序列的新ID</returns>
        protected int GetSequence(string TableName, string TableCol, string tableWhere = "")
        {
            DataParameters DP = new DataParameters();
            DP.Add("@TableName", SqlDbType.VarChar, TableName);
            DP.Add("@TableCol", SqlDbType.VarChar, TableCol);
            DP.Add("@tableWhere", SqlDbType.VarChar, tableWhere);
            return ExeProc("P_Sequence", DP, false).ReturnValueInt;
        }

        /// <summary>
        /// 通过存储过程,获得数据集 DataReader
        /// </summary>
        /// <param name="tblName">要查询的表名</param>
        /// <param name="strGetFields">要查询的字段</param>
        /// <param name="strWhere">查询条件(注意:不要加 "where")</param>
        /// <param name="OrderSql">排序规则(注意:不要加 "order by",且不能为空)</param>
        /// <param name="PageSize">页大小 为0时,则不分页</param>
        /// <param name="PageIndex">页索引</param>
        /// <returns>返回:记录集 SqlDataReader</returns>
        protected SqlDataReader GetDataReader(string tblName, string strGetFields, string strWhere, string OrderSql, int PageSize, int PageIndex)
        {
            SqlCommand Cmd = new SqlCommand("P_Pagination", GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;
            Cmd.Parameters.Add("@tblName", SqlDbType.VarChar).Value = tblName;
            Cmd.Parameters.Add("@strGetFields", SqlDbType.VarChar).Value = strGetFields;
            Cmd.Parameters.Add("@strWhere", SqlDbType.VarChar).Value = strWhere;
            Cmd.Parameters.Add("@OrderSql", SqlDbType.VarChar).Value = OrderSql;
            Cmd.Parameters.Add("@PageSize", SqlDbType.Int).Value = PageSize;
            Cmd.Parameters.Add("@PageIndex", SqlDbType.Int).Value = PageIndex;
            Cmd.Parameters.Add("@doCount", SqlDbType.Bit).Value = false;
            return Cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }

        /// <summary>
        /// 通过存储过程及自定义参数,获得数据集 DataReader
        /// </summary>
        /// <param name="ProcName">存储过程名</param>
        /// <param name="DataParas">存储过程参数集</param>
        /// <returns>返回:记录集 SqlDataReader</returns>
        protected SqlDataReader GetDataReader(string ProcName, DataParameters DataParas)
        {
            SqlCommand Cmd = new SqlCommand(ProcName, GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;

            // 遍历 存储过程参数集
            foreach (System.Collections.DictionaryEntry obj in DataParas.Parameters)
            {
                Cmd.Parameters.Add(obj.Key.ToString(), (SqlDbType)((object[])obj.Value)[0]).Value = ((object[])obj.Value)[1];
            }
            return Cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }

        /// <summary>
        /// 通过存储过程,获得数据集 DataTable
        /// </summary>
        /// <param name="tblName">要查询的表名</param>
        /// <param name="strGetFields">要查询的字段</param>
        /// <param name="strWhere">查询条件(注意:不要加 "where")</param>
        /// <param name="OrderSql">排序规则(注意:不要加 "order by",且不能为空)</param>
        /// <param name="PageSize">页大小 为0时,则不分页</param>
        /// <param name="PageIndex">页索引</param>
        /// <returns>返回:记录集 DataTable</returns>
        protected DataTable GetDataTable(string tblName, string strGetFields, string strWhere, string OrderSql, int PageSize, int PageIndex)
        {
            SqlCommand Cmd = new SqlCommand("P_Pagination", GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;
            Cmd.Parameters.Add("@tblName", SqlDbType.VarChar).Value = tblName;
            Cmd.Parameters.Add("@strGetFields", SqlDbType.VarChar).Value = strGetFields;
            Cmd.Parameters.Add("@strWhere", SqlDbType.VarChar).Value = strWhere;
            Cmd.Parameters.Add("@OrderSql", SqlDbType.VarChar).Value = OrderSql;
            Cmd.Parameters.Add("@PageSize", SqlDbType.Int).Value = PageSize;
            Cmd.Parameters.Add("@PageIndex", SqlDbType.Int).Value = PageIndex;
            Cmd.Parameters.Add("@doCount", SqlDbType.Bit).Value = false;
            SqlDataAdapter DA = new SqlDataAdapter(Cmd);
            DataTable DT = new DataTable();
            DA.Fill(DT);
            Cmd.Connection.Close();
            return DT;
        }

        /// <summary>
        /// 通过指定的存储过程名称,获取数据集 DataTable
        /// </summary>
        /// <param name="ProcName">存储过程名</param>
        /// <param name="DataParas">存储过程参数集</param>
        /// <returns>返回:记录集 DataTable</returns>
        protected DataTable GetDataTable(string ProcName, DataParameters DataParas = null)
        {
            SqlCommand Cmd = new SqlCommand(ProcName, GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;

            // 遍历 存储过程参数集
            if(DataParas != null)
            {
                foreach (System.Collections.DictionaryEntry obj in DataParas.Parameters)
                {
                    Cmd.Parameters.Add(obj.Key.ToString(), (SqlDbType)((object[])obj.Value)[0]).Value = ((object[])obj.Value)[1];
                }
            }
            SqlDataAdapter DA = new SqlDataAdapter(Cmd);
            DataTable DT = new DataTable();
            DA.Fill(DT);
            Cmd.Connection.Close();
            return DT;
        }

        /// <summary>
        /// 执行SQL查询语句,获取数据集 DataReader
        /// </summary>
        /// <param name="sqlTxt">要执行的SQL语句</param>
        /// <returns>返回:记录集 DataReader</returns>
        protected SqlDataReader GetDataReader(string sqlTxt)
        {
            SqlCommand Cmd = new SqlCommand(sqlTxt, GetConn());
            Cmd.CommandType = CommandType.Text;
            return Cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }

        /// <summary>
        /// 执行SQL查询语句,获取数据集 DataTable
        /// </summary>
        /// <param name="sqlTxt">要执行的SQL语句</param>
        /// <returns>返回:记录集 DataTable</returns>
        protected DataTable GetDataTable(string sqlTxt)
        {
            SqlCommand Cmd = new SqlCommand(sqlTxt, GetConn());
            Cmd.CommandType = CommandType.Text;
            SqlDataAdapter DA = new SqlDataAdapter(Cmd);
            DataTable DT = new DataTable();
            DA.Fill(DT);
            Cmd.Connection.Close();
            return DT;
        }

        /// <summary>
        /// 通过存储过程,获得数据集 总数
        /// </summary>
        /// <param name="tblName">要查询的表名</param>
        /// <param name="strWhere">查询条件</param>
        /// <returns>返回:记录集数量</returns>
        protected int GetDataCount(string tblName, string strWhere = "")
        {
            SqlCommand Cmd = new SqlCommand("P_Pagination", GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;
            Cmd.Parameters.Add("@tblName", SqlDbType.VarChar).Value = tblName;
            Cmd.Parameters.Add("@strGetFields", SqlDbType.VarChar).Value = "*";
            Cmd.Parameters.Add("@strWhere", SqlDbType.VarChar).Value = strWhere;
            Cmd.Parameters.Add("@OrderSql", SqlDbType.VarChar).Value = "";
            Cmd.Parameters.Add("@PageSize", SqlDbType.Int).Value = 0;
            Cmd.Parameters.Add("@PageIndex", SqlDbType.Int).Value = 1;
            Cmd.Parameters.Add("@doCount", SqlDbType.Bit).Value = true;
            int Result = (int)Cmd.ExecuteScalar();
            Cmd.Connection.Close();
            return Result;
        }

        /// <summary>
        /// 执行SQL查询语句,并返回数据集长度
        /// </summary>
        /// <param name="sqlTxt">要执行的SQL语句</param>
        /// <returns>返回:数据集长度</returns>
        protected int GetDataCount(string sqlTxt)
        {
            SqlCommand Cmd = new SqlCommand(sqlTxt, GetConn());
            Cmd.CommandType = CommandType.Text;
            SqlDataAdapter DA = new SqlDataAdapter(Cmd);
            DataTable DT = new DataTable();
            DA.Fill(DT);
            Cmd.Connection.Close();
            return DT.Rows.Count;
        }

        /// <summary>
        /// 执行查询语句,并返回第一行第一列数据
        /// </summary>
        /// <param name="SelectTxt">要执行的查询语句</param>
        /// <returns>返回查询结果集的第一行第一列数据</returns>
        protected object GetOnlyData(string SelectTxt)
        {
            SqlCommand Cmd = new SqlCommand(SelectTxt, GetConn());
            object Result = Cmd.ExecuteScalar();
            Cmd.Connection.Close();
            return Result;
        }

        /// <summary>
        /// 执行语句,并返回受影响的行数
        /// </summary>
        /// <param name="CmdTxt">要执行的 增、删、改 语句</param>
        /// <returns>返回受影响的行数</returns>
        protected int RunSqlCommand(string CmdTxt)
        {
            SqlCommand Cmd = new SqlCommand(CmdTxt, GetConn());
            int ExecuteCount = Cmd.ExecuteNonQuery();
            Cmd.Connection.Close();
            Cmd.Dispose();
            return ExecuteCount;
        }

        /// <summary>
        /// 执行存储过程,并返回存储过程执行结果(字符串)
        /// </summary>
        /// <param name="ProcName">存储过程名称</param>
        /// <param name="DataParas">存储过程参数集</param>
        /// <param name="HasResult">该存储过程是否有返回值</param>
        /// <returns>存储过程返回值</returns>
        protected ProcResultValue ExeProc(string ProcName, DataParameters DataParas, bool HasResult)
        {
            // 此处预留异常处理Try catch, 由Application获取并跳转异常页面。
            // 返回值
            ProcResultValue Result = new ProcResultValue();

            // 创建 Command
            SqlCommand Cmd = new SqlCommand(ProcName, GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;
            
            // 遍历 存储过程参数集
            foreach (System.Collections.DictionaryEntry obj in DataParas.Parameters)
            {
                Cmd.Parameters.Add(obj.Key.ToString(), (SqlDbType)((object[])obj.Value)[0]).Value = ((object[])obj.Value)[1];
            }

            // 创建返回参数
            if (HasResult)
            {
                Cmd.Parameters.Add("@Result", SqlDbType.NVarChar, -1);
                Cmd.Parameters["@Result"].Direction = ParameterDirection.Output;
            }

            //存储过程默认返回值  存储过程:Return
            Cmd.Parameters.Add("@Return", SqlDbType.Int);
            Cmd.Parameters["@Return"].Direction = ParameterDirection.ReturnValue;

            // 执行存储过程
            Cmd.ExecuteNonQuery();

            // 获得返回值
            if (HasResult)
                Result.ResultValueStr = Cmd.Parameters["@Result"].Value.ToString();
            Result.ReturnValueInt = (Cmd.Parameters["@Return"].Value is int ? (int)Cmd.Parameters["@Return"].Value : -1);

            // 关闭数据库链接
            Cmd.Connection.Close();

            // 在这里执行一些存储过程catch异常的操作
            if(Result.ReturnValueInt == -1)
            {

            }

            // 返回执行结果
            return Result;
        }

        /// <summary>
        /// 执行函数,并返回函数执行结果
        /// </summary>
        /// <param name="FuncName">函数名称</param>
        /// <param name="DataParas">函数参数集</param>
        /// <param name="ResultType">返回值类型</param>
        /// <returns>存储过程返回值</returns>
        protected object ExeFunc(string FuncName, DataParameters DataParas, SqlDbType ResultType)
        {
            // 返回值
            object Result = null;

            // 创建 Command
            SqlCommand Cmd = new SqlCommand(FuncName, GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;

            // 遍历 存储过程参数集
            foreach (System.Collections.DictionaryEntry obj in DataParas.Parameters)
            {
                Cmd.Parameters.Add(obj.Key.ToString(), (SqlDbType)((object[])obj.Value)[0]).Value = ((object[])obj.Value)[1];
            }

            // 创建返回参数
            Cmd.Parameters.Add("@Return", ResultType, -1);
            Cmd.Parameters["@Return"].Direction = ParameterDirection.ReturnValue;

            // 执行存储过程
            Cmd.ExecuteScalar();

            // 获得返回值
            Result = Cmd.Parameters["@Return"].Value;

            // 关闭数据库链接
            Cmd.Connection.Close();

            // 返回执行结果
            return Result;
        }
    }
}

第三步、上面对数据库访问封装方法有一个DataParameters传参对象,你没有想错,这个对象是自己封装的类,调用起来更加方便,请看下面代码

namespace Ant.DAL
{
    /// <summary>
    /// 数据库[存储过程、函数]参数类
    /// </summary>
    public class DataParameters
    {
        private Hashtable HT = new Hashtable(); // 存储过程参数表

        /// <summary>
        /// 数据库[存储过程、函数]参数类 构造函数
        /// </summary>
        public DataParameters()
        {
        }

        /// <summary>
        /// 数据库[存储过程、函数] 参数表
        /// </summary>
        public Hashtable Parameters
        {
            get
            {
                return HT;
            }
        }

        /// <summary>
        /// 添加数据库[存储过程、函数]的参数
        /// </summary>
        /// <param name="ParaName">参数名称</param>
        /// <param name="ParaType">参数类型</param>
        /// <param name="ParaValue">参数值</param>
        public void Add(string ParaName, SqlDbType ParaType, object ParaValue)
        {
            HT.Add(ParaName, new object[] { ParaType, ParaValue });
        }
    }
}

第四步、调用

/// <summary>
        /// (查询调用)根据条件查询系统操作对象数据
        /// </summary>
        /// <param name="sqlField">查询字段</param>
        /// <param name="sqlWhere">查询条件 注:不要加 Where</param>
        /// <param name="orderBy">排序 注:不要加 Order By</param>
        /// <param name="pageSize">页大小 大于等于 0</param>
        /// <param name="pageIndex">页码 大于等于 1</param>
        /// <returns>返回:SqlDataReader</returns>
        public SqlDataReader GetData(string sqlField, string sqlWhere, string orderBy, int pageSize, int pageIndex)
        {
            return base.GetDataReader("Base_Action", sqlField, sqlWhere, orderBy, pageSize, pageIndex);
        }

        /// <summary>
        /// (存储过程增删改调用)设置单条系统操作对象
        /// </summary>
        /// <param name="editSign">操作标识</param>
        /// <param name="ID">主键ID</param>
        /// <param name="Menu">类型ID(系统菜单ID、公共页面对象ID)</param>
        /// <param name="Name">名称:按钮/链接ID</param>
        /// <param name="Text">描述:按钮/连接名称</param>
        /// <returns>返回:操作结果 空/异常信息</returns>
        public ProcResultValue SetActionInfo(SetActionInfo_EditSign editSign, long ID, long Menu, string Name, string Text)
        {
            DataParameters DP = new DataParameters();
            DP.Add("@EditSign", System.Data.SqlDbType.Int, (int)editSign);
            DP.Add("@ID", System.Data.SqlDbType.BigInt, ID);
            DP.Add("@Menu", System.Data.SqlDbType.BigInt, Menu);
            DP.Add("@Name", System.Data.SqlDbType.VarChar, Name);
            DP.Add("@Text", System.Data.SqlDbType.NVarChar, Text);
            return base.ExeProc("P_Base_Action", DP, true);
        }        

 

asp.net/wingtip/创建数据访问层

asp.net/wingtip/创建数据访问层

一. 什么是数据访问层

在wingtip项目中,数据访问层是对以下三者的总称:
1. product类等数据相关的实体类(class)
2. 数据库(database),对实体类成员的存储
3. 上述二者的交互操作。

product类

 1 using System.ComponentModel.DataAnnotations;
 2 
 3 namespace WingtipToys.Models
 4 {
 5   public class Product
 6   {
 7     [ScaffoldColumn(false)]
 8     public int ProductID { get; set; }
 9 
10     [Required, StringLength(100), Display(Name = "Name")]
11     public string ProductName { get; set; }
12 
13     [Required, StringLength(10000), Display(Name = "Product Description"), DataType(DataType.MultilineText)]
14     public string Description { get; set; }
15 
16     public string ImagePath { get; set; }
17 
18     [Display(Name = "Price")]
19     public double? UnitPrice { get; set; }
20 
21     public int? CategoryID { get; set; }
22 
23     public virtual Category Category { get; set; }
24   }
25 }
View Code

database(T-SQL)

 1 CREATE TABLE [dbo].[Products] (
 2     [ProductID]   INT            IDENTITY (1, 1) NOT NULL,
 3     [ProductName] NVARCHAR (100) NOT NULL,
 4     [Description] NVARCHAR (MAX) NOT NULL,
 5     [ImagePath]   NVARCHAR (MAX) NULL,
 6     [UnitPrice]   FLOAT (53)     NULL,
 7     [CategoryID]  INT            NULL,
 8     CONSTRAINT [PK_dbo.Products] PRIMARY KEY CLUSTERED ([ProductID] ASC),
 9     CONSTRAINT [FK_dbo.Products_dbo.Categories_CategoryID] FOREIGN KEY ([CategoryID]) REFERENCES [dbo].[Categories] ([CategoryID])
10 );
11 
12 
13 GO
14 CREATE NONCLUSTERED INDEX [IX_CategoryID]
15     ON [dbo].[Products]([CategoryID] ASC);
View Code

 


二. 让实体类与数据库开始交流

创建好了product类以及对应的数据库,我们接下来要让将二者使用起来。首先是上下文类(context class),这个类负责管理实体类(如product类、category类),并且提供对数据库的访问操作。

productContext类

 1 using System.Data.Entity;
 2 namespace WingtipToys.Models
 3 {
 4   public class ProductContext : DbContext
 5   {
 6     public ProductContext()
 7       : base("WingtipToys")
 8     {
 9     }
10 
11     public DbSet<Category> Categories { get; set; }
12     public DbSet<Product> Products { get; set; }
13     public DbSet<CartItem> ShoppingCartItems { get; set; }
14     public DbSet<Order> Orders { get; set; }
15     public DbSet<OrderDetail> OrderDetails { get; set; }
16 
17   }
18 }
View Code

 在程序第一次运行的时候,数据库虽然已经建立好了数据表,但这是一个空表,如何给这个数据表添加一些数据呢?建立一个ProductDatabaseInitializer类

ProductDatabaseInitializer类:

  1 using System.Collections.Generic;
  2 using System.Data.Entity;
  3 
  4 namespace WingtipToys.Models
  5 {
  6   public class ProductDatabaseInitializer : DropCreateDatabaseIfModelChanges<ProductContext>
  7   {
  8     protected override void Seed(ProductContext context)
  9     {
 10       GetCategories().ForEach(c => context.Categories.Add(c));
 11       GetProducts().ForEach(p => context.Products.Add(p));
 12     }
 13 
 14     private static List<Category> GetCategories()
 15     {
 16       var categories = new List<Category> {
 17                 new Category
 18                 {
 19                     CategoryID = 1,
 20                     CategoryName = "Cars"
 21                 },
 22                 new Category
 23                 {
 24                     CategoryID = 2,
 25                     CategoryName = "Planes"
 26                 },
 27                 new Category
 28                 {
 29                     CategoryID = 3,
 30                     CategoryName = "Trucks"
 31                 },
 32                 new Category
 33                 {
 34                     CategoryID = 4,
 35                     CategoryName = "Boats"
 36                 },
 37                 new Category
 38                 {
 39                     CategoryID = 5,
 40                     CategoryName = "Rockets"
 41                 },
 42             };
 43 
 44       return categories;
 45     }
 46 
 47     private static List<Product> GetProducts()
 48     {
 49       var products = new List<Product> {
 50                 new Product
 51                 {
 52                     ProductID = 1,
 53                     ProductName = "Convertible Car",
 54                     Description = "This convertible car is fast! The engine is powered by a neutrino based battery (not included)." + 
 55                                   "Power it up and let it go!", 
 56                     ImagePath="carconvert.png",
 57                     UnitPrice = 22.50,
 58                     CategoryID = 1
 59                },
 60                 new Product 
 61                 {
 62                     ProductID = 2,
 63                     ProductName = "Old-time Car",
 64                     Description = "There''s nothing old about this toy car, except it''s looks. Compatible with other old toy cars.",
 65                     ImagePath="carearly.png",
 66                     UnitPrice = 15.95,
 67                      CategoryID = 1
 68                },
 69                 new Product
 70                 {
 71                     ProductID = 3,
 72                     ProductName = "Fast Car",
 73                     Description = "Yes this car is fast, but it also floats in water.",
 74                     ImagePath="carfast.png",
 75                     UnitPrice = 32.99,
 76                     CategoryID = 1
 77                 },
 78                 new Product
 79                 {
 80                     ProductID = 4,
 81                     ProductName = "Super Fast Car",
 82                     Description = "Use this super fast car to entertain guests. Lights and doors work!",
 83                     ImagePath="carfaster.png",
 84                     UnitPrice = 8.95,
 85                     CategoryID = 1
 86                 },
 87                 new Product
 88                 {
 89                     ProductID = 5,
 90                     ProductName = "Old Style Racer",
 91                     Description = "This old style racer can fly (with user assistance). Gravity controls flight duration." + 
 92                                   "No batteries required.",
 93                     ImagePath="carracer.png",
 94                     UnitPrice = 34.95,
 95                     CategoryID = 1
 96                 },
 97                 new Product
 98                 {
 99                     ProductID = 6,
100                     ProductName = "Ace Plane",
101                     Description = "Authentic airplane toy. Features realistic color and details.",
102                     ImagePath="planeace.png",
103                     UnitPrice = 95.00,
104                     CategoryID = 2
105                 },
106                 new Product
107                 {
108                     ProductID = 7,
109                     ProductName = "Glider",
110                     Description = "This fun glider is made from real balsa wood. Some assembly required.",
111                     ImagePath="planeglider.png",
112                     UnitPrice = 4.95,
113                     CategoryID = 2
114                 },
115                 new Product
116                 {
117                     ProductID = 8,
118                     ProductName = "Paper Plane",
119                     Description = "This paper plane is like no other paper plane. Some folding required.",
120                     ImagePath="planepaper.png",
121                     UnitPrice = 2.95,
122                     CategoryID = 2
123                 },
124                 new Product
125                 {
126                     ProductID = 9,
127                     ProductName = "Propeller Plane",
128                     Description = "Rubber band powered plane features two wheels.",
129                     ImagePath="planeprop.png",
130                     UnitPrice = 32.95,
131                     CategoryID = 2
132                 },
133                 new Product
134                 {
135                     ProductID = 10,
136                     ProductName = "Early Truck",
137                     Description = "This toy truck has a real gas powered engine. Requires regular tune ups.",
138                     ImagePath="truckearly.png",
139                     UnitPrice = 15.00,
140                     CategoryID = 3
141                 },
142                 new Product
143                 {
144                     ProductID = 11,
145                     ProductName = "Fire Truck",
146                     Description = "You will have endless fun with this one quarter sized fire truck.",
147                     ImagePath="truckfire.png",
148                     UnitPrice = 26.00,
149                     CategoryID = 3
150                 },
151                 new Product
152                 {
153                     ProductID = 12,
154                     ProductName = "Big Truck",
155                     Description = "This fun toy truck can be used to tow other trucks that are not as big.",
156                     ImagePath="truckbig.png",
157                     UnitPrice = 29.00,
158                     CategoryID = 3
159                 },
160                 new Product
161                 {
162                     ProductID = 13,
163                     ProductName = "Big Ship",
164                     Description = "Is it a boat or a ship. Let this floating vehicle decide by using its " + 
165                                   "artifically intelligent computer brain!",
166                     ImagePath="boatbig.png",
167                     UnitPrice = 95.00,
168                     CategoryID = 4
169                 },
170                 new Product
171                 {
172                     ProductID = 14,
173                     ProductName = "Paper Boat",
174                     Description = "Floating fun for all! This toy boat can be assembled in seconds. Floats for minutes!" + 
175                                   "Some folding required.",
176                     ImagePath="boatpaper.png",
177                     UnitPrice = 4.95,
178                     CategoryID = 4
179                 },
180                 new Product
181                 {
182                     ProductID = 15,
183                     ProductName = "Sail Boat",
184                     Description = "Put this fun toy sail boat in the water and let it go!",
185                     ImagePath="boatsail.png",
186                     UnitPrice = 42.95,
187                     CategoryID = 4
188                 },
189                 new Product
190                 {
191                     ProductID = 16,
192                     ProductName = "Rocket",
193                     Description = "This fun rocket will travel up to a height of 200 feet.",
194                     ImagePath="rocket.png",
195                     UnitPrice = 122.95,
196                     CategoryID = 5
197                 }
198             };
199 
200       return products;
201     }
202   }
203 }
View Code

当数据库被创建并且初始化的时候,执行了该类的Seed()方法。这个方法在该类中,是对基类中Seed()方法的重写。执行结束后,数据库中就被填充了类别和产品两类数据。


三. 让web前台使用他们

在web应用启动的时候,为了能够使用我们前边创建好的各个类、数据库、操作逻辑等等,我们需要更新在Global.asax.cs中的Application_Start方法(handler)。

using WingtipToys.Models;
using WingtipToys.Logic;

namespace WingtipToys
{
    public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            // Code that runs on application startup
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            // Initialize the product database.(此处为方法的更新)
            Database.SetInitializer(new ProductDatabaseInitializer());

            // Create the custom role and user.
            RoleActions roleActions = new RoleActions();
            roleActions.AddUserAndRole();

            // Add Routes.
            RegisterCustomRoutes(RouteTable.Routes);
        }
       ...
       ...其他代码省略...
       ...
     }
}

在web应用启动时,在第一次访问数据的时候(product data),程序会执行指定方法(initializer)来生成数据。

 

四. 总结

这一章就写这么多,主要是在数据和数据操作层面解释了什么是所谓的“数据访问层”。通过上述三个小节可以看到,“数据访问层”是对实体类(class)、数据库(database,table)、方法(method)的一个统称。对于实体类这样的.cs文件,我们将他们存放在Models文件夹下,也即给他们扣个帽子,“模型”指的就是他们。

我们今天的关于Spring Data JPA如何提供数据访问接口而不是休眠数据访问层spring data jpa调用存储过程的分享就到这里,谢谢您的阅读,如果想了解更多关于(六)SpringBoot与数据访问、.net数据访问层组件Data Abstract下载及介绍、ASP.NET 一个数据访问层的封装、asp.net/wingtip/创建数据访问层的相关信息,可以在本站进行搜索。

本文标签: