你还在用传统的JDBC持久化访问吗?

前言

这里我会采用mybatis3.2做数据库的持久化,很多小伙伴或许还停留在老师的教导下,仍然停留在使用传统的JDBC持久化访问数据层。今天,我们来聊聊面向接口编程和怎么充分利用注解的优势!

配图.jpg

实现DAO持久层

从目前的Java框架趋势来看,spring框架仍旧占据主流,不论你使用SSH框架和SSM框架开发,必透彻spring是无可厚非的。

从目前互联网公司的分布来看,中小型公司仍旧拥有半壁江山,它们没有雄厚的资金和开发资源,也就是说极少有公司会使用hibernate+struts开发项目,对中小型公司来说开发超大型项目是不在它们的考虑范围之内的。那么,mybatis+springmvc开发框架就此兴起...

闲聊结束,我先说说原理吧:
使用mybatis定义接口完成sql语句的映射,该接口还可以直接作为DAO的组件使用。

桥接模式知道吗?
桥接模式在这里的应用:
使用该模式能够体现业务逻辑组件封装DAO组件的模式,也可以分离业务逻辑组件和DAO组件的功能。也就是说,业务逻辑组件负责业务逻辑的变化,而DAO组件负责持久化的变化。


这样做的好处:
①每个DAO组件包含了数据库的访问逻辑。
②每个DAO组件可对一个数据表完成基本的CRUD等操作。

1.公共常量类

HrmConstants 类

/**
 * 
 * 常量
 *
 */
public class HrmConstants {

    //数据库表常量
    public static final String USERTABLE="user_inf";
    public static final String DEPTTABLE="dept_inf";
    public static final String JOBTABLE="job_inf";
    public static final String EMPLOYEETABLE="employee_inf";
    public static final String NOTICETABLE="notice_inf";
    public static final String DOCUMENTTABLE="document_inf";
    
    //登录
    public static final String LOGIN="loginFrom";
    //用户的session对象
    public static final String USER_SESSION="user_session";
    //默认每页4条数据
    public static int PAGE_DEFAULT_SIZE=4;
    
}

这里数据库我就不贴出来了。这个公共常量类根据数据库表的结构定义得,也就是说在数据库里面我一共创建了6个表,每个表和此类是一一对应的。至于这里的session对象,是为了后期编写控制层所铺垫的,与本次所讲内容无影响噢。

2.实体类

/**
 * 
 * 用户实体类
 *
 */
public class User {

    private Integer id;//id
    private String username;//用户名
    private String loginname;//登录名
    private String password;//密码
    private Integer status;//状态
    private Date createDate;//建档日期
    
    public User() {
    }

    //setter和getter方法
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getLoginname() {
        return loginname;
    }

    public void setLoginname(String loginname) {
        this.loginname = loginname;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }
    
}

这里,我会以用户实体类做一个案例介绍。实体类的基本准则就是遵循javabean规则,也就是常说的公有的类、私有的成员变量以及自带一个无参的构造方法。当然,这里我用了setter和getter方法对其进行了简单的封装。

3.定义DAO接口

/**
 * 
 * UserDao的接口实现类
 *
 */
public interface UserDao {

    //登录用户名和密码查询员工
    @Select("select * from "+USERTABLE+" where loginname = #{loginname} and password = #{password} ")
    User selectByLoginnmameAndPassword(
            @Param("loginname") String loginname,
            @Param("password") String password
            );
    
    //根据Id查询用户
    @Select("select * from "+USERTABLE+" where id = #{id} ")
    User selectById(Integer id);
    
    //根据Id删除用户
    @Delete("delete from "+USERTABLE+" where id = #{id} ")
    void deleteById(Integer id);
    
    //动态修改用户
    @SelectProvider(method = "updateUser", type = UserDynaSqlProvider.class)
    void update(User user);
    
    //动态查询
    @SelectProvider(method = "selectWhitParam", type = UserDynaSqlProvider.class)
    List<User> selectByPage(Map<String, Object> params);
    
    //根据参数查询用户总数
    @SelectProvider(method = "count", type = UserDynaSqlProvider.class)
    Integer count(Map<String, Object> params);
    
    //动态插入用户
    @SelectProvider(method = "inserUser", type = UserDynaSqlProvider.class)
    void save(User user);
    
}

这里才是真正的开始升华了,首先我只定义了一个 UserDao的接口,然后充分利用mybatis的注解优势,定义了'登录用户名和密码查询员工'的方法......
这里为大家补充一下注解知识:

@Select注解,这个不用解释了吧,就相当于存放查询语句的一个注解,定义在某一个方法上,效果相当于在配置文件里面编写查询语句。

@Param注解,是对参数的解释。这里用的 string loginname是前面在公共常量类里面定义的。怎么说呢,我们可以理解成request.setAttribute("","")这种形式的升华吧。

@SelectProvider注解,用于生成查询用的sql语句,有别于@Select注解。结构上看,@SelectProvide指定了一个Class及其方法,通过调用Class上的这个方法来获得sql语句。


注意事项:
①这里的@Param注解是基于mybatis框架的,不是spring框架上的,导入包的时候要注意哟!
②@SelectProvider注解在编程的思维上有一个跨度,因为它本身需要一个class和其方法,所以在定义这个注解的时候,务必思考好下一个层次结构里面的类和方法所需要做的事哦!当然,在接口里面的方法,是可以事先预算好的,但是在它上面的注解,就要多思考思考才能做决定哦!
③公共常量类。在此接口的运用上,既然是面向接口编程,还要完成数据库的基本操作,那么是一定要导入公共常量类里面的USERTABLE的。
④id = #{id} 生成的sql语句是 id = ?

4.动态SQL提供类

public class UserDynaSqlProvider {

    //分页动态查询
    public String selectWhitParam(final Map<String, Object> params) {
        String sql=new SQL(){
            {
                SELECT("*");
                FROM(USERTABLE);
                if (params.get("user")!=null) {
                    User user=(User) params.get("user");
                    if (user.getUsername()!=null && !user.getUsername().equals("")) {
                        WHERE(" username LIKE CONCAT('%',#{user.username},'%') ");
                    }
                    if (user.getStatus()!=null && !user.getStatus().equals("")) {
                        WHERE(" status LIKE CONCAT('%',#{user.status},'%') ");
                    }
                }
            }
        }.toString();
        if (params.get("pageModel")!=null) {
            sql += " limit #{pageModel.firstLimitParam} , #{pageModel.pageSize} ";
        }
        return sql;
    }
    
    //动态查询总数量
    public String count(final Map<String, Object> params) {
        return new SQL(){
            {
                SELECT("*");
                FROM(USERTABLE);
                if (params.get("user") !=null) {
                    User user=(User) params.get("user");
                    if (user.getUsername()!=null && !user.getUsername().equals("")) {
                        WHERE(" username LIKE CONCAT('%',#{user.username},'%') ");
                    }
                    if (user.getStatus()!=null && !user.getStatus().equals("")) {
                        WHERE(" status LIKE CONCAT('%',#{user.status},'%') ");
                    }
                }
            }
        }.toString();
    }
    
    //动态插入
    public String inserUser(final User user) {
        return new SQL(){
            {
                INSERT_INTO(USERTABLE);
                if (user.getUsername()!=null && !user.getUsername().equals("")) {
                    VALUES("username", "#{username}");
                }
                if (user.getStatus()!=null && !user.getStatus().equals("")) {
                    VALUES("status", "#{status}");
                }
                if (user.getLoginname()!=null && !user.getLoginname().equals("")) {
                    VALUES("loginname", "#{loginname}");
                }
                if (user.getPassword()!=null && !user.getPassword().equals("")) {
                    VALUES("password", "#{password}");
                }
            }
        }.toString();
    }
    
    //动态更新
    public String updateUser(final User user) {
        return new SQL(){
            {
                UPDATE(USERTABLE);
                if (user.getUsername()!=null) {
                    SET(" username = #{username} ");
                }
                if (user.getLoginname()!=null) {
                    SET(" loginname = #{loginname} ");
                }
                if (user.getPassword()!=null) {
                    SET(" password = #{password} ");
                }
                if (user.getStatus()!=null) {
                    SET(" status = #{status} ");
                }
                if (user.getCreateDate()!=null) {
                    SET(" create_date = #{createDate} ");
                }
                WHERE(" id = #{id} ");
            }
        }.toString();
    }
}

正如前面编写接口类的时候所说,既然用了@SelectProvider注解,必然会使用到一个class和它的方法。我们在接口类里面用了四次@SelectProvider注解,那么与之对应的就应该有四个方法,分别是分页动态查询(selectWhitParam)、动态查询总数量(count)、动态插入(inserUser)、动态更新(updateUser)。

这个类是专门为接口提供sql语句服务的,不再需要传统的去实现接口,用注解代替了原本繁琐的事情。

ps:或许有人会疑惑,我们怎么把所写的配置在applicationContext.xml里面呢?会不会很麻烦?现在,我告诉你,一点也不麻烦哦!

配置文件

applicationContext.xml

<!-- mybatis:scan 会扫描com.dao.inter包下面的所有接口当作spring的bean配置,之后可以进行依赖注入 -->
    <mybatis:scan base-package="com.dao.inter"/>
    <!-- 使用PropertyOverrideConfigurer后处理器加载数据源参数 -->
    <context:property-override location="classpath:db.properties" />
    <!-- 配置c3p0数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.CombopooledDataSource "/>
    <!-- 配置sqlSessionFactory。org.mybatis.spring.SqlSessionFactoryBean是mybatis社区开发用于整合Spring的bean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref="dataSource"/>

db.properties

dataSource.driverClass=com.mysql.jdbc.Driver
dataSource.jdbcUrl=jdbc:mysql://127.0.0.1:3306/hrm_db
dataSource.user=root
dataSource.password=root
dataSource.maxPoolSize=20
dataSource.maxIdleTime=1000
dataSource.minPoolSize=6
dataSource.initialPoolSize=5

原理:mybatis的持久化DAO接口只需要通过SqlSession的getMapper方法获得对应的接口实例,从而达到调用接口方法完成数据库的操作,而在spring容器里,只负责生成和管理DAO的组件。


看完了?那么大家觉得是不是要比传统的JDBC持久化访问要简单些呢?我想,至少也要方便一些吧。

如果大家觉得我写的对你有帮助,请顺手点个赞支持一下呗;如果大家觉得我有写的不对的地方,欢迎大家多多发言。谢谢!

转载请注明作者及文章出处噢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,511评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,495评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,595评论 0 225
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,558评论 0 190
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,715评论 3 270
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,672评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,112评论 2 291
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,837评论 0 181
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,417评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,928评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,316评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,773评论 2 234
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,253评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,827评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,440评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,523评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,583评论 2 249

推荐阅读更多精彩内容

  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,246评论 0 4
  • 这部分主要是开源Java EE框架方面的内容,包括Hibernate、MyBatis、Spring、Spring ...
    杂货铺老板阅读 1,264评论 0 2
  • 1 引言# 本文主要讲解JDBC怎么演变到Mybatis的渐变过程,重点讲解了为什么要将JDBC封装成Mybait...
    七寸知架构阅读 76,058评论 36 982
  • 朋友在创业阶段,有天对我说:“明明我已经什么事都计划好了,也按计划在做了,为什么反而提不起精神,还有点懒散,没...
    Flora陆丽辉阅读 430评论 2 10
  • 1.不要轻易放弃一个每天都会想念的人,这样的人,一辈子也不会遇到几个。 2.每个人心里,都住着这么一个人,遥远的爱...
    曲歌阅读 509评论 1 4