1.JDBC
1.1JDBC是什么
- 高级语言的应用程序需要特定的方式访问数据库。
- 特定的方式:JDBC, ODBC
- JDBC本质上是一系列的应用程序接口(API)
- 通过JAVA语言访问任何结构化数据库
- 通过JDBC API写出的程序,能够将SQL语句发送到相应的任何一种数据库
- 通过使用JDBC,开发人员可以很方便地将SQL语句传送给几乎任何一种数据库。也就是说,开发人员可以不必写一个程序访问SyBase,写另一个程序访问Oracle,再写一个程序访问Microsoft的SQLServer。用JDBC写的程序能够自动地将SQL语句传送给相应地数据库管理系统(DBMS)。不但如此,使用JAVA编写的应用程序可以在任何支持JAVA的平台上运行,不必在不同的平台上编写不同的应用。
- 简单地说,JDBC能完成下列三件事:
- 同一个数据库建立连接
- 向数据库发送SQL语句
- 处理数据库返回的结果
1.2 JDBC基本编程
- 建立数据库连接
DBConnection |
- 到数据库中查找是否存在给定id的用户,如果存在,就创建一个Bean,否则返回null
BankBean |
JDBC的使用过程
1.注册驱动
- 放置JDBC包或配置ODBC
- 针对提供JDBC包的数据库系统,例如SQLServer2000/2005/2008,JRE6.0运行环境,需要事先把SQLServer的JDBC包sqljdbc4.jar复制到JRE安装目录的libext下,或者复制到工程项目的lib目录下。其他环境变量的前提设置:已设置好JAVA_HOME和classpath。
- 针对没有提供JDBC包的数据库系统,例如Access,需要事先配置ODBC数据源,使用sun提供的JDBC-ODBC桥,由JRE安装目录下的librt.jar提供。
- 在程序中加载驱动器—Class.forName(“数据库驱动器名称”)
- 不同数据库,驱动程序名称不同,例如SQLServer:Class.forName(“com.microsoft.sqlserver.jdbc.SQLServerDriver”);
- MySQL数据源:Class.forName(“com.mysql.jdbc.Driver”);
- ODBC数据源:Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);
2.建立连接(Connection)
- 声明Connection对象:Connection cnotallow=null;
- 通过驱动程序建立连接
- 方式1:cnotallow=DriverManager.getConnection(url, user, password);
url格式:
JDBC:子协议:子名称://主机IP地址:端口;数据库名;属性名=属性值; …
其他参数如:useUnicode=true&characterEncoding=GBK - 方式2:cnotallow=DriverManager.getConnection(url);
此时,user,password用“属性名=属性值”方式放置在url字符串中
或者表示没有用户名和密码
建立连接示例(连接MySQL方式):
String url="jdbc:mysql://localhost:3306/loginuser";
conn=DriverManager.getConnection(url,"root","root");
3.创建命令对象(Statement)并执行SQL语句
- Statement对象,执行不需要参数的SQL语句
Statement st=conn.createStatement();
st.executeQuery("select * from bankaccount");
- PreparedStatement对象,执行需要传送参数的SQL语句
String sql="select * from bankaccount where bankid=? and balance>?";
PreparedStatement ps=conn.prepareStatement(sql);
ps.setString(1,"101");
ps.setInt(2,100);
ps.executeQuery();
4.处理执行结果(ResultSet)
- 对查询的结果集进行读取
- 获取Statement对象st执行查询的结果集
ResultSet rs=st.executeQuery(sql); - 获取PreparedStatement对象ps执行查询的结果集
ResultSet rs=ps.executeQuery();
- 依次处理结果集中的每条记录
while(rs.next()){
//获取当前记录中指定列名的数据
rs.getString("col_name1");
rs.getInt("col_name2");
}
5.释放资源
- 释放ResultSet,Statement,Connection
- 数据库连接(Connection)是非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭将导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。
//释放资源
public static void dbClose(Connection conn,PreparedStatement ps,ResultSet rs)
throws SQLException
{
rs.close();
ps.close();
conn.close();
}
6.代码模板
1.3JDBC的缺点
2.MyBatis
2.1MyBatis是什么
MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。
- 一个基于Java的持久层框架
- 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索
- 将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录
2.2MyBatis基本编程
- mybatis-config.xml
- pojo—User.java
public class User {
private String id;
private String userName;
private String password;
private String name;
private Integer age;
private Integer sex;
private Date birthday;
服务器托管网 private String created;
private String updated;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getCreated() {
return created;
}
public void setCreated(String created) {
this.created = created;
}
public String getUpdated() {
return updated;
}
public void setUpdated(String updated) {
this.updated = updated;
}
@Override
public String toString() {
return "User{" +
"id='" + id + ''' +
", userName='" + userName + ''' +
", password='" + password + ''' +
", name='" + name + ''' +
", age=" + age +
", sex=" + sex +
", birthday='" + new SimpleDateFormat("yyyy-MM-dd").format(birthday) + ''' +
", created='" + created + ''' +
", updated='" + updated + ''' +
'}';
}
}
- Mapper—UserMapper.xml
select * from user_copy where id = #{id}
- Test—MyBatisTest.java
public class MyBatisTest {
public static void main(String[] args) throws Exception {
// 指定全局配置文件
String resource = "mybatis-config.xml";
// 读取配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
// 构建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
// 操作CRUD,第一个参数:指定statement,规则:命名空间+“.”+statementId
// 第二个参数:指定传入sql的参数:这里是用户id
User user = sqlSession.selectOne("UserMapper.selectUserById", 100);
System.out.println(user);
} finally {
sqlSession.close();
}
}
}
2.3MyBatis的优点
1.优化获取和释放
- 解决了数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能的问题。
- 解决方法:统一从DataSource里面获取数据库连接,将DataSource的具体实现通过让用户配置来应对变化。在SqlMapConfig.xml中配置数据库连接池,使用连接池管理数据库连接。
2.SQL统一管理,对数据库进行存取操作
- 使用JDBC对数据库进行操作时,SQL查询语句分布在各个Java类中,可读性差,不利于维护,当我们修改Java类中的SQL语句时需要重新进行编译。
- MyBatis可以把SQL语句放在配置文件中统一进行管理,以后修改配置文件,也不需要重新编译部署。
- 解决方法:将SQL语句配置在XXXMapper.xml文件中与java代码分离。
3.传入参数映射和生成动态SQL语句
在查询中可能需要根据一些属性进行组合查询,比如我们进行商品查询,我们可以根据商品名称进行查询,也可以根据发货地进行查询,或者两者组合查询。如果使用JDBC进行查询,这样就需要写多条SQL语句。
4.能够对结果集进行映射
在使用JDBC进行查询时,返回一个结果集ResultSet,要从结果集中取出结果封装为需要的类型。在Mybatis中可以设置将结果直接映射为自己需要的类型,比如:JavaBean对象,一个Map,一个List等等。
解决方法:MyBatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。
2.4MyBatis与Spring整合
整合后比MyBatis基本编程多了一个DAO。
3.MyBatis Plus
通用CRUD操作:内置通用Mapper、通用Service,仅仅通过少量配置即可实现单表大部分CRUD操作。
4.#{}和${}的区别
- #{}是占位符,预编译处理;${}是拼接符,字符串替换,没有预编译处理
- MyBatis在处理#{}时,#{}传入参数是以字符串传入,会将SQL中的#{}替换为?号,调用PreparedStatement的set方法来赋值
- MyBatis在处理{}替换成变量的值,相当于JDBC中的Statement编译
- 变量替换后,#{}对应的变量自动加上单引号”;变量替换后,${}对应的变量不会加上单引号”
- #{}可以有效防止SQL注入,提高系统安全性;${}不能防止SQL注入
- #{}的变量替换是在DBMS中;${}的变量替换是在DBMS外
5.MyBatis缓存
MyBatis中有一级缓存和二级缓存,默认情况下一级缓存是开启的,而且是不能关闭的。一级缓存是指SqlSession级别的缓存,当在同一个SqlSession中进行相同的sql语句查询时,第二次以后的查询不会从数据库查询,而是直接从缓存中获取,一级缓存最多缓存1024条SQL。二级缓存是指可以跨SqlSession的缓存。是mapper级别的缓存,对于mapper级别的缓存,不同的sqlsession是可以共享的。
5.1MyBatis的一级缓存原理(sqlsession级别)
第一次发出一个查询sql,sql查询结果写入sqlsession的一级缓存中,缓存使用的数据结构是一个map。
key:MapperID+offset+limit+Sql+所有的入参
value:用户信息
同一个sqlsession再次发出相同的sql,就从缓存中取出数据。如果两次中间出现commit操作(修改、添加、删除),本sqlsession中的一级缓存区域全部清空,下次再去缓存中查询不到所以要从数据库查询,从数据库查询到再写入缓存。
5.2MyBatis的二级缓存原理(mapper级别)
二级缓存的范围是mapper级别(mapper同一个命名空间),mapper以命名空间为单位创建缓存数据结构,结构是map。MyBatis的二级缓存是通过CacheExecutor实现的。CacheExecutor其实是Executor的代理对象。所有的查询操作,在CacheExecutor中都会先匹配缓存中是否存在,不存在则查询数据库。
key:MapperID+offset+limit+sql+所有的入参
具体使用需要配置:
- MyBatis全局配置中启用二级缓存配置
- 在对应的Mapper.xml中配置cache节点
- 在对应的select查询节点中添加useCache=true
服务服务器托管网器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: Flask后端开发(二) – 功能实现和项目总结
Flask后端开发(二) – 功能实现和项目总结 目录 Flask后端开发(二) – 功能实现和项目总结 1. 功能1:修改文件参数值 1.1. 获取网页端传参 1.2. 读取文件 1.2.1. 一般文件读取方式 1.2.2. 特殊文件 —— mlx文件 1.…