持久层框架:DBUtils Hibernate
Mybatis:就类似与hibernate的orm持久层框架
优点:
sql优化方面,Hiberhate的查询会将表中的所有字段查询出来,这一点会有性能消耗。当然了,Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。说得更深入一些,如果有个查询要关联多张表,比如5张表,10张表时,而且,我们要取的字段只是其中几张表的部分字段。这时用hibernate时就会显得非常力不从心。就算用hibernate的 sqlquery,后续的维护工作也会让人发狂。
JDBC访问数据库存在的问题
1.频繁的创建·和关闭数据连接,太消耗资源
2.sql语句和参数的硬编码,不适合于维护数据库
3.结果集获取与遍历负载,存在硬编码,不利于维护,期望能够查询后返回一个java对象
mybatis简介
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
Mybatis是面向sql的持久层框架,他封装了jdbc访问数据库的过程,我们开发,只需专注于sql语句本身的拼装,其它复杂的过程全部可以交给mybatis去完成。
简单入门程序
1.导入必须的jar包
2.配置SqlMapConfig.xml
3.配置log4j.properties
4.设置数据库映射文件 pojo
1.配置SqlMapConfig文件
<?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>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="admin" />
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<mapper resource = "mybatis/user.xml"/>
</mappers>
</configuration>
文件解析
<?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">
<elemenr></element>
标签里面可以创建多个element
可以配置两个环境 关键词default:可以进行选择相应的环境
2.配置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
设置数据库字段的映射文件
package pojo;
import java.util.Date;
public class User {
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
private String uuid2;
public String getUuid2() {
return uuid2;
}
public void setUuid2(String uuid2) {
this.uuid2 = uuid2;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="
+ address + ", uuid2=" + uuid2 + "]";
}
}
4.设置sql语句查询的映射文件,user.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 :命名空间 ,用于隔离sql语句
id:sql id,语句的唯一标识
parameterType:入参的数据类型
resultType:返回结果的数据类型
#{} :相当于一个占位符
${} :字符串的拼接指令,如果入参为普通的数据类型,{}里面只能写value
-->
<mapper namespace="user">
<select id = "getUserById" parameterType = "int" resultType="pojo.User">
SELECT * FROM `user`
where id = #{id2}
</select>
</mapper>
**
**
**执行sql的查询
public class MybatisTest {
@Test
public void testGetUserById() throws IOException {
//加载核心配置文件
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
//io包创建一个核心配置文件的输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//通过输入流来创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = ssfb.build(inputStream);
//创建sqlsession对象 包含mybatis访问数据库的所有的操作:增删改查
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行查询
//第一个是sql的id 带上命名空间
//第二个是sql传入的参数 和user.xml中的文件入参一样
User user = sqlSession.selectOne("user.getUserById", 1);
//输出结果
System.out.println(user);
//释放资源
sqlSession.close();
}
}
文件位置
根据用户名来模糊查询用户信息
1.配置文件user.xml
**${}:字符串拼接的符号
<select id="getUserById" parametereType="string" resultType =pojo.User>
select *from ‘user’
where username LIKE ‘%${value}%’
</select>
**
2.创建SqlSessionFactoryUtils
目的是将创建SqlSessionFactoryBuilder进行封装成一个方法来进行快捷的调用
public class SqlSessionFactoryUtils{
//1.创建SqlSessionFactory对象
private static SqlSessionFactory sqlSessionFactory;
try{
//1.创建SqlSessionFatoryBuilder对象
SqlSessionFatoryBuilder ssfb = new SqlSessionFatoryBuilder();
//2.创建字节流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
sqlSessionFactory= ssfb.build(inputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
3.创建sql执行功能
//1.加载上面的工具类
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtis.getSqlSessionFactory();
//2.创建SqlSession对象
Sqlsession sqlSession = SqlSessionFactory.openSession();
List<User> list = sqlSession.selectList("user.getUserByUserName","张");
for(User user:list){
System.out.println(user);
}
//关流
sqlSession.close();
####根据用户id来查询数据库
xml配置
<select id = "getUserById" parameterType = "int" resultType="pojo.User">
SELECT * FROM `user`
where id = #{id2}
</select>
测试文件
@Test
public void testGetUserById() throws IOException { //加载配置文件
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
//io包创建一个核心配置文件的输入流
InputStream inputStream=Resources.getResourceAsStream("SqlMapConfig.xml");
//通过输入来创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory =ssfb.build(inputStream);
//创建sqlsession对象
SqlSession sqlSession =sqlSessionFactory.openSession(); //执行查询
User user =sqlSession.selectOne("user.getUserById", 1);
//输出结果
System.out.println(user);
//释放资源
sqlSession.close();
}
插入用户
xml配置文件
<!--
keyProperty :user表中的主键id
resultType: 主键的返回值类型
order: 下面的sql代码执行完之后再进行执行 -->
<insert id ="insertUser" parameterType="pojo.User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO `user`(
`username`,
`birthday`,
`sex`,
`address`)
VALUES(
#{username},
#{birthday},
#{sex},
#{address}
)
<!-- <selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
是获取数据库运行最后一个程序是的主键id值
order有两个值
一是before
二是after
也可以在insert属性 上进行简化useGeneratedKeys="true" keyProperty="id"
也是具有相同的效果
-->
</insert>
测试文件
@Test
public void testInsertUser() {
// 1.加载工具类
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
// 2.创建SQLSession getUserByUseName
SqlSession sqlSession = sqlSessionFactory.openSession(true);
User user = new User();
user.setUsername("王五2259");
user.setSex("1");
user.setBirthday(new Date());
user.setAddress("湖北 ");
sqlSession.insert("user.insertUser",user);
//插入查询
System.out.println(user );
sqlSession.close();
}
###更新用户
配置文件
<update id = "updateUser" parameterType = "pojo.user">
UPDATE
`user`
SET
`username` = #{username}
where `id` = #{id}
</update>
测试文件
public void testUpdateUser(){
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
//true 自动提交数据
Sqlsession sqlSession = sqlSessionFatory.openSession(true);
User user = new User();
user.setUsername("张三");
user.setId(23);
sqlSession.update("user.updateUser" ,user);
//每次手动提交数据
//SQLSession.commit();
sqlSession.close();
}
删除用户
配置文件
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="int">
DELETE FROM `user`
WHERE `id` = #{id}
</delete>
测试文件
@Test
public void testDeleteUser() {
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession(true);
User user = new User();
user.setId(40);
sqlSession.delete("user.deleteUser", user);
sqlSession.close();
}```