一、JDBC
环境准备: jdk+eclipse+maven
创建maven项目+配置pom.xml,加入数据库依赖
public class JdbcDemo {
public static void main(String[] args) {
Connection con = null;
PreparedStatement psmt=null;
ResultSet rs=null;
try {
// 1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.创建一个数据库连接对象
con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/demo", "root", "root");
// 3.定义sql语句
String sql = "select*from 'user' where id=? ";
// 4.创建Statement语句对象
psmt = con.prepareStatement(sql);
// 5.设置参数
psmt.setInt(1, 10);
// 6.执行
rs = psmt.executeQuery();
// 7.处理结果集
while(rs.next()){
System.out.println("用户Id:"+rs.getInt("id")+",用户名称:"+rs.getString("username"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
// 8.释放资源
try{
if(rs != null) rs.close();
if(psmt != null) psmt.close();
if(con != null) con.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
频繁的创建连接对象和释放,容易造成系统资源的浪费,从而影响系统的性能,在企业中,可以通过使用连接池技术解决这个问题(Mybatis 内部提供连接池)
SQL语句的定义,参数设置,结果集处理存在问题
结果集处理存在重复代码,处理麻烦
二、 MyBatis
是一个持久层框架,是对JDBC的封装;
通过xml或者注解进行配置,实现Java对象和SQL语句的对应关系
mapper代理开发步骤
1、要求mapper映射文件中的namespace属性值,必须是mapper代理接口的全限定名称
2、要求mapper映射文件中,sql语句标签的声明,与mapper接口方法的声明一致
2.1.要求sql语句的resultType属性指定的类型(如果返回值是一个集合,resultType指定的是集合中存放的类型),与mapper接口方法的返回值类型一致
2.2.要求sql语句的id属性值,与mapper接口的方法名称一致
2.3.要求sql语句的parameterType属性指定的类型,与mapper接口方法的参数类型一致
1.添加依赖(在pox.xml文件中加入)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.itheima</groupId>
<artifactId>mybatis-first</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mybatis-first</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- mysql版本 -->
<mysql.version>5.1.30</mysql.version>
<!-- junit版本 -->
<junit.version>4.12</junit.version>
<!-- mybatis版本号 -->
<mybatis.version>3.4.5</mybatis.version>
<!-- log4j日志包版本 -->
<slf4j.version>1.7.7</slf4j.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<!-- mysql数据库依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- mybatis核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- log4j日志包 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- junit依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2.新建sqlMapConfig.xml文件(mybatis框架的主配置文件,文件名称可以修改)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 运行环境配置 -->
<!-- default:指定使用哪一个运行环境 -->
<environments default="development">
<!-- id:唯一标识一个运行环境 -->
<environment id="development">
<!-- 配置事务 -->
<transactionManager type="JDBC" />
<!-- 数据源配置 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/demo" />
<property name="username" value="root" />
<property name="password" value="admin" />
</dataSource>
</environment>
</environments>
</configuration>
3.新建log4j.properties文件,日志文件
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
4.新建用户实体类对象
public class User {
private Integer id; // int(11) NOT NULL AUTO_INCREMENT,
private String username; // varchar(32) NOT NULL COMMENT '用户名称',
private Date birthday; // date DEFAULT NULL COMMENT '生日',
private String sex; // char(1) DEFAULT NULL COMMENT '性别',
private String address; // varchar(256) DEFAULT NULL COMMENT '地址',
}+get/set方法+toString
5.编写mapper接口
public interface UserMapper {
// 1.根据用户Id查询用户
User queryUserById(Integer id);
// 2.新增一个用户
void insertUser(User user);
}
6.准备mapper映射文件(用户配置Java对象,与sql语句对应关系)--新建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">
<!--namespace:名称空间,相当于java中的package,用于防止sql语句名称冲突(sql语句的隔离) -->
<mapper namespace="test">
<!--mybatis针对每一种sql语句:新增/修改/删除/查询,
提供了对应的标签:insert/update/delete/select来放置
-->
<!-- 根据用户Id查询用户,说明:
select标签:用于放置查询sql语句
id:唯一标识名称
parameterType:输入参数的类型
resultType:输出结果的类型(暂时注意:需要的是全限定名称)
#{id}:占位符,相当于jdbc中的?
-->
<select id="queryUserById" parameterType="int" resultType="domain.User">
select * from `user` where id=#{id}
</select>
<!-- 根据用户名称模糊查询用户 -->
<select id="queryUserByName" parameterType="string" resultType="domain.User">
<!-- select * from `user` where username like #{username} -->
<!-- where username like '%小%' ,说明:${value}:字符串拼接符,处理参数-->
select * from `user` where username like '%${value}%'
</select>
<!-- 新增用户 :id是自增长的-->
<insert id="insertUser" parameterType="domain.User">
insert into `user`(id,username,birthday,sex,address)
values(#{id},#{username},#{birthday},#{sex},#{address})
insert into `user`(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
</insert>
<!-- 根据用户Id修改用户,说明:update:用于放置修改的sql语句-->
<update id="updateUserById" parameterType="cn.itheima.po.User">
update `user`
set username=#{username},sex=#{sex} where id=#{id}
</update>
<!-- 根据用户Id删除用户,说明:delete:用于放置删除sql语句-->
<delete id="deleteUserById" parameterType="int">
delete from `user` where id=#{id}
</delete>
</mapper>
7.在sqlMapConfig.xml(主配置文件)中,加载mapper.xml文件
<!-- 加载mapper映射文件 -->
<mappers>
<!-- 加载User.xml文件,说明:
1.resource:指定配置文件的位置
-->
<mapper resource="sqlmap/Mapper.xml"/>
</mappers>
8.测试
public class demoTest01 {
@Before
public void init() throws IOException{
private SqlSessionFactory sqlSessionFactory =null;
// 1.加载主配置文件sqlMapConfig.xml
/**
* getResourceAsStream:从类的根路径下加载主配置文件
*/
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 2.读取配置文件内容
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
/**
* sqlSessionFactory对象:
* 1.它是mybatis框架的核心对象,它是线程安全的,一个项目中只需要一个即可
*/
sqlSessionFactory = builder.build(inputStream);
}
@Test
public void queryUserByIdTest() throws IOException{
// 3.使用sqlSessionFactory对象,创建SqlSession对象
/**
* sqlSession对象:
* 1.它相当于jdbc中的Connection对象,它提供了操作数据库的CRUD方法
* 2.它是线程不安全的,每一个执行的方法都需要创建一个sqlSession
*/
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 4.使用sqlSession对象,获取mapper接口的代理对象
/* getMapper:获取mapper接口的代理对象
* 参数:
* type:mapper接口的字节码
*/
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
/**
* selectOne:查询单条记录
* 参数:
* statement:执行的sql语句(名称空间+"."+sql语句Id)
* parameter:传入的参数值
*/
// 3.调用方法执行
//查询一条
User user = mapper.queryUserById(2);
//模糊查询
List<Object> list = sqlSession.selectList("test.queryUserByName", "%小%");
//新建用户
User user = new User(); user.setXXX("***");
mapper.insertUser(user);
//根据ID修改
sqlSession.update("test.updateUserById", user);
//根据ID删除
sqlSession.delete("test.deleteUserById", 3);
// 5.释放资源
sqlSession.close();
}
}
三、缓存
Cache
- 存在内存中的临时数据
- 将用户经常查询的数据放在缓存(内存)中,用户查询的时候就不用从数据库查询
- 从缓存中查数据,减少了数据库的查询次数,从而提高查询效率,解决了高并发系统的性能问题
为什么使用缓存
- 减少与数据库的交互次数,减少系统的开销,提高系统的效率
使用情况
- 经常需要查询并且不经常改变的数据
1、mybatyis缓存
MyBatis自带二级缓存
- 默认情况是只开启了一级缓存(sqlsession 级别的缓存,也被称为本地缓存)
- 二级缓存需要手动开启和配置,基于namespace级别
- MyBatis定义了缓存接口Cache,我们可以通过实现Cache接口来自定义二级缓存
1.1 一级缓存
SqlSession
第一次查询的结构会放在本地缓存,以后相同的方法,相同的参数查询的时候,会直接从缓存拿,没必要去查询数据库
增删改操作一定会刷新缓存
1.2 二级缓存
二级缓存也叫全局缓存
机制:
- 一个会话查询一条数据,数据会放到当前会话的一级缓存中
- 如果当前会话关闭了,对应的一级缓存就没了
- 可以把信息放到二级缓存中
- 新的查询就可以从二级缓存中获取
- 不同的名称空间对应不同的二级缓存也就是不同的mapper对应不同的map
<!--显式的开启全局缓存-->
<setting name="cacheEnabled" value="true"/>
<!--在当前Mapper.xml中使用二级缓存-->
<cache/>
<--也可以自定义参数-->
<cache eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>