微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring Boot专栏六:JDBC的简单使用

Spring Boot专栏六:JDBC的简单使用


本节专栏我们来介绍JDBC的简单使用

什么是JDBC

如果想完整充分学习JDBC,可以参考大佬们的博客,比如:学JDBC,这一篇就够了

在这里拾人牙慧,冒昧地援引一下:

JDBC 规范定义接口,具体的实现由各大数据库厂商来实现。
JDBC 是 Java 访问数据库的标准规范,真正怎么操作数据库还需要具体的实现类,也就是数据库驱动。每个
数据库厂商根据自家数据库的通信格式编写好自己数据库的驱动。所以我们只需要会调用 JDBC 接口中的方法即可,数据库驱动由数据库厂商提供。
使用 JDBC 的好处:

  1. 程序员如果要开发访问数据库的程序,只需要会调用 JDBC 接口中的方法即可,不用关注类是如何实现的。
  2. 使用同一套 Java 代码,进行少量的修改就可以访问其他 JDBC 支持数据库

简单来说,JDBC的全称是Java Database connectivity,也就是Java访问、使用数据库一个接口(连接的口,不是interface那个接口),我们只需要按照sql语言的规则写出来,数据库,比如MysqL,就会自动替我们去执行操作。

xxxDao.xml的内容怎么写

专栏第四节粗略地讲了xml文件内容怎么写,本节具体地来介绍一下。

xml头部的内容

在专栏第四节中,我们提到了xml文件的头两行应该这么写:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

这个是固定死的,除非xml或者mybatis等的版本变化了,否则我们就是这么写。以后我们写其他的xxxDao.xml文件,只要复制这段话就行了。

mapper对的内容

在专栏第四节中,xml文件的主要内容包括一个mapper对<mapper> </mapper>中:

<mapper namespace="com.example.demo.dao.UserDao">

    <select id="show_user_all" resultType="com.example.demo.entity.User">
        select *
        from user__
    </select>

    <select id="show_user_by_user_name" parameterType="String" resultType="com.example.demo.entity.User">
        select user_name, user_password, register_time, login_time
        from user__
        where user_name=#{user_name}
    </select>

</mapper>

其中,mapper对有个参数namespace,它代表该xml文件对应哪个Dao.java文件吗。第四节中也提到了,这句话是找到对应Dao的关键。
其他的两个select对,就是和JDBC有关了,我们看下一节

使用JDBC手写sql语句

本小节的内容基于大家有基本的sql语句基础。在Spring Boot中,一般把JDBC语言写到xml文件中,方便日后维护。下面我们来讲解如何写sql语句,这里我们只讲增删查改四类语句,不涉及add, alert, drop等语句。

增insert

增 insert,首先我们要在xml的语句对的开头写<insert …>,在对结束的时候写</insert>.
在<insert …>中,有这么几个重要的参数:

  1. id:这个参数不止是insert有,其他的删改查也都有,是用来对应Dao.java文件中的方法名称——所以这部分一定要注意,如果对不上,就会报错;
  2. useGeneratedKeys:是否自动生成主键。这个地方挺坑的,我研究了挺久。
    先说一下这个参数怎么用:当它的值为"true"时,数据库认将数据表中的第一列、第一个属性当作主键,进行自增;如果不想认的话,可以通过修改keyProperty和keyColumn这两个参数,来指定主键。
    但是自动生成主键,只对MysqL等几种数据库适用,大部分还是不适用的。另外,自动设置主键,需要我们在MysqL关闭自动生成主键”(通过navicat可以设置)——听起来就很晕乎,所以我建议,大家把useGeneratedKeys设置为"false",keyProperty和keyColumn这两个参数都不用,并且在增加数据的时候,把主键也当作要插入的一个值,加进去。
    有同学会问了,新增一个用户,怎么能知道这个用户的id?这就需要我们先去查找当前最大的user_id,记为max_id,然后令新用户的id为max_id+1即可(这个sql语句我放到查询语句的写法中讲)。或者如果大家已经在navicat中对user_id设置了“自动递增”,那么就可以不用管user_id这个属性了,navicat软件自动帮我们递增了。

接下来我们看一下一个实例,如何在用户表中插入一个新的用户,在给定user_id(通过上述方法取得), user_name, user_phone, user_password, user_wallet, register_time, login_time的情况下:

<insert id="add_user" useGeneratedKeys="false">
	insert into
	user_ (user_id, user_name, user_phone, user_password, user_wallet, register_time, login_time)
	values (#{user_id}, #{user_name}, #{user_phone}, #{user_password}, #{user_wallet}, #{register_time}, #{login_time})
</insert>

此时在UserDao.java接口中,应该有一个如下的方法,与上述xml语句对应:

int add_user(@Param("user_id") int user_id, @Param("user_name") String user_name,
	@Param("user_phone") String user_phone, @Param("user_password") String user_password,
	@Param("user_wallet") double user_wallet, @Param("register_time") String register_time,
	@Param("login_time") String login_time);

UserService.java和UserServiceImple.java中应该也有对应的代码,留给大家当作作业,我会上传代码到github上去,大家可以参考。

最后,注意一下insert语句的返回值,是int型的,它表示向数据库中成功插入了多少条记录;若插入失败,返回0。

删delete

删delete,首先我们要在xml的语句对的开头写<delete…>,在对结束的时候写</delete>.
在<delete…>中,有这么几个重要的参数:

  1. id:同insert中的介绍;
  2. parameterType:对于删改查三种操作,如果Dao.java中的方法中有且只一个输入,那么可以添加一个参数parameterType,用来表示该输入的类型。我们一会用基本数据类型和字符串做个演示,复杂的类型一会再作说明。

接下来我们用两个实例来说明,第一个是根据user_id来删除用户,第二个是根据user_name来删除

<delete id="delete_user_by_user_id" parameterType="int">
	delete from
	user_
	where user_id=#{user_id}
</delete>

<delete id="delete_user_by_user_name" parameterType="String">
	delete from
	user_
	where user_name=#{user_name}	
</delete>

对应UserDao.java接口中的两个方法

int delete_user_by_user_id(@Param("user_id") int user_id);
int delete_user_by_user_name(@Param("user_name") String user_name);

delete语句的返回值,也是int型的,它表示向数据库中成功删除了多少条记录;若一条都没有删除,返回0。

改 update

改 update,首先我们要在xml的语句对的开头写<update…>,在对结束的时候写</update>.
在<update…>中的参数同<delete …>。但一般用不到parameterType,原因也好理解:update语句中需要set 某某等于某某,且where 某某等于某某,也就是说一般会有两个参数,所以parameterType用到得不多。

接下来我们用两个实例来说明,第一个修改用户名,第二个是进行充值,二者都是基于user_id进行修改的:

<update id="update_user_name_by_user_id">
	update
	user_
	set user_name=#{user_name}
	where user_id=#{user_id}
</update>

<update id="update_user_wallet_by_user_id">
	update
	user_
	set user_wallet=#{user_wallet}
	where user_id=#{user_id}
</update>

对应UserDao.java接口中的两个方法

int update_user_name_by_user_id(@Param("user_id") int user_id, @Param("user_name") String user_name);
int update_user_wallet_by_user_id(@Param("user_id") int user_id, @Param("user_wallet") double user_wallet);

这里有同学可能会有疑问,第二个方法不是说好了是要充值吗,那不就是要在原余额数上加一个数吗,怎么变成了赋值?我是这么考虑的,因为还有支付这个功能,这二者都是对user_wallet进行操作。如果我把它写成一个方法,同时在controller层写方法时,提前计算好充值或支付后的余额,进行修改操作,这样节省了代码量。如果有朋友认为这两个功能应该分开来写,也是有道理的,功能原子化嘛,各有各的道理,这就看写项目时,项目经理怎么考虑了。

update语句的返回值,也是int型的,它表示向数据库中成功更改了多少条记录;若一条都没有更改,返回0。

查 select

查 select,首先我们要在xml的语句对的开头写<select…>,在对结束的时候写</select>.
在<select…>中的参数有三个:

  1. id:同delete中的介绍
  2. parameterType:同delete中的介绍
  3. resultType:这个是select独有的一个参数,代表返回值的类型(其他三类的返回值都为int),这个是一个必选项,因为无论你想让数据库返回的是一个属性还是多个属性,都可以用java中的基本数据类型或包装类或一个自定义的类来记录下来,肯定能对应上一个返回值类型
    接下来我们演示的几个案例,都是返回值为简单数据类型,复杂的返回值类型,我放到下面几个小节来讲。

接下来我们用两个实例来说明,第一个查询当前最大的用户id,第二个是查询某个用户的钱包余额(根据用户id):

<select id="select_max_user_id" resultType="int">
	select max(user_id)
	from user_
</select>

<select id="select_user_wallet_by_user_id" parameterType="int" resultType="double">
	select user_wallet
	from user_
	where user_id=#{user_id}
</select>

对应UserDao.java接口中的两个方法

int select_max_user_id();
double select_user_wallet_by_user_id(@Param("user_id") int usre_id);

返回值为一个类/对象

显然,这种情况只会在select语句中出现。除非是java.lang中的类,否则我们要写清楚该类的具体位置。我们之前就遇到过这种例子,根据用户id查询用户的一些信息:

<select id="show_user_by_user_name" parameterType="String" resultType="com.example.demo.entity.User">
	select user_name, user_password, register_time, login_time
	from user_
	where user_name=#{user_name}
</select>

可以看到我们在resultType中写的是"com.example.demo.entity.User"。注意,在这种情况下,要在类中添加对应的构造方法

输入为一个类/对象

这种情况可以在任何一种sql语句中出现,由于此时的输入往往只有一个,因此一般需要添加parameterType参数(insert语句除外),写的方法和上述“返回值为一个类/对象”相同。
下面介绍一个根据用户名修改用户密码的sql语句,其中输入为一个User类:

<update id="update_user_name_by_user_id_Class" parameterType="com.example.demo.entity.User">
	update
	user_
	set user_password=#{user.user_password}
	where user_name=#{user.user_name}
</update>

注意这种情况下sq语句的写法,尤其是user_password=#{user.user_password}和user_name=#{user.user_name}

对应UserDao.java接口中的方法

int update_user_name_by_user_id_Class(@Param("user") User user);

返回值为一个列表、数组

首先,我建议大家将所有的数组转化为列表,这样方便进行操作,因为在java中列表毕竟是一个类,而数组不是。
然后,当返回值是一个列表时,我们不必刻意做改变。我们之前就遇到过这种例子,查询所有用户的所有信息:

<select id="show_user_all" resultType="com.example.demo.entity.User">
	select *
	from user_
</select>

resultType仍然是类,JDBC如果收到多个输出,就会自动帮我们包装成列表。

输入为一个列表、数组

这里依然建议大家用列表。
输入如果仅有列表时,那么就需要用到parameterType参数,且参数值填为:java.util.List
另外,在sql语句中使用列表时,也需要做更改,下面我们举一个根据用户id数组查询用户名的用例:

<select id="select_user_name_list_by_user_id_list" parameterType="java.util.List" resultType="String">
        select user_name
        from user_
        where
        <foreach collection="user_id_list" item="item" index="index" separator="or">
            user_id=#{item}
        </foreach>
    </select>

注意在where子句中加了一个<foreach …></foreach>对,其中的colleaction参数对应Dao类方法中@Param参数,item与index就按照我这里写的就行,separator参数的值表示用什么字符串来分割<foreach …></foreach>对中的内容,在where子句中当然是用or来分割,因为我们要写成user_id=1 or user_id=2这样的。如果是update中的set子句,那么要用,来分割……这部分大家自己理解。
在user_id=#{item}中要写item,表示那个元素是遍历了列表的每个元素

对应UserDao.java接口中的方法

List<String> select_user_name_list_by_user_id_list(@Param("user_id_list") List<Integer> user_id_list);

返回值选择基本属性还是包装类

返回值可以是int, double等基本数据结构,也可以是Integer, Double等包装类。在使用JDBC中,正常情况下它们的返回值是一样的;但是,如果搜索到的结果为空,那么

  1. 如果返回值为基本数据结构,则返回该基本数据结构的初始化值,比如int返回0,double返回0.0;
  2. 如果返回值为包装类,则返回null;

注意小于号<和大于号>

最后要注意的是,在xml语句中,不能用<表示小于,不能用>表示大于,因为它认这两个符号表示<select>等中的“对”。
所以如果我们要在sql语句中比较大小,要将<表示成"&lt;",>表示成"&gt;",其意义分别为less than和greater than.
要表示小于等于、大于等于、不等于也很简单,分别是:"&lt;=", “&gt;=”, “&lt;&gt;”

本节专栏的内容到此结束,为了方便大家拷贝代码,我已经将我的项目放到了github上,项目地址为https://github.com/DTSSDUTDeepLearning/Spring-Boot-Dante,有需求的朋友们自行前往,目前网站还不完善,请大家包涵,后期我会抓紧时间完善。

谢谢大家的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐