**********************************************************************************************一:mybatis概念1:简介 MyBatis本是apache的一个开源项目iBatis,2010年改名为 MyBatis, MyBatis 是一个基于Java的持久层框架。(操作数据库)2:优点 1:半自动化的ORM实现(实体类和SQL语句之间建立映射关系) 2:SQL代码从程序代码中彻底分离,可重用 3:与JDBC相比,减少了50%以上的代码量 4:小巧灵活、简单易学,是最简单的持久化框架 5:提供XML标签,支持编写动态SQL 6:提供映射标签,支持对象与数据库的ORM字段映射3:MyBatis缺点 1:SQL语句编写工作量大,对开发人员有一定sql技术要求 2:数据库移植性差(不同数据库,sql语句语法有所不同)*******************************************mybatis环境搭建开始******************************************
1:导入mybatis的jar包 mybatis-3.2.2.jar mysql-connector-java-5.1.25-bin.jar
2:创建mybatis的核心配置文件(mybatis-config.xml) <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> 驱动 <property name="url" value="jdbc:mysql://localhost:3306/y2t189?useUnicode=true&characterEncoding=utf-8" /> 数据库的url <property name="username" value="root" /> 用户名 <property name="password" value="zhangjiugui" /> 密码 </dataSource> </environment> </environments> <!-- dao层的mapper映射文件(xml) --> <mappers> <mapper resource="com/accp/y2t189/dao/UserMapper.xml" /> </mappers> </configuration>
3: 实体类
4:数据访问的接口(dao)
public List<User> findUsers();
5:接口与sql语句的映射 UserMapper.xml
命名空间必须是响应接口的全路径 <mapper namespace="com.accp.y2t189.dao.UserMapper"> id必须和接口中的方法名一致 resultType返回值类型(返回集合的话,指定集合元素的类型) <select id="findUsers" resultType="com.accp.y2t189.entity.User"> SELECT * FROM users </select>
</mapper>
6:mybatis的工具类
获得SqlSession ①:读取配置文件,创建session工厂 ②:在session工厂里,获得session会话 关闭session 判断session实例是否创建,不为null,就关闭session
/** * mybatis的工具类 * 获得session */ public class MybatisUtil { public static SqlSessionFactory sf; //session工厂 //获得session工厂 static { try { Reader is= Resources.getResourceAsReader("mybatis-config.xml"); sf= new SqlSessionFactoryBuilder().build(is); } catch (Exception e) { e.printStackTrace(); } } //获得session public static SqlSession getSession(){ return sf.openSession(); } //关闭session public static void closeSession(SqlSession session){ if(session !=null){ session.close(); } } }
7: 数据操作 //获得session session=MybatisUtil.getSession(); //获得接口实例 List<User> listUser=session.getMapper(UserMapper.class).findUsers(); //关闭session
*******************************************mybatis环境搭建结束*************************************************************************************增删改开始***************************************************
/** * 查询所有数据 * @return */ public List<User> findAll();****************** <select id="findAll" resultType="entity.User"> SELECT * FROM users </select>
**************************************************
/** * 根据编号查询对象 * @param 用户表的主键 * @return 一个对象user */ public User findById(Integer userId);****************** <select id="findById" parameterType="Integer" resultType="entity.User"> select * from users where id=#{userId} </select>
**************************************************
/** * 增加用户信息 * @param 一个对象数据 * @return 数据库的影响行数 */ public Integer add(User user);****************** <insert id="add" parameterType="entity.User"> INSERT INTO users VALUES(NULL,#{userName},#{password},#{realName}) </insert>
**************************************************
/** * 根据编号删除对象 * @param 用户表的主键 * @return 数据库的影响行数 */ public Integer delete(Integer id);****************** <delete id="delete" parameterType="Integer"> delete from users where id=#{id} </delete>
**************************************************
/** * 修改用户信息 * @param 一个对象数据 * @return 数据库的影响行数 */ public Integer update(User user);****************** <!-- 根据属性的主键修改其他的属性值--> <update id="update" parameterType="entity.User"> update users set userName=#{userName} ,password=#{password},realName=#{realName} where id=#{id} </update>
**************************************************
/** * 连表查询用户信息 * 在从表的实体类中添加级联查询主表中的属性 * SELECT u.*,rolename 在用户表中添加角色表的属性-角色名称 */ public List<User> findUserAndRole(); ****************** <select id="findUserAndRole" resultType="entity.User"> SELECT u.*,rolename FROM users u INNER JOIN role r ON u.`roleid`=r.`roleid` </select>************************************************** 模糊查询
//根据角色名称,模糊查询角色列表 public List<Role> findRoleByRoleName(String rolename); <!-- <select id="findRoleByRoleName" resultMap="roleMapping"> SELECT * FROM role where roleName like concat('%',#{rolename},'%') </select> --> <select id="findRoleByRoleName" resultMap="roleMapping"> SELECT * FROM role where roleName like "%"#{rolename}"%" </select>*******************************************增删改查结束**********************************************************************************************分页查询开始*************************************************** /** * 多参传入的方法: * 1:多个不同类型的参数入参时,映射文件中可以不指定参数类型, * 接口中的方法使用注解,将注解指定的名字,传入映射文件相应属性中 * 2:也可以把多个参数封装成对象,以对象类型入参 * 分页查询 * @param from 从第几条开始查... * @param pagesize 每页显示的记录数 * @return 当前页对象的集合 */ public List<User> fenye(@Param("from")Integer from,@Param("pagesize")Integer pagesize);****************** <select id="fenye" resultType="entity.User"> SELECT * FROM users u INNER JOIN role r ON u.`roleid`=r.`roleid` LIMIT #{from} ,#{pagesize} </select>***************************** /** * 查询总记录数 */ public Integer count();****************** <select id="count" resultType="Integer"> SELECT count(*) FROM users </select>
***************************** protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); res.setContentType("text/html;charset=utf-8"); SqlSession session=MybatisUtil.getSession(); //获得mybatis的session对象 try { Integer pagesize=3; //每页显示的记录数 Integer page=null; //当前页 String pageQian=req.getParameter("page"); if(pageQian !=null){ page=Integer.parseInt(pageQian); }else{ page=1; //默认看第一页 } /* * 数据库查询总页数 */ Integer count=session.getMapper(UserMapper.class).count(); int totalyeshu=0; //总页数 if(count%pagesize==0){ totalyeshu=count/pagesize; }else{ totalyeshu=(count/pagesize)+1; } /* * 数据库查询当前页的数据 */ List<User> userList=session.getMapper(UserMapper.class).fenye((page-1)*pagesize, pagesize); /* * 将数传给前台 */ req.setAttribute("USERLIST", userList); //集合数据 req.setAttribute("PAGE", page); //当前页 req.setAttribute("COUNT", totalyeshu); //总页数 } catch (Exception e) { e.printStackTrace(); }finally{ MybatisUtil.closeSession(session); } req.getRequestDispatcher("indexFenye.jsp").forward(req, res); //转发至主页 }***************************** <div> <h3 algin="right"> < <span style="font-size:12px;">共${COUNT }页 / 第${PAGE}页 </span> <c:if test="${PAGE>1 }"> <a href="fenye?page=1">首页</a> <a href="fenye?page=${PAGE-1}">上页</a> </c:if> <c:forEach begin="1" end="${COUNT }" var="i"> <a href="fenye?page=${i}" >${i}</a> </c:forEach> <c:if test="${PAGE<COUNT }"> <a href="fenye?page=${PAGE+1}">下页</a> <a href="fenye?page=${COUNT}">尾页</a> </c:if> <span style="font-size:12px;">GO</span> <select id="goTo" οnchange="goPage(this.value)" > <c:forEach begin="1" end="${COUNT }" var="i" > <option value="${i }" ${i==PAGE?"selected='selected'":"" } >${i }</option> </c:forEach> </select> <span style="font-size:12px;">页</span> > </h3> <script> function goPage(page){ window.location.href="fenye?page="+page; } </script> </div>
*******************************************分页查询结束***************************************************
*******************************************配置文件开始*************************************************** 打印测试的日志信息
1:导入jar包 log4j-1.2.17.jar
2:在src下编写配置文件 log4j.properties
3:log4j.properties内容如下:
## debug 级别 log4j.rootLogger=DEBUG,Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.Target=System.out log4j.appender.Console.layout = org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=%d{yyyy-MM-dd-HH\:mm\:ss,SSS} [%t] [%c] [%p] - %m%n log4j.logger.com.mybatis=DEBUG
##输出sql 语句 log4j.logger.java.sql.Connection=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG</strong>
4:配置 mybatis-config.xml
<configuration> <settings> <setting name="logImpl" value="LOG4J" /> </settings> <environments default="development"> </environments> </configuration>
************************************************** 别名的创建
<settings> </settings>
<!--类型别名 :可以在Mapper.xml映射中使用别名代替全路径名--> <typeAliases> <!--type:类型的全路径 alias:替代类型的别名 --> <typeAlias alias="User" type="cn.zx.pojo.User"/> <!--自动扫描此包下的所有javabean,自动生成一个默认别名,就是类名 --> <!--<package name="cn.smbms.pojo"/>--> </typeAliases> <environments default="development"> </environments>
************************************************** 数据库的数据源参数与核心配置文件分离
1:创建src下database.properties文件
2:在database.properties下面写:
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/y2t189?useUnicode=true&characterEncoding=utf-8 user=root password=zhangjiugui
3:在 mybatis-config.xml下面配置
<configuration>
<!-- 引入 database.properties 文件--> <properties resource="database.properties"/>
<settings> </settings> 4:将 mybatis-config.xml文件中的参数,改为 ${database.properties配置文件中相应的key} <property name="driver" value="${driver}"/>
************************************************** 类中的字段与数据库中的属性命名不匹配
一:类中的字段与数据库中的属性命名必须一致,那么框架才会自动为我们做数据库中sql语句查询出的列与类中的属性映射
二:类中的字段与数据库中的属性命名不匹配
<!--resultMap解决映射问题 type:映射类型 id:唯一标识 --> <resultMap type="entity.Role" id="roleMapping"> <!--主键用id标签 property:实体类中的id属性 column:数据库中id属性对应的主键列--> <id property="id" column="roleid"></id> <!--非主键列 property:实体类中的相应属性 column:数据库中相应属性对应的数据库的列--> <result property="name" column="roleName"/> </resultMap>
<!--映入自定义的映射,使用resultMap属性 --> <select id="findRole" resultMap="roleMapping"> SELECT * FROM role </select>
*******************************************配置文件结束***************************************************
*******************************************动态查询开始*************************************************** if动态查询 /** * 一:动态查询 */ public List<User> findUsers(@Param("userName")String userName,@Param("roleName")String roleName);****************** <select id="findUsers" resultType="entity.User"> SELECT u.*,rolename FROM users u INNER JOIN role r ON u.`roleid`=r.`roleid` where 1=1 <if test="userName !='' and userName !=null"> and userName=#{userName} </if> <if test="roleName !='' and roleName !=null"> and roleName=#{roleName} </if> </select>
************************************************** if+where组合配置
public List<User> find(User user);
<!-- if+where:在包含语句前添加一个where 并 智能判断where、and、or关键字是否添加, 无需考虑因此产生的语法错误 --> <select id="find" parameterType="entity.User" resultType="entity.User"> SELECT * FROM smbms_user u,smbms_role r <where> <if test="address!='' and address!=null">and address like CONCAT('%',#{address},'%')</if> <if test="roleName!='' and roleName!=null">and roleName like CONCAT('%',#{roleName},'%')</if> </where> order by userRole desc </select>
************************************************** <!-- foreach (在实现 mybatis in 语句查询时特别有用) 你可以传递一个List实例或者数组作为参数对象传给MyBatis 配置文件中的parameterType是可以不配置的 参数: 1:collection:传进来的参数类型 List集合写成:”list” 数组写成:”array”, 其他复杂类型写成:包含结果集List集合,在整个map集合中的键 2:item:临时变量(每一个迭代元素的别名) 3:open:该语句以什么开始 4:close:该语句以什么结束 5:separator:多个迭代元素以什么分隔(符) -->
sql语句in关键字的用法
//根据部门条件,获取用户表数据列表-foreach_list public List<User> getUserByDepId_foreach_list(List<String> roleIdList);
<!-- foreach(循环List<String>参数) - 作为where中in的条件 --> <select id="getUserByDepId_foreach_list" resultType="cn.zx.pojo.User"> select * from smbms_user where userRole in <foreach collection="list" item="roleIds" open="(" separator="," close=")"> #{roleIds} </foreach> </select>
测试类 List<String> list=new ArrayList<String>(); list.add("教员"); list.add("经理");
*******************************************动态查询结束**********************************************************************************************配置一对多双向映射开始*****************************************
CREATE TABLE `smbms_role` ( `id` int(10) NOT NULL PRIMARY KEY COMMENT '主键ID', `roleName` varchar(15) NOT NULL COMMENT '角色名称') COMMENT= '角色表'
CREATE TABLE `smbms_user` ( `id` bigint(20) PRIMARY KEY NOT NULL COMMENT '主键ID', `userName` varchar(15) NOT NULL COMMENT '用户名称', `userPassword` varchar(15) NOT NULL COMMENT '用户密码', `address` varchar(30) NULL COMMENT '地址', `userRole` int(10) NULL COMMENT '角色id') COMMENT= '用户表'
**************************************************复杂映射的环境的使用场合: 1:在得到所有用户信息的同时又要得到每位用户的角色信息(一对一,在多方添加一个一方的实体属性)association 在得到所有角色信息的同时又要得到每个角色下的所有用户信息列表(一对多,在一方添加一个多方的集合属性)collection
用户:多方 角色:一方 resultMap的复杂应用 1:resultMap属性 ①id:resultMap的唯一标识 ②type:(映射结果的类型)Java实体类
2:resultMap子元素 ①id:映射对应主键id,设置此项可提高MyBatis性能
②result:映射非主键id property属性:映射数据库列的实体对象的属性 column属性:数据库列名或者别名
③association: 映射到JavaBean的某个“复杂类型”属性,比如JavaBean类 复杂的类型关联,一对一内部嵌套 映射一个嵌套JavaBean属性 A: association属性: property属性:映射数据库列的实体对象的属性名 javaType属性:完整Java类名或者别名 resultMap属性:引用外部resultMap B: association子元素 id:映射association属性的javaType类的主键 result:映射association属性的javaType类的简单属性 property属性:映射数据库列的实体对象的属性 column属性:数据库列名或者别名 ④collection: 映射到JavaBean的某个“复杂类型”属性,比如集合 复杂类型集合,一对多,内部嵌套,映射一个嵌套结果集到一个列表 A:collection:属性 property:映射数据库列的实体对象的属性 ofType:完整Java类名或者别名(集合所包括的类型) resultMap:引用外部resultMap
注意:如果映射中出现不同字段,的名字一样,需要指定别名区分。**************************************************/** * 根据用户编号获取此用户下的用户信息,及每个用户的角色信息(association) */ public List<User> findRoleByUserId(Integer id);
<!— 根据用户编号获取此用户下的用户信息,及每个用户的角色信息 1:在用户表中添加 private Role role; 属性 及 getset方法 2:<resultMap>:必须将要查的字段,全部映射,不然查不到数据... (除非将mybatis全局配置文件中设置自动映射级别为FULL) 3:association:映射单个属性(多对一的关系) 4:如果映射中出现不同字段,的名字一样,需要指定别名区分。(以下标红字体部分) --> <resultMap type="entity.User" id="userInRole"> <id property="id" column="id"/> <result property="userName" column="userName"/> <result property="userPassword" column="userPassword"/> <result property="address" column="address"/> <result property="userRole" column="userRole"/> <association property="role" javaType="entity.Role"> <id property="id" column="r_id"/> <result property="roleName" column="roleName"/> </association> </resultMap> <select id="findRoleByUserId" parameterType="Integer" resultMap="userInRole"> SELECT u.*,r.`id` AS r_id ,r.roleName FROM smbms_user u , smbms_role r WHERE u.`userRole`=r.id AND u.`id`=#{id}</select>
public void findRoleByUserId(){ session=MybatisUtil.getSqlSession(); List<User> list=session.getMapper(InfoMapper.class).findRoleByUserId(1); for(User user :list){ System.out.println(user.getId()+"\t"+user.getUserName()); System.out.println("\t\t"+user.getRole().getId()+"\t" +user.getRole().getRoleName()); } }**************************************************/*** 获取指定角色编号下的用户列表(collection)*/ public List<Role> findUserByRoleId(Integer id);
<!— 获取指定角色编号下的用户列表 在角色表中添加属性:private List<User> userList; 及getset方法 获取指定角色的用户列表(collection) 映射一对多关系的关系 --> <resultMap type="entity.Role" id="roleInUser"> <id property="id" column="r_id"/> <result property="roleName" column="roleName"/> <collection property="userList" ofType="entity.User" resultMap="userInRole" /> </resultMap> <select id="findUserByRoleId" parameterType="Integer" resultMap="roleInUser"> SELECT u.*,r.`id` AS r_id ,r.roleName FROM smbms_user u , smbms_role r WHERE u.`userRole`=r.id AND r.id=#{id} </select>
public void findUserByRoleId(){ session=MybatisUtil.getSqlSession(); List<Role> list=session.getMapper(InfoMapper.class).findUserByRoleId(1); for(Role role :list){ System.out.println(role.getId()+"\t"+role.getRoleName()); for(User user :role.getUserList()){ System.out.println("\t\t"+user.getUserName()+"\t"+user.getUserPassword()); } } }************************************************** <!— 基于映射复用的写法 <resultMap type="entity.User" id=" userInRole "> <id property="id" column="id"/> <result property="userName" column="userName"/> <result property="userPassword" column="userPassword"/> <result property="address" column="address"/> <association property="role" javaType="cn.zx.pojo.Role" resultMap="roleResult"/> </resultMap> <resultMap type="cn.zx.pojo.Role" id="roleResult"> <id property="id" column="r_id"/> <result property="roleName" column="roleName"/> </resultMap> -->*******************************************配置一对多双向映射结束******************************************************************************配置文件补充开始*****************************************<configuration> <settings> <!-- 实体类的属性,与数据库中的列,映射设置 设置resultMap的自动映射级别为: NONE :禁止自动匹配 <resultMap>中必须将所有需要的实体类的属性,与数据库中的列,全部映射上 PARTIAL(默认) 自动匹配所有属性(含有association,collection的<resultMap>除外) FULL :自动匹配所有 --> <setting name="autoMappingBehavior" value="PARTIAL" /> </settings>
</configuration>************************************************** public static SqlSession createSqlSession(){ //true 关闭事务控制 默认为true 在增删改的时候有一定危险(无需手动提交或回滚事务) //false 开启事务控制 提交sqlSession.commit(); 回滚sqlSession.rollback(); return factory.openSession(false);}*******************************************配置文件补充结束************************************************************************************动态查询拓展*********************************************<!-- choose (when:分支条件 ,otherwize:以上条件都不满足执行此) 注意:此种查询结果为:只满足一种条件就执行查询--><select id="getUserList_choose" resultType="User"> select * from smbms_user where 1=1 <choose> <when test="userName != null and userName != ''"> and userName = #{userName} </when> <when test="userRole != null"> and userRole= #{userRole} </when> <otherwise> and id=#{id} </otherwise> </choose></select>*******************************************
//修改 public int updateUser(User user);
<!--if/set(判断参数) 用于更新操作,在包含语句前添加一个set 并 他将自动智能判断每个if条件后是否添加",")--><update id="updateUser" parameterType="entity.User"> update smbms_user <set> <if test="userName!='' and userName!=null">userName=#{userName},</if> <if test="address!='' and address!=null">address =#{address},</if> <if test="roleName!='' and roleName!=null">roleName =#{roleName},</if> <if test="userPassword!='' and userPassword!=null"> userPassword =#{userPassword}, </if> <if test="userRole!='' and userRole!=null">userRole =#{userRole},</if> </set> where id=#{id} </update> <!— 对整个trim包含的内容智能自动判断是否加上 prefix前缀,或者 suffix后缀 prefixOverrides:自动判断子语句if前面的条件语句是否添加或不添加其值 suffixOverrides:自动判断子语句if后边的条件语句是否添加或不添加其值 --><update id="updateUser" parameterType="entity.User"> update smbms_user <trim prefix="set" suffixOverrides="," suffix="where id=#{id}"> <if test="userName!='' and userName!=null">userName=#{userName},</if> <if test="address!='' and address!=null">address =#{address},</if> <if test="roleName!='' and roleName!=null">roleName =#{roleName},</if> <if test="userPassword!='' and userPassword!=null"> userPassword =#{userPassword}, </if> <if test="userRole!='' and userRole!=null">userRole =#{userRole},</if> </trim></update> *******************************************<!-- foreach (在实现 mybatis in 语句查询时特别有用) 你可以传递一个List实例或者数组作为参数对象传给MyBatis 配置文件中的parameterType是可以不配置的 参数: 1:collection:传进来的参数类型 List集合写成:”list” 数组写成:”array”, 其他复杂类型写成:包含结果集List集合,在整个map集合中的键 2:item:临时变量(每一个迭代元素的别名) 3:open:该语句以什么开始 4:close:该语句以什么结束 5:separator:多个迭代元素以什么分隔(符) -->//根据部门条件,获取用户表数据列表-foreach_arraypublic List<User> getUserByDepId_foreach_array(String[] arrys);
<!-- foreach(循环array参数) - 作为where中in的条件 --><select id="getUserByDepId_foreach_array" resultType="cn.zx.pojo.User"> select * from smbms_user where userRole in <foreach collection="array" item="roleId" open="(" separator="," close=")"> #{roleId} </foreach></select>
String[] depIds = {"1","2"};sqlSession = MyBatisUtil.createSqlSession();List<User> userList = new ArrayList<User>();userList = sqlSession.getMapper(SqlQrendMap.class).getUserByDepId_foreach_array(depIds);
*************************** //根据部门条件,获取用户表数据列表-foreach_listpublic List<User> getUserByDepId_foreach_list(List<String> roleIdList);
<!-- foreach(循环List<String>参数) - 作为where中in的条件 --><select id="getUserByDepId_foreach_list" resultType="cn.zx.pojo.User"> select * from smbms_user where userRole in <foreach collection="list" item="roleIds" open="(" separator="," close=")"> #{roleIds} </foreach></select>
List<String> depIdList = new ArrayList<String>();depIdList.add("1");depIdList.add("2");depIdList.add("4");sqlSession = MyBatisUtil.createSqlSession();List<User> userList = new ArrayList<User>();userList = sqlSession.getMapper(SqlQrendMap.class).getUserByDepId_foreach_list(depIdList);*************************** //根据用户角色列表和性别(多参数),获取该角色列表下并指定性别的用户列表信息-foreach_map --> public List<User> getUserByConditionMap_foreach_map(Map<String,Object> map);<select id="getUserByConditionMap_foreach_map" resultType="cn.zx.pojo.User"> select * from smbms_user where userName = #{userName} and userRole in <foreach collection="roleIds" item="roleMap" open="(" separator="," close=")"> #{roleMap} </foreach></select>List<Integer> roleList = new ArrayList<Integer>(); roleList.add(1); roleList.add(3);Map<String, Object> conditionMap = new HashMap<String,Object>(); conditionMap.put("userName", "admin"); conditionMap.put("roleIds",roleList);List<User> userList = new ArrayList<User>();userList = sqlSession.getMapper(SqlQrendMap.class).getUserByConditionMap_foreach_map(conditionMap);
*******************************************动态查询拓展*****************************************
转载于:https://www.cnblogs.com/zhuhuibiao/p/9825301.html