接口:API。 规范。 定义方法签名。
接口和抽象了的意义上的区别。
抽象类是类,抽象类的目的就是让其他类来继承的。 只要继承从意义上来说就要说通 is a。
接口更趋向于功能。希望某一个类有接口指定的功能,就让这个类实现这个接口。
实现
接口属于java的语言的四大类型之一,而且是非常重要的类型。
语法:
public interface 接口名{
常量
抽象方法
默认方法(JKD1.8开始才有)
}
实例:
public interface Ink {
//常量
public static final int WIDTH = 15;
//在接口中定义一个成员变量,则默认使用 public static final -->常量
int HEIGHT = 20;
//方法默认就是public abstract修饰
public abstract void methodA();
//默认就是抽象方法
void methodB();
//jdk 1.8开始有了默认方法
default void methodC(){
System.out.println("默认方法C");
}
default void methodD(){
System.out.println("默认方法D");
}
}
接口中的普通的方法都默认是抽象方法。
接口不能被实例化(直接创建接口对象)。
接口中所有的成员变量默认都是常量。(必须有初始值,不可以改变)
接口中可以有默认方法(1.8)。默认方法可以有方法体。默认方法都是使用default修饰。
接口的实现
我们可以使用任何一类实现一个接口。当然这个类也可以是抽象类。
如果一个类实现了一个接口,就默认继承了这个接口的默认方法。
如果这个类不是抽象了,则这个类必须实现接口中所有的抽象方法。
如果这个类是抽象类,则可以选择实现接口中的 抽象方法。
非抽象类实现接口:
public class ColorInk implements Ink {
抽象类实现接口:
public abstract class OtherInk implements Ink{
public void methodA() {
System.out.println("选择实现方法methodA");
}
}
接口是多现实的:一个类可以实现多个接口。
1.8之前的接口中是没有默认方法的,所有的方法都是抽象方法,那么一个类实现类两个接口,两个接口中有同样的方法,是不影响的。
案例:
public interface InterB {
void methodA();
}
public interface InterA {
void methodA();
}
public class InterImpl implements InterA,InterB {
但是1.8开始有了默认方法,看看效果:
public interface InterB {
void methodA();
default void methodB(){
System.out.println("InterB - methodB");
}
}
public interface InterA {
void methodA();
default void methodB(){
System.out.println("InterA - methodB");
}
}
要求自己实现一个methodB方法:
public class InterImpl implements InterA,InterB {
接口之间的继承: 接口是可以多继承的
接口可以继承接口。
一个接口可以继承多个其他接口。
多继承,如果只有抽象方法,不会产生冲突
public interface InterA {
void methodA();
}
public interface InterB {
void methodA();
}
public interface InterC extends InterA,InterB {
void methodA();
}
如果两个父接口有同名的默认方法:

接口的使用
接口看上去就是比抽象类更抽象一个类。
接口的作用和抽象类类似,但是抽象更趋向于类。而接口更趋向于功能。
使用上和抽象类几乎相同。
抽象类都是 申明抽象类对象, 创建子类实例。
接口也一样。
实现类的类型转向接口也是向上转型,自动转换。 接口类型转向实现类也是向下转型,需要强制类型转换。
public static void main(String[] args) {
//申明接口类型,创建实现类对象
Ink ink = new ColorInk();
ink.methodA();//实现的方法methodA
ink.methodB();//实现的方法methodB
ink.methodC();//默认方法C
ink.methodD();//默认方法D
}
tips:如果在实现类中扩展方法
接口的多态:
public interface USB {
void turnOn();
void turnOff();
}
public class Mouse implements USB {
@Override
public void turnOn() {
System.out.println("鼠标开");
}
@Override
public void turnOff() {
System.out.println("鼠标关");
}
}
public class Mic implements USB {
@Override
public void turnOn() {
System.out.println("音响开");
}
@Override
public void turnOff() {
System.out.println("音响关");
}
}
public class Computer {
public void openUSB(USB usb){
usb.turnOn();
}
public void stopUSB(USB usb){
usb.turnOff();
}
}
public class Test {
public static void main(String[] args) {
Computer computer = new Computer();
computer.openUSB(new Mouse());
computer.openUSB(new Mic());
}
}
实现类重写默认方法:
public class BlackInk implements Ink{
@Override
public void methodA() {
System.out.println("黑白墨盒-methodA");
}
@Override
public void methodB() {
System.out.println("黑白墨盒-methodB");
}
//重写默认方法
@Override
public void methodC() {
System.out.println("黑白墨盒-methodC");
}
@Override
public void methodD() {
System.out.println("黑白墨盒-methodD");
}
}
测试:
Ink ink = new BlackInk();
ink.methodA();
ink.methodB();
ink.methodC();
ink.methodD();
案例测试:
public class Test {
public static void main(String[] args) {
InterB inter = new InterImpl();
inter.methodA();//被子类实现
inter.methodB();//接口中的默认方法被重写的
//实现类对象可以直接赋值给任意一个父接口。
InterA ia = new InterImpl();
InterB ib = new InterImpl();
}
}
补充:接口中可以定义静态方法。
package com.qidian.demo5;
public interface InterA {
public static void methodA(){
System.out.println("接口中的静态方法");
}
}
public class Test {
public static void main(String[] args) {
//接口中的静态方法
InterA.methodA();
}
}
JDBC
JDBC是一套接口。java程序要连接数据库,就要有对应的程序访问对应的数据。但是数据库各不相同,java没有办法开发一套程序对应所有的关系型数据库。
我们访问数据无非就四个操作:增删改查。 --> 增删改,查
定义接口:
public List<Data> queryAll(tableName); public int insert(.....); 只有接口,不做实现....
由数据库开发商实现这些接口。开发商所实现的这一套代码就是JDBC驱动。
驱动? 不同接口之间的数据(信号)转换程序。
JDBC的驱动:java接口和关系型数据库之间的信号转换程序。 不同的数据库就需要不同的转换程序。
java连接数据库的工作原理
对于程序员来说,只要关心java提供的操作数据的接口即可。
JDBC常用接口
DriverManager:这个类管理数据库驱动程序的列表,查看加载的驱动是否符合JAVA Driver API的规范。
Connection:与数据库中的所有的通信是通过唯一的连接对象。 一个连接。
Statement:把创建的SQL对象,转而存储到数据库当中。 发送sql。
ResultSet:它是一个迭代器,用于检索查询数据。 查询的结构。

JDBC的基本操作步骤
[0]准备,准备JDBC的驱动包。
驱动包是数据库开发商提供的,在java库中是没有的,需要我们下载,并且加入到我们的classpath中。
下载驱动:
https://mvnrepository.com/search
搜索mysql,根据自己的版本需求点开:进入详情页面之后,点击下载jar文件:
创建一个java项目,将驱动加入项目的classpath中:
说明: 所谓classpath就是JVM在启动的时候,加载类的路径。 之所以要将jar文件加入到classpath中,就是希望JVM在找驱动的时候能找到。
具体操作:
在项目的根目录下创建一个lib文件夹,将驱动的jar文件拷贝到lib中。

开始将jar文件加入到项目的classpath中:

找到你的驱动jar文件。

添加完成。

产生一个连接
public class Demo1 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 步骤1 : 加载驱动
// 参数是驱动类的列名,不同的数据库驱动类名不同。
// MySQL5.x和MySQL8.x驱动类名不同。
Class.forName("com.mysql.jdbc.Driver");
// 步骤2: 获取连接
// 参数1 : url
// 参数2: 连接数据库的用户名
// 参数3: 连接数据库的密码
Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/books","root","root123");
System.out.println(con);
}
}
获取连接中的url说明: url->统一资源定位器 jdbc:mysql://127.0.0.1:3306/books jdbc:mysql: 这个是固定的前缀,不同的数据库前缀不同 3306 : MySQL数据库默认的服务监听端口。 127.0.0.1 : 是mysql所在的服务器的地址。如果是本机,可以使用localhost。 /books : 要连接的数据库的名字。
[1]加载驱动。
[2]获取连接。
[3]创建statement。
[4]执行sql语句。
[5]处理执行结果。
[6]关闭连接。
完整案例
public class Demo2 {
private static final String DRIVER_CLASS="com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://127.0.0.1:3306/books";
private static final String USERNAME = "root";
private static final String PASSWORD = "root123";
public static void main(String[] args) {
// 将需要的对象申明在try语句块以外
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
//[1]加载驱动。
Class.forName(DRIVER_CLASS);
//[2]获取连接。
con = DriverManager.getConnection(URL,USERNAME,PASSWORD);
//[3]创建statement。
st = con.createStatement();
//[4]执行sql语句。
// 准备一个字符串,存储sql语句
String sql = "select * from g_book";
rs = st.executeQuery(sql); // 这里的rs对象就是我们查询的一张虚拟表
//[5]处理执行结果。
while(rs.next()){// 将结果集的数据逐行遍历
String isbn = rs.getString("isbn");
String title = rs.getString("title");
float cost = rs.getFloat("cost");
int categoryId = rs.getInt("category_Id");
System.out.println("isbn:"+isbn +",title:"+title+",cost:"+cost+",categoryId:"+categoryId);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
// [6]关闭连接。
if(rs!=null) {
rs.close();
}
if(st!=null) {
st.close();
}
if(con!=null) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
说明:
// [1]加载驱动。
Class.forName("com.mysql.jdbc.Driver");
这里使用反射机制将驱动相关的类加载到内存中。
不同的数据库会有不同的驱动的类名。MySQL8的驱动类名不一样。“com.mysql.cj.jdbc.Driver”
// [2]获取连接。
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/books","root","root123");
获取连接使用的是java提供的一个类DriverManager,DriverManager中有多个静态方法可以获取一个有效的连接。我们这里使用的方法需要传入三个参数。 三个参数分别是:
url : 连接数据库的地址。
前缀:jdcb:mysql://
服务器地址: localhost 当然也可以写IP地址。 127.0.0.1,
端口:3306。
数据库的名称: /books
username: 连接数据库的用户名。
password: 连接数据库的密码。
// [3]创建statement。
Statement st = con.createStatement();
通过Connection对象可以直接创建Statement。
Statement提供了大量的API用来执行的sql语句。
// [4]执行sql语句。
ResultSet rs = st.executeQuery("select * from g_book");
我们这里执行的查询操作,索引使用api: executeQuery(sql) 。查询执行结束之后会得到ResultSet对象。
如果是增删改,则使用API: executeUpdate(sql) 。返回数据库受影响的行数。(int)
// [5]处理执行结果。
while(rs.next()){
System.out.print(rs.getString("isbn")+"-");
System.out.print(rs.getString("title")+"-");
System.out.print(rs.getString("cost")+"-");
System.out.print(rs.getString("price")+"\n");
}
只要查询操作才有这一步。
我们可以简单的认为ResultSet就是一个虚拟表(迭代器),可以迭代处理查询返回的结果。
try {
// [6]关闭连接。
if(rs!=null) {
rs.close();
}
if(st!=null) {
st.close();
}
if(con!=null) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
关闭连接。正常情况下 ResultSet,Statement,Connection都是需要关闭的。
JDBC完成添加操作
案例:通过JDBC给boys表添加一条数据
public class Demo2_Insert {
// 连接数据库需要的常量
private static final String DRIVER_CLASS="com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://127.0.0.1:3306/student";
private static final String USERNAME = "root";
private static final String PASSWORD = "root123";
public static void main(String[] args) {
// 将需要的对象申明在try语句块以外
Connection con = null;
Statement st = null;
// ResultSet rs = null; 增删改都是没有查询结果,的所以不需要ResultSet
try{
// 加载驱动
Class.forName(DRIVER_CLASS);
// 获取链接
con = DriverManager.getConnection(URL,USERNAME,PASSWORD);
// 获取Statement对象
st = con.createStatement();// 在内部创建了一个Statement接口实现类的对象,并且返回了这个对象。
// 准备sql语句
String sql = "insert into boys(id,boyname,usercp) values(6,'鸣人',50000)";
// 执行sql 增删改操作全部使用executeUpdate
int result = st.executeUpdate(sql);
// 这里result就是数据库受影响的行数
System.out.println(result);
}catch (Exception e){
e.printStackTrace();// 将异常信息输出到控制台
}finally {
try{
if(st!=null){
st.close();
}
if(con !=null ){
con.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
说明几个问题:
-
st使用什么方法执行sql语句。
在JDBC中,对数据库的操作只有两种。分别是修改和查询。所谓修改就是对数据库的数据产生了影响,比新增数据,修改数据,删除数据。 查询是对数据本身不产生任何影响的。
所以在执行增删改操作的时候统一使用 executeUpdate(sql) 返回的结果是数据库受影响的行数。
查询操作统一使用 executeQuery(sql) 返回的结果是查询的结果集(ResultSet对象)
JDBC完成修改操作
修改操作和添加操作的流程完全一致,仅仅修改修改sql语句即可。
public class Demo2_update {
// 连接数据库需要的常量
private static final String DRIVER_CLASS="com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://127.0.0.1:3306/student";
private static final String USERNAME = "root";
private static final String PASSWORD = "root123";
public static void main(String[] args) {
// 将需要的对象申明在try语句块以外
Connection con = null;
Statement st = null;
// ResultSet rs = null; 增删改都是没有查询结果,的所以不需要ResultSet
try{
// 加载驱动
Class.forName(DRIVER_CLASS);
// 获取链接
con = DriverManager.getConnection(URL,USERNAME,PASSWORD);
// 获取Statement对象
st = con.createStatement();// 在内部创建了一个Statement接口实现类的对象,并且返回了这个对象。
// 准备sql语句
String sql = "update boys set boyname = 'mingren' where id = 6";
// 执行sql 增删改操作全部使用executeUpdate
int result = st.executeUpdate(sql);
// 这里result就是数据库受影响的行数
System.out.println(result);
}catch (Exception e){
e.printStackTrace();// 将异常信息输出到控制台
}finally {
try{
if(st!=null){
st.close();
}
if(con !=null ){
con.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
JDBC完成删除操作
删除操作。。。。 程序就略了。在JDBC中增删改是同一个操作。
所有JDBC只有两个操作: update和query。
所以statement有两个重要的API: executeUpdate和executeQuery
JDBC查询操作-多行数据查询
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Demo2_query {
// 连接数据库需要的常量
private static final String DRIVER_CLASS="com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://127.0.0.1:3306/student";
private static final String USERNAME = "root";
private static final String PASSWORD = "root123";
public static void main(String[] args) {
// 将需要的对象申明在try语句块以外
Connection con = null;
Statement st = null;
ResultSet rs = null; //增删改都是没有查询结果,的所以不需要ResultSet
try{
// 加载驱动
Class.forName(DRIVER_CLASS);
// 获取链接
con = DriverManager.getConnection(URL,USERNAME,PASSWORD);
// 获取Statement对象
st = con.createStatement();// 在内部创建了一个Statement接口实现类的对象,并且返回了这个对象。
// 准备sql语句
String sql = "select * from beauty";
// 执行sql 查询操作全部使用executeQuery(sql);
rs = st.executeQuery(sql);
// rs就是一个结果集
while(rs.next()){// 返回true说明这一行剥离成功
// 取出剥离出来的数据 rs.getXxxx(parm) xxx是对应的数据类型。
// parm可以是列的索引,索引从1开始计算 这个参数还可以是列名(不区分大小写)
int id = rs.getInt(1);
String name = rs.getString("name");// rs.getString(2);
String sex = rs.getString("sex");
String birth = rs.getString("borndate");
String phone = rs.getString("phone");
int boyfriendId = rs.getInt("boyfriend_id");
System.out.println("id:"+id+",name:"+name+",sex:"+sex+",birth:"+birth+",phone:"+phone+",boyfriendId:"+boyfriendId);
}
}catch (Exception e){
e.printStackTrace();// 将异常信息输出到控制台
}finally {
try{
if(rs!=null){
rs.close();
}
if(st!=null){
st.close();
}
if(con !=null ){
con.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
看图理解结果集处理:
我们使用select * from beauty查询一张虚拟表,在ResultSet中:

会有一个指针指向每一行的上面,当我们执行rs.next的时候,指针会向下移动,移动成功就返回true,否则返回false。当到大最后一行之后,再next就返回false。
每移动一次,就剥离一行出来。我们可以通过rs.getXxx()方法获取这一行的所有的列的数据。
JDBC查询操作-单行数据查询
查询一条数据和查询多条数据本身是没有啥区别
public class Demo2_query_one {
// 连接数据库需要的常量
private static final String DRIVER_CLASS="com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://127.0.0.1:3306/student";
private static final String USERNAME = "root";
private static final String PASSWORD = "root123";
public static void main(String[] args) {
// 将需要的对象申明在try语句块以外
Connection con = null;
Statement st = null;
ResultSet rs = null; //增删改都是没有查询结果,的所以不需要ResultSet
try{
// 加载驱动
Class.forName(DRIVER_CLASS);
// 获取链接
con = DriverManager.getConnection(URL,USERNAME,PASSWORD);
// 获取Statement对象
st = con.createStatement();// 在内部创建了一个Statement接口实现类的对象,并且返回了这个对象。
// 准备sql语句
String sql = "select * from beauty where id = 1";
// 执行sql 查询操作全部使用executeQuery(sql);
rs = st.executeQuery(sql);
// rs就是一个结果集
if(rs.next()){// 返回true说明这一行剥离成功
// 取出剥离出来的数据 rs.getXxxx(parm) xxx是对应的数据类型。
// parm可以是列的索引,索引从1开始计算 这个参数还可以是列名(不区分大小写)
int id = rs.getInt(1);
String name = rs.getString("name");// rs.getString(2);
String sex = rs.getString("sex");
String birth = rs.getString("borndate");
String phone = rs.getString("phone");
int boyfriendId = rs.getInt("boyfriend_id");
System.out.println("id:"+id+",name:"+name+",sex:"+sex+",birth:"+birth+",phone:"+phone+",boyfriendId:"+boyfriendId);
}
}catch (Exception e){
e.printStackTrace();// 将异常信息输出到控制台
}finally {
try{
if(rs!=null){
rs.close();
}
if(st!=null){
st.close();
}
if(con !=null ){
con.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
JDBC查询操作-单行单列数据查询
统计有多少美女:
public class Demo2_query_count {
// 连接数据库需要的常量
private static final String DRIVER_CLASS="com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://127.0.0.1:3306/student";
private static final String USERNAME = "root";
private static final String PASSWORD = "root123";
public static void main(String[] args) {
// 将需要的对象申明在try语句块以外
Connection con = null;
Statement st = null;
ResultSet rs = null; //增删改都是没有查询结果,的所以不需要ResultSet
try{
// 加载驱动
Class.forName(DRIVER_CLASS);
// 获取链接
con = DriverManager.getConnection(URL,USERNAME,PASSWORD);
// 获取Statement对象
st = con.createStatement();// 在内部创建了一个Statement接口实现类的对象,并且返回了这个对象。
// 准备sql语句
String sql = "select count(*) from beauty";
// 执行sql 查询操作全部使用executeQuery(sql);
rs = st.executeQuery(sql);
// rs就是一个结果集
if(rs.next()){// 返回true说明这一行剥离成功
int count = rs.getInt(1); // 直接根据索引取出
System.out.println("总共有"+count+"美女的信息");
}
}catch (Exception e){
e.printStackTrace();// 将异常信息输出到控制台
}finally {
try{
if(rs!=null){
rs.close();
}
if(st!=null){
st.close();
}
if(con !=null ){
con.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
经过上面的代码浏览,你会发现,有一个固定的框架:
public class Demo2_query_count {
// 连接数据库需要的常量
private static final String DRIVER_CLASS="com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://127.0.0.1:3306/student";
private static final String USERNAME = "root";
private static final String PASSWORD = "root123";
public static void main(String[] args) {
Connection con = null;
Statement st = null;
ResultSet rs = null; //增删改都是没有查询结果,的所以不需要ResultSet
try{
Class.forName(DRIVER_CLASS);
con = DriverManager.getConnection(URL,USERNAME,PASSWORD);
st = con.createStatement();
//-------------------------------------
// 准备sql语句
String sql = "select count(*) from beauty";
// 执行sql 查询操作全部使用executeQuery(sql);
//rs = st.executeQuery(sql);
// rs就是一个结果集
//if(rs.next()){// 返回true说明这一行剥离成功
// int count = rs.getInt(1); // 直接根据索引取出
// System.out.println("总共有"+count+"美女的信息");
//}
//----------------------------------------
}catch (Exception e){
e.printStackTrace();// 将异常信息输出到控制台
}finally {
try{
if(rs!=null){
rs.close();
}
if(st!=null){
st.close();
}
if(con !=null ){
con.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
MySQL8.0的driver和url的写法:
URL写法: jdbc:mysql://localhost:3306/数据库名称?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true driver写法: com.mysql.cj.jdbc.Driver
常见的错误:
[1]数据库用户名和密码写错了。

[2]驱动找不到的错误
驱动类名字写错了或者驱动的jar文件没有添加到classpath下。

[3]url写错了

[4]SQL语句的拼写错误
表明写错,或者数据库名写错

sql语句的语法错误:

[5]使用rs.getXxxx(cname)的时候列名拼写错误

我们计算机使用的数据都是二进制,如果要将‘hello’存储到磁盘上,就需要将字符转换为二进制。使用一定的规则来将对应的字符转换为可以存储、传输的形式的方式就是编码。
编码规则有好多种。 ISO8859-1, 中文编码:GBK,GB2312,GB18030。 国际通用编码UTF-8。
乱码是怎么来?
输入的编码和输出的编码不一致导致的。
-
存储的时候使用的编码和读取的时候使用的编码不一致。
-
发送的时候使用的编码和接收的时候使用的编码不一致。
现在的问题:数据从APP到数据库就乱码了。
-
创建数据库的时候,设置数据库的编码为utf-8。
-
在使用JDBC连接数据数据库的时候,设置连接参数中的编码也为utf-8。
设置方式:在URL后面添加参数。
jdbc:mysql://127.0.0.1:3306/student?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
JDBC的封装
JDBC的使用方式。
DAO:

实现下面的接口:
public interface BookDAO {
/** * 根据传入的参数添加一本图书信息到图书表中 *
* @return 返回数据库受影响的行数
* */
public int save(String isbn,String title,float cost,float price,String pid,int categoryId);
/**
* 根据传入的参数修改一本图书信息
* tips:isbn是不能修改的,所以update 是根据isbn修改其他的列的值
* @return 返回数据库受影响的行数
* */
public int update(String isbn,String title,float cost,float price,String pid,int categoryId);
/**
* 根据isbn删除一本图书的信息 * @return 返回数据库受影响的行数
* */
public int delete(String isbn);
/** *
* 查询图书的总条数,返回总条数
* */
public int queryTotal();
/** *
* 根据isbn查询一本图书的信息,要求返回map,map结构如下 *
* {isbn:95279527,title:'一本测试图书',cost:25.5,price:35.5,pname:'胡说八道出版 社',cname:'童书'} *
* tips: 要连接查询的
* */
public Map queryByIsbn(String isbn);
/** *
* 根据标题查询图书信息. 注意要模糊查询 *
* sql = "select * from book where title like '%"+title+"%'; *
* 返回一个list,list中放的都是map,结构如下面的例子 */
public List<Map> queryByTitle(String title);
}
具体实现:
public class BookDAOImpl implements BookDAO {
// 连接数据库需要的常量
private final String DRIVER_CLASS="com.mysql.jdbc.Driver";
private final String URL = "jdbc:mysql://127.0.0.1:3306/books?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true";
private final String USERNAME = "root";
private final String PASSWORD = "root123";