Mybatis
Mybatis
1,是一个基于Java的持久层框架
2,Mybatis帮助程序员将数据存入数据库中,和从数据库中取数据
3,传统jdbc:有很多重复代码,如结果集封装,数据库建立连接等
4,Mybatis是一个半自动化的ORM框架
5,它支持定制化 SQL、存储过程以及高级映射
6,MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
7,MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs映射成数据库中的记录
执行流程
读取核心配置文件—>SqlFactory类—>SqlSession—>(执行相关操作)
使用Mybatis
步骤:
1,导入相关jar包
- ant-1.10.3.jar
- ant-launcher-1.10.3.jar
- asm-7.0.jar
- cglib-3.2.10.jar
- commons-logging-1.2.jar
- javassist-3.24.1-GA.jar
- log4j-1.2.17.jar
- log4j-api-2.11.2.jar
- log4j-core-2.11.2.jar
- mybatis-3.5.2.jar
- ognl-3.2.10.jar
- slf4j-api-1.7.26.jar
- slf4j-log4j12-1.7.26.jar
- mysql-connector-java-8.0.15.jar
2,编写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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/user?serverTimezone=GMT%2B8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="cn/com/entity/user-mapper.xml"/>
</mappers>
</configuration>
3,创建SqlSessionFactory
public class MybatisUtil {
public static SqlSessionFactory getsqlSessionFactory() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory;
}
}
4,获得SqlSession
public static SqlSession getSession() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
return sqlSessionFactory.openSession();
}
5,创建实体类
6,编写sql语句的映射文件----要添加到核心配置文件中
<?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">
<mapper namespace="cn.com.entity.UserMapper">
<select id="selectUser" resultType="cn.com.entity.User">
select * from user where id = #{id}
</select>
</mapper>
7,测试
public class Test {
public static void main(String[] args) throws IOException {
UserDao userdao = new UserDao();
System.out.println(userdao.getById(1));
List<User> list = userdao.getAll();
for(User u:list)
System.out.println(u);
User user = new User();
user.setId(8);
System.out.println(userdao.add(user));
User user_update = userdao.getById(3);
user_update.setNumber(66666);
System.out.println(userdao.update(user_update));
System.out.println(userdao.delete(3));
}
}
CURD操作
Dao层
Mapper文件
配置文件解析
Mybatis-config.xml
核心配置文件
**环境配置(environments):**可以配置多个环境,每个SqlSessionFactory实例只能选择一种环境。default指向默认环境。每个 environment 元素定义唯一的环境 ID
事务管理器(transactionManager):
1,JDBC – 这个配置就是直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域
2,MANAGED – 这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为
数据源(dataSource):
1,UNPOOLED– 这个数据源的实现只是每次被请求时打开和关闭连接。
2,POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。
3,JNDI – 这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。
映射器(mappers):
定义 SQL 映射语句文件
mapper文件
定义sql映射语句
< mapper>:
namespace 命名空间 = 防止sql语句的id重名,命名一般为,包名+类名/包名+mapper文件名
parameterType 指sql语句参数类型,可以是java基本数据类型或实体类
resultType 返回结果类型
useGeneratedKeys=“true” 使用自增主键
优化配置文件
属性(properties):
类型别名(typeAliases):
属性名和字段名不一致
数据库表的设计
实体类
结果
解决方案:
由于mybatis会根据查询的列名去进行设值
1,为列名指定别名 别名和java实体类的属性名一致
2,设置结果映射类型
分页的实现
1,limit startIndex,pageSize
mapper映射文件
<select id="selectAll" parameterType="Map" resultType="User">
select * from user limit #{startIndex},#{pageSize}
</select>
dao中写法
public List<User> getAll(int currentPage,int pageSize) throws IOException{
SqlSession session = MybatisUtil.getSession();
Map<String,Integer> map = new HashMap<String,Integer>();
map.put("startIndex",(currentPage - 1)*pageSize );
map.put("pageSize", pageSize);
List<User> list = session.selectList("cn.com.entity.UserMapper.selectAll",map);
session.close();
return list;
}
注:不用为参数设置类,可以采用map结构来解决
2,通过RowBounds来实现分页的效果
mapper文件不需要改变
RowBounds 参数为 index-下标 size-偏移量
面向接口编程
好处:
扩展性好,分层开发中,上层不用管具体实现,大家都遵循共同的标准,使得开发变得容易,规范性更好
举例:
接口层(Dao):
实现层(DaoImpl):
注解的实现
其实质是动态代理生成实现类,调用实现方法
1,编写Dao接口
2,在核心配置文件中导入
3,使用
关于联表的处理
多对一
a,数据库表设计
b,实体类
Student.java
Teacher.java
c,编写映射文件
1,按结果嵌套处理
<mapper namespace="cn.com.entity.student.mapper">
<select id="getstudents" resultMap="StudentTeacher">
select s.id sid,s.name sname,s.tid stid,t.id tid,t.name tname from student s,teacher t where s.tid = t.id
</select>
<resultMap type="Student" id="StudentTeacher">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
<association property="teacher" javaType="Teacher">
<id column="tid" property="id"/>
<result column="tname" property="name"/>
</association>
</resultMap>
</mapper>
2,按查询嵌套处理
<select id="getstudents" resultMap="StudentTeacher">
select * from student
</select>
<resultMap type="Student" id="StudentTeacher">
<association property="teacher" column="tid" javaType="Teacher" select="cn.com.entity.teacher.mapper.getTeacher">
</association>
</resultMap>
<mapper namespace="cn.com.entity.teacher.mapper">
<select id="getTeacher" resultType="Teacher">
select * from teacher where id=#{id}
</select>
</mapper>
一对多
b,实体类
Student.java
c,编写映射文件teacher-mapper.xml
1,第一种
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid,s.name sname,s.tid stid,t.id tid,t.name tname from student s,teacher t where s.tid = t.id and t.id = #{id}
</select>
<resultMap type="Teacher" id="TeacherStudent">
<id column="tid" property="id"/>
<result column="tname" property="name"/>
<collection property="students" ofType="Student">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
</collection>
</resultMap>
2,第二种
<select id="getTeacher" resultMap="TeacherStudent">
select * from teacher where id = #{id}
</select>
<resultMap type="Teacher" id="TeacherStudent">
<collection property="students" javaType="ArrayList" ofType="Student"
column="id" select="getStudentByTid">
</collection>
</resultMap>
<select id="getStudentByTid" resultType="Student">
select * from student where tid = #{id}
</select>
动态sql
根据不同的查询条件,生成不同的sql语句
MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。
if
choose,when,otherwise
trim,where,set
foreach