源头(没有持久层框架之前的数据持久化)
传统的JDBC:https://blog.youkuaiyun.com/qq_30641447/article/details/51381984
JDBC连接数据库
•创建一个以JDBC连接数据库的程序,包含7个步骤:
1、加载JDBC驱动程序:
在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),
这通过java.lang.Class类的静态方法forName(String className)实现。
例如:
try{
//加载MySql的驱动类
Class.forName("com.mysql.jdbc.Driver") ;
}catch(ClassNotFoundException e){
System.out.println("找不到驱动程序类 ,加载驱动失败!");
e.printStackTrace() ;
}
成功加载后,会将Driver类的实例注册到DriverManager类中。
2、提供JDBC连接的URL
•连接URL定义了连接数据库时的协议、子协议、数据源标识。
•书写形式:协议:子协议:数据源标识
协议:在JDBC中总是以jdbc开始
子协议:是桥连接的驱动程序或是数据库管理系统名称。
数据源标识:标记找到数据库来源的地址与连接端口。
例如:(MySql的连接URL)
jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=gbk ;
useUnicode=true:表示使用Unicode字符集。如果characterEncoding设置为 gb2312或GBK,本参数必须设置为true 。characterEncoding=gbk:字符编码方式。
3、创建数据库的连接
•要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,该对象就代表一个数据库的连接。
•使用DriverManager的getConnectin(String url , String username ,String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和 密码来获得。
例如:
//连接MySql数据库,用户名和密码都是root
String url = "jdbc:mysql://localhost:3306/test" ;
String username = "root" ;
String password = "root" ;
try{
Connection con =
DriverManager.getConnection(url , username , password ) ;
}catch(SQLException se){
System.out.println("数据库连接失败!");
se.printStackTrace() ;
}
4、创建一个Statement
•要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3种类型:
1、执行静态SQL语句。通常通过Statement实例实现。
2、执行动态SQL语句。通常通过PreparedStatement实例实现。
3、执行数据库存储过程。通常通过CallableStatement实例实现。
具体的实现方式:
Statement stmt = con.createStatement() ;
PreparedStatement pstmt = con.prepareStatement(sql) ;
CallableStatement cstmt =con.prepareCall("{CALL demoSp(? , ?)}") ;
5、执行SQL语 句
Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate 和execute
1、ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句 ,返回一个结果集(ResultSet)对象。
2、int executeUpdate(String sqlString):用于执行INSERT、UPDATE或DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等
3、execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的 语句。 具体实现的代码:
ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;
int rows = stmt.executeUpdate("INSERT INTO ...") ;
boolean flag = stmt.execute(String sql) ;
6、处理结果
两种情况:
1、执行更新返回的是本次操作影响到的记录数。
2、执行查询返回的结果是一个ResultSet对象。
• ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些 行中数据的访问。
• 使用结果集(ResultSet)对象的访问方法获取数据:
while(rs.next()){
String name = rs.getString("name") ;
String pass = rs.getString(1) ; // 此方法比较高效
}
(列是从左到右编号的,并且从列1开始)
7、关闭JDBC对象
操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声 明顺序相反:
1、关闭记录集 2、关闭声明 3、关闭连接对象
if(rs != null){ // 关闭记录集
try{
rs.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
if(stmt != null){ // 关闭声明
try{
stmt.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
if(conn != null){ // 关闭连接对象
try{
conn.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
springJDBC连接数据库:
spring集成jdbc帮助我们完成许多JDBC API开发过程中许多单调乏味,底层细节处理的工作。
简略过程:
step1.导包。
spring-webmvc,ojdbc,dbcp,spring-jdbc,junit
step2.添加Spring配置文件。
step3.配置JdbcTemplate。
注:
JdbcTemplate对常用的jdbc api做了一些封装,调用这些
方法时,不再需要考虑如何获取连接、关闭连接以及处理异常等等。
<!-- 配置jdbcTemplate -->
<bean id="jt" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="ds"/>
</bean>
step4.调用JdbcTemplate的方法来访问数据库。
注:
通常将JdbcTemplate注入到DAO。
dao实现类里编写方法,编写SQL语句,调用jt方法执行
@Repository("userspring")
public class UserDAOSpringJDBCImpl {
@Autowired
@Qualifier("jt")
private JdbcTemplate jt;
public void delete(String ename){
String sql = "delete from user_lql where ename=?";
Object[] args = {ename};
jt.update(sql,args);
System.out.println("ename: "+ename+"删除成功");
}
public UserDAOSpringJDBCImpl() {
System.out.println("UserDAOSpringJDBCImpl()");
}
相比于传统的JDBC,封装了许多底层操作;
Mybatis持久层框架
持久化理解:https://blog.youkuaiyun.com/qq_33530388/article/details/62053538
- 首先持久是相对于瞬时来说的,* 持久层,可以理解成数据 保存在 数据库或者 硬盘一类可以保存很长时间的设备里面,不像放在内存中那样断电就消失了,也就是把数据存在持久化设备上*
- 企业应用中* 数据很重要(各种订单数据、客户数据、库存数据之类的),比应用程序本身更重要, 所以需要把数据持久化。持久化可以通过很多方式,写文件和数据库都可以。只是现在企业一般都会选择把数据持久化到数据库中,因为可以很方便的查询统计分析,但数据库的数据最终还是会写到磁盘上的。Java 程序员为了操作数据库, 最开始是使用JDBC*来进行的,但是这种方式* 开发效率低 ,要写一堆重复代码,加上关系数据库和对象本身存在所谓的阻抗不匹配情况,所以 为了提高开发效率,有人发明了 ORM 即 对象关系映射框架* (Hibernate是其中的佼佼者),对于 Java 程序员来说,就可以通过操纵对象来操纵数据库了。
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
mybatis提供两种方式访问数据库(创建sqlSession即会话或者通过Mapper映射器)
通过sqlSession会话方式:
step1. 导包。
mybatis,ojdbc,junit
step2. 添加MyBatis配置文件。
step3. 添加实体类。
注:实体类的属性名要和表的字段名一样(大小写可以忽略)
step4. 添加映射文件。
注:存放sql语句。
不要忘记修改MyBatis配置文件,指定映射文件的位置。
step5. 调用MyBatis的api访问数据库。
添加mybatis配置文件(SqlMapConfig.xml)即配置数据库的连接
<configuration>
<environments default="environment">
<environment id="environment">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/orcl" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!-- 指定映射文件的位置 -->
<!-- 注意:映射文件有几个写几个,不能多写 -->
<mappers>
<mapper resource="entity/EmpMapper.xml" />
</mappers>
</configuration>
添加实体类
表所对应的字段的属性+get,set+构造+tostring
添加映射文件(EmpMapper.xml)
<mapper namespace="test">
<!-- id:每一条SQL语句应该有唯一的id(称之为sqlid)
可以添加的参数有:实体类,要写类的全名)
resultType:返回值类型 -->
<insert id="save" parameterType="entity.Employee">
INSERT INTO user_lql VALUES(id,#{ename},#{salary},#{age})
</insert>
</mapper>
测试
private SqlSession session;
@Before
public void init(){
String config="SqlMapConfig.xml";//引入文件
SqlSessionFactoryBuilder ssfb =
new SqlSessionFactoryBuilder();
SqlSessionFactory ssf = ssfb.build(TestCase.class.getClassLoader()
.getResourceAsStream(config));
//获得SqlSession 对象
session = ssf.openSession();
}
@Test
public void test1(){
//调用SqlSession提供的方法访问数据库
Employee e = new Employee(1,"罗宾",20000,15);
session.insert("test.save", e);
//提交事务(添加,修改,删除)
session.commit();
//关闭资源
session.close();
}
添加映射器:
创建一个maven项目,jar类型
1.导入mybatis,mysql驱动,junit包
2.添加mybatis配置文件,SqlMapConfig.xml,用来加载连接数据库
3.添加与表字段像对应的实体类,对其进行合理的封装
4.与实体类同包下,添加映射文件EmpMapper.xml,存放标签+对应的SQL语句
mapper 的namespace自己命名
5.在配置文件中,指定映射文件的位置
<!-- 指定映射文件的位置 -->
<!-- 注意:映射文件有几个写几个,不能多写 -->
<mappers>
<mapper resource="entity/EmpMapper.xml" />
</mappers>
6.接着写Mapper映射器
要求:
a.方法名必须与sqlId一样。
b.参数类型必须与parameterType一样。
c.返回类型必须与resultType一样。
d.映射文件中的namespace必须与Mapper映射器全限定名一样.
全限定名:包名加类名。
实现:
1.创建一个接口,作为映射器
2.映射文件的namespace指明到映射器(接口)
<mapper namespace="dao.EmployeeDAO">
3.在接口中声明与映射文件中id名对应的方法名,参数值与返回值同样对应的方法
4.测试方法中测试
public class TestCase {
private EmployeeDAO dao;
@Before
public void init(){
//启动容器
ApplicationContext ac = new
ClassPathXmlApplicationContext("spring-mybatis.xml");
//employeeDAO 在哪里设置的???默认的
dao = ac.getBean("employeeDAO",EmployeeDAO.class);
//使用@Repositor("empdao")来自己设置注解id
}
@Test
public void test1(){
//不需要获取SqlSessionFactoryBuilder....
Employee e = new Employee();
e.setEname("卡萨丁");
e.setSalary(5555);
e.setAge(22);
dao.save(e);
//不用考虑事务提交,也不考虑关闭SqlSession
}
@Test
public void test2(){
List<Employee> employees = dao.findAll();
for (Employee employee : employees) {
System.out.println(employee);
}
}
}
而在SSM框架中我们使用注入DAO到service+使用@Service持久层注解来直接调用持久层方法,实现对数据库的操作。
Mybatis与Hibernate对比学习
学习地址:https://blog.youkuaiyun.com/w_q_q_/article/details/79032062
1. hibernate是全自动,而mybatis是半自动
hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql。而mybatis仅有基本的字段映射,对象数据以及对象实际关系仍然需要通过手写sql来实现和管理。
2. hibernate数据库移植性远大于mybatis
hibernate通过它强大的映射结构和hql语言,大大降低了对象与数据库(oracle、mysql等)的耦合性,而mybatis由于需要手写sql,因此与数据库的耦合性直接取决于程序员写sql的方法,如果sql不具通用性而用了很多某数据库特性的sql语句的话,移植性也会随之降低很多,成本很高。
3. hibernate拥有完整的日志系统,mybatis则欠缺一些
hibernate日志系统非常健全,涉及广泛,包括:sql记录、关系异常、优化警告、缓存提示、脏数据警告等;而mybatis则除了基本记录功能外,功能薄弱很多。
4. mybatis相比hibernate需要关心很多细节
hibernate配置要比mybatis复杂的多,学习成本也比mybatis高。但也正因为mybatis使用简单,才导致它要比hibernate关心很多技术细节。mybatis由于不用考虑很多细节,开发模式上与传统jdbc区别很小,因此很容易上手并开发项目,但忽略细节会导致项目前期bug较多,因而开发出相对稳定的软件很慢,而开发出软件却很快。hibernate则正好与之相反。但是如果使用hibernate很熟练的话,实际上开发效率丝毫不差于甚至超越mybatis。
5. sql直接优化上,mybatis要比hibernate方便很多
由于mybatis的sql都是写在xml里,因此优化sql比hibernate方便很多。而hibernate的sql很多都是自动生成的,无法直接维护sql;虽有hql,但功能还是不及sql强大,见到报表等变态需求时,hql也歇菜,也就是说hql是有局限的;hibernate虽然也支持原生sql,但开发模式上却与orm不同,需要转换思维,因此使用上不是非常方便。总之写sql的灵活度上hibernate不及mybatis。
随着使用情况的不断增多,我又做了进一步的总结总结:
mybatis:小巧、方便、高效、简单、直接、半自动
hibernate:强大、方便、高效、复杂、绕弯子、全自动
mybatis:
1. 入门简单,即学即用,提供了数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美。
2. 可以进行更为细致的SQL优化,可以减少查询字段。
3. 缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。
4. 二级缓存机制不佳。
hibernate:
1. 功能强大,数据库无关性好,O/R映射能力强,如果你对Hibernate相当精通,而且对Hibernate进行了适当的封装,那么你的项目整个持久层代码会相当简单,需要写的代码很少,开发速度很快,非常爽。
2. 有更好的二级缓存机制,可以使用第三方缓存。
3. 缺点就是学习门槛不低,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate方面需要你的经验和能力都很强才行。
举个形象的比喻:
mybatis:机械工具,使用方便,拿来就用,但工作还是要自己来作,不过工具是活的,怎么使由我决定。
hibernate:智能机器人,但研发它(学习、熟练度)的成本很高,工作都可以摆脱他了,但仅限于它能做的事。