Mybatis
Mybatis是一个基于java的持久层框架(半自动化的ORM框架)。
持久化:数据从瞬时状态变为持久状态。
持久层:完成持久化工作的代码块。
mybatis-config.xml配置文件:
<?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 指的是mybatis 可以配置多个环境模式 default指向默认的环境 每个SqlSessionFactory对应一个环境environment --> <environments default="development"> <environment id="development"> <!-- JDBC – 这个配置就是直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。 MANAGED – 这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。 --> <transactionManager type="JDBC"/> <!-- UNPOOLED– 这个数据源的实现只是每次被请求时打开和关闭连接。 POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这是 一种使得并发 Web 应用快速响应请求的流行处理方式。 JNDI – 这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="Mapper.xml"/> </mappers> </configuration>
mapper.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"> <mapper namespace="cn.user.UserMapper"> <select id="selectUser" resultType="cn.user.pojo.User"> select * from user where id = #{id} </select> <insert id="addUser" parameterType="cn.user.pojo.User" useGeneratedKeys="true"> insert into user(name,password) values(#{name},#{password}) </insert> <update id="updateUser" parameterType="cn.user.pojo.User"> update user set name=#{name},password=#{password} where id=#{id} </update> <delete id="deleteUser" parameterType="cn.user.pojo.User"> delete from user where id=#{id} </delete> </mapper>
User类
package cn.user.pojo; public class User { private int id; private String name; private String password; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
测试类:
package com.mybatis; import java.io.IOException; import java.io.InputStream; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import cn.user.pojo.User; public class Mybatis { private static SqlSession session = null; static { //1.读取mybatis的核心配置文件(mybatis-config.xml) InputStream in; try { in = Resources.getResourceAsStream("mybatis-config.xml"); //2.通过配置信息获取一个SqlSessionFactory工厂对象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); //3.通过工厂获取一个SqlSession对象 session = factory.openSession(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Test public void selectById() { User user = session.selectOne("cn.user.UserMapper.selectUser",1); System.out.println("id= "+user.getId()+"name="+user.getName()+"password="+user.getPassword()); session.close(); } @Test public void insert() { User user = new User(); user.setName("猪"); user.setPassword("123"); int rows = session.insert("cn.user.UserMapper.addUser",user); session.commit(); System.out.println(rows); session.close(); } @Test public void update() { User user = new User(); user.setId(4); user.setName("猪"); user.setPassword("123456"); int rows = session.update("cn.user.UserMapper.updateUser",user); session.commit(); System.out.println(rows); session.close(); } @Test public void delete() { int rows = session.delete("cn.user.UserMapper.deleteUser",4); session.commit(); System.out.println(rows); session.close(); } }
配置文件的优化
jdbc.properties配置文件:
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8 jdbc.username=root jdbc.password=root
mybatis-config.xml配置文件:
<?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> <properties resource="jdbc.properties"/> <!--environments 指的是mybatis 可以配置多个环境模式 default指向默认的环境 每个SqlSessionFactory对应一个环境environment --> <environments default="development"> <environment id="development"> <!-- JDBC – 这个配置就是直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。 MANAGED – 这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。 --> <transactionManager type="JDBC"/> <!-- UNPOOLED– 这个数据源的实现只是每次被请求时打开和关闭连接。 POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这是 一种使得并发 Web 应用快速响应请求的流行处理方式。 JNDI – 这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。 --> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="Mapper.xml"/> </mappers> </configuration>
<typeAliases > <!-- 为指定类型指名 别名 使得在mapper映射文件中可以简化引用 --> <typeAlias type="cn.user.pojo.User" alias="User"/> </typeAliases> resultType="cn.user.pojo.User" <!-- 等价 --> resultType="User"
简化:
<typeAliases > <!-- 为指定类型指别名 使得在mapper映射文件中可以简化引用 --> <!-- 为某个包下的类指定别名 默认别名就是类名--> <package name="cn.user.pojo.User"> </typeAliases> resultType="cn.user.pojo.User" <!-- 等价 --> resultType="User"
解决属性名和列名不一致:
1. 取别名
<select id="selectUser" resultType="cn.user.pojo.User"> select * from user where id = #{id} select id, username name, password password where id=#(id) </select>
2.设置结果映射类型
<resultMap type="Usr" id="UserMap"> <id column="id" property="id"/> <result column="username" property="name"/> <result column="password" property="password"/> </resultMap> <select id="selectUser" resultMap="UserMap"> select * from user where id = #{id} </select>
分页的实现
方法一:
<select id="selectUser" parameterType="map" resultType="cn.user.pojo.User"> select * from user limit #{startIndex},#{pageNum} </select>
public List<User> selectPage(int currentPage, int pageSize) { Map<String ,Integer> map = new HashMap<>(); map.put("startIndex", (currentPage-1)*pageSize); map.put("pageSize", pageSize); List<User> list = session.selectList("cn.user.UserMapper.selectUser",map); session.close(); return List; }
方法二:
<select id="selectUser" resultType="cn.user.pojo.User"> select * from user limit #{startIndex},#{pageNum} </select>
public List<User>selectPage(int currentPage, int pageSize) { RowBounds rowBounds = new RowBounds((currentPage-1)*pageSize,pageSize); List<User> list = session.selectList("cn.user.UserMapper.selectUser",null,rowBounds); List<User> list = session.selectList("cn.user.UserMapper.selectUser",map); session.close(); }
使用Mapper接口开发:
1.Mappper文件中的namespace属性要跟Mapper接口路径一致。
2.Mapper 接口中的方法名要与Mapper文件中的Id一致。
使用注解开发:
<mappers> <mapper resource="Mapper.xml"/> <!-- 加载注解 --> <mapper class="cn.user.dao.UserDao"/> </mappers>
创建接口类:
public interface UserDao { @Select("select *from user") public List<User> seleceList(); }
实现方法:
public void getAll() { UserDao userDao = session.getMapper(UserDao.class); List<User> list = userDao.selectList(); System.out.println(list); session.close(); }
多对一的处理:(多个学生对应一个老师)
实例类:
package cn.user.pojo; //Teacher lass Teacher { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } //Student public class Student { private int id; private String name; private Teacher teacher; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Teacher getTeacher() { return teacher; } public void setTeacher(Teacher teacher) { this.teacher = teacher; } }
Mapper文件:
1.按查询结果嵌套处理
<?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.user.StudentMapper"> <!-- 对多对一处理有两种方式 1.按查询结果嵌套处理 2.按查询嵌套处理 --> <!-- 按查询结果嵌套处理 --> <select id="getStudent" 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"/> <!-- 关联对象 关联对象在Student实体类中的属性--> <association property="teacher" javaType="Teacher"> <id column="tid" property="id"/> <result column="tname" property="username"/> </association> </resultMap> </mapper>
2.按查询嵌套处理:
<?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.user.StudentMapper"> <!-- 对多对一处理有两种方式 1.按查询结果嵌套处理 2.按查询嵌套处理 --> <!-- 按查询嵌套处理 --> <select id="getStudent" resultMap="StudentTeacher"> select * from student </select> <resultMap type="Student" id="StudentTeacher"> <!-- 如果查询语句在宁一个Mapper文件,需要namespace+类名 --> <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"> </association> </resultMap> <select id="getTeacher" resultType="Teacher"> select * from teacher where id=#{id} </select> </mapper>
一对多的处理:
1. 1.按查询结果嵌套处理
<?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.user.StudentMapper"> <!-- 对多对一处理有两种方式 1.按查询结果嵌套处理 2.按查询嵌套处理 --> <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="username"/> </collection> </resultMap> </mapper>
2.按查询嵌套处理
<?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.user.StudentMapper"> <!-- 对多对一处理有两种方式 1.按查询结果嵌套处理 2.按查询嵌套处理 --> <select id="getTeacher" resultMap="TeacherStudent"> select * from teacher } </select> <resultMap type="Teacher" id="TeacherStudent"> <collection property="students" ofType="Student" javaType="ArrayList" column="id" select="getStudentByid"> </collection> </resultMap> <select id="getStudentByid" resultType="Student"> select * from student where tid=#{id} </select> </mapper>
动态语句:动态sql根据不同的查询条件,生成不同的sql语句
<!-- 动态指定要查询的列 --> <select id="findAll2" resultType="Emp"> select ${cols} from Emp </select> <select id="findAll3" resultType="Emp"> select * from emp where name like '%${name}%' </select> <select id="findAll4" resultType="Emp"> select * from emp where name like #{name} </select> <select id="findBySal" resultType="com.tedu.pojo.Emp"> select * from emp <where> <if test="minSal!=null"> salary>=#{minSal} </if> <if test="maxSal!=null"> and salary <![CDATA[<=]]>#{maxSal} </if> </where> </select> <update id="update3"> update emp <set> <if test="name != null"> name=#{name}, </if> <if test="job != null"> job=#{job}, </if> <if test="salary != null"> salary=#{salary} </if> </set> where id=#{id} </update> <!-- 根据员工的id批量删除员工信息 --> <update id="deleteByIds"> delete from emp where id in <foreach collection="array" open="(" item="id" separator="," close=")"> #{id} </foreach> </update>
Mapper接口开发:
Mapper mapper = session.getMapper(xxxMapper.class);
mapper.findById(); (findById是接口中对应的方法)。
idea找不到资源文件解决办法
<resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources>