持久层框架:mybatis(半自动,一般使用于大型项目),hibernate(全自动,适用于小型,简单的项目),spring DataJPA,spring jdbcTemplate(一般不使用)
-
Mybatis框架
1.什么是mybatis?
MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生信息,将接口和Java的POJOs(Plain Ordinary Java Object,普通的Java对象)映射成数据库中的记录
2.MyBatis优缺点
优点:MyBatis几乎避免了所有的jdbc代码,能自动映射,让程序员把精力放在sql语句上,属于半自动的持久层框架,支持定制sql,可以根据需求编写sql语句,也可以自动生成;
缺点:sql语句多,还是有缺陷的;
3.MyBatis开发有三种模式:
3.1:Dao+DaoImpl(不常用)
3.1.2:mybatis-configs.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> <!-- 配置读取db.properteis的标签 --> <properties resource="db.properties"></properties> <!-- 开发环境 --> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"></transactionManager> <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="com/oracle/pojo/User.xml"></mapper> </mappers> </configuration>
3.1.3: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"> <mapper namespace="haha"> <select id="getUser" parameterType="string" resultType="com.oracle.pojo.User"> select * from `user` where username = #{username} and `password` = #{password}; </select> <select id="getOne" parameterType="java.lang.Integer" resultType="com.oracle.pojo.User"> select * from `user` where uid = #{uid} </select> </mapper>
3.1.4:UserDao
public interface UserDao { //登录 public User getUserByUsernameAndPassword(String username, String password)throws Exception; public User getUserbyUid(Integer uid)throws Exception; }
3.1.5 : UserDaoImpl
public class UserDaoImpl implements UserDao{ @Override public User getUserByUsernameAndPassword(String username, String password) throws Exception{ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); User user = new User(); user.setUsername(username); user.setPassword(password); Object obj = sqlSession.selectOne("haha.getUser", user); //关闭资源 SqlSessionUtil.close(sqlSession); return (User)obj; } @Override public User getUserbyUid(Integer uid) throws Exception { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); Object obj = sqlSession.selectOne("haha.getOne", uid); SqlSessionUtil.close(sqlSession); return (User)obj; } }
3.1.6 : Test
public class TestMybatis { @Test public void test2() throws Exception { UserDao userDao = new UserDaoImpl(); User user = userDao.getUserbyUid(2); System.out.println(user); } @Test public void test1() throws Exception { UserDao userDao = new UserDaoImpl(); User user = userDao.getUserByUsernameAndPassword("张三", "123"); System.out.println(user); } }
3.1.7 : SqlSessionFactory封装
public class SqlSessionUtil { //初始化属性 private static SqlSession sqlSession = null; private static SqlSessionFactory sqlSessionFactory = null; //私有构造器 private SqlSessionUtil(){} //静态块儿加载 static{ try { InputStream ips = Resources.getResourceAsStream("mybatis-config.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips); } catch (IOException e) { e.printStackTrace(); } } //静态方法获取sqlSession会话 public static SqlSession getSqlSession(){ if(sqlSession == null){ sqlSession = sqlSessionFactory.openSession(); } return sqlSession; } //关闭资源 public static void close(SqlSession sqlSession){ if(sqlSession != null){ sqlSession.close(); } } }
3.2.1:增删改操作
3.2.1.1添加UserDao: public int insertUser(User user)throws Exception; UserDaoImpl: @Override public int insertUser(User user) throws Exception { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); int a = sqlSession.insert("user.insertUser", user); //手动提交 sqlSession.commit(); //关闭资源 SqlSessionUtil.close(sqlSession); return a; } //user.xml <insert id="insertUser"> insert into `user`(uid,username,password,address) values(null,#{username},#{password},#{address}) </insert>
3.2.1.2 修改
UserDao: public int updateUserById(User user)throws Exception; UserDaoImpl: @Override public int updateUserById(User user) throws Exception { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); int a = sqlSession.update("user.updateUserByUid", user); //手动提交 sqlSession.commit(); SqlSessionUtil.close(sqlSession); return a; //user,xml <update id="updateUserByUid"> update `user` set username = #{username} , `password` = #{password} , address = #{address} where uid = #{uid} </update> }
3.2.1.3 删除
UserDao: public int deleteUserById(Integer id)throws Exception; UserDaoImpl: @Override public int deleteUserById(Integer id) throws Exception { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); int a = sqlSession.delete("user.deleteUserByUid", id); //手动提交 sqlSession.commit(); SqlSessionUtil.close(sqlSession); return a; //user,xml <delete id="deleteUserByUid"> delete from `user` where uid = #{uid} </delete> }
3.2.1.4 分页查询
UserDao: public List<User> getUserByLimit(Map<String,Integer> map)throws Exception; UserDaoImpl: @Override public List<User> getUserByLimit(Map<String,Integer> map) throws Exception { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); List<User> list = sqlSession.selectList("user.getUserByLimit", map); return list; //user,xml <select id="getUserByLimit" resultType="user"> select * from `user` limit #{startRow},#{pageSize} </select> }
测试类:
@Test public void test7() throws Exception { Map<String,Integer> map = new HashMap<>(); Integer pageNo = 2; Integer pageSize = 5; //map集合的key 是 #{名} value是具体值 map.put("startRow",(pageNo-1)*pageSize); map.put("pageSize",pageSize); List<User> list = userDao.getUserByLimit(map); for (User user : list) { System.out.println(user); } }
3.2:mapper动态代理开发(重点)
什么是代理模式?
用大白话解释就是,程序员不用编写DaoImpl实现类,让MyBatis帮我们就行,那么MyBatis就是一个代理商,帮我们完成实现,体现在代码上就是以后没有daoImpl实现类,只有Dao存在。但是使用代理模式必须满足4个条件:
1.Dao中的方法名必须和select标签,update,delete,insert标签的id一致;
2.mapper标签的namespace的值必须是接口的全路径名<mapper namespace ="com.oracle.mapper.UserMapper"></mapper>
3.dao方法中的入参的类型必须和select,update,insert标签的parameterType类型一致
4.dao方法中的返回值类型,必须和select表亲的resultType类型一样
3.2.1:代码案例
UserMapper.javapublic interface UserMapper { //模糊查询带分页 public List<User> getUserByLikeWithLimit(@Param("like") String like , @Param("startRow") Integer startRow, @Param("pageSize") Integer pageSize); //模拟登录 public User getUserByUserNameAndPassword(@Param("username") String username, @Param("password") String password); //根据id查询 public User getUserByUid(Integer uid)throws Exception; ; //根据id删除 public int deleteUserByUid(Integer uid)throws Exception; //根据id修改 public int updateUserByUid(User user)throws Exception; //插入 public int insertUser(User user)throws Exception; //模糊查询 public List<User> getUserByLike(String like)throws Exception; }
UserMapper.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命名空间一定是 与 接口全路径名一致 --> <mapper namespace="com.oracle.mapper.UserMapper"> <!-- id属性的值 一定与 接口中的方法名一致 --> <select id="getUserByUserNameAndPassword" resultType="user"> select * from `user` where username = #{username} and `password` = #{password} </select> <delete id="deleteUserByUid"> delete from `user` where uid = #{uid} </delete> <select id="getUserByLike" resultType="user"> select * from `user` where username like concat('%',#{like},'%') </select> <select id="getUserByLikeWithLimit" resultType="user"> select * from `user` where username like concat('%',#{like},'%') limit #{startRow},#{pageSize} </select> </mapper>
Test.java
public class TestUserMapper { /** * 模糊查询带分页 单元测试 * @throws Exception */ @Test public void test5() throws Exception { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); //调用自己的方法 int startRow = (2-1)*2; List<User> list = mapper.getUserByLikeWithLimit("张",startRow,2); for (User user : list) { System.out.println(user); } sqlSession.close(); } }
3.2.2:动态sql
查询案例: sql的字段片段 <sql id="userColumns"> uid,username,`password`,address </sql>
修改: <update id="updateUserByUid"> update `user` <set> <if test=" username != null and username != ''"> username = #{username}, </if> <if test=" password != null and password != ''"> `password` = #{password}, </if> <if test=" address != null and address != ''"> address = #{address} </if> </set> <where> uid =#{uid} </where> </update>
查询语句的动态sql: <select id="getUserByLikeWithLimit" resultType="user"> select <include refid="userColumns"></include> from `user` <where> <if test=" like != null and like != '' "> username like concat('%',#{like},'%') </if> </where> <if test="startRow !=null"> limit #{startRow},#{pageSize} </if> </select>
3.2.3批量删除
//批量删除 public int deletesByUids(int[] ids)throws Exception;
<!--批量删除--> <delete id="deletesByUids"> delete from `user` <where> uid in <foreach item="a" collection="array" open="(" close=")" separator=","> #{a} </foreach> </where> </delete>
3.2.4主键回填
<insert id="insertUser" useGeneratedKeys="true" keyProperty="uid" > <!-- 主键回填技术 这个只适用于 mysql ,如果是oracle数据库就使用 (useGeneratedKeys="true" keyProperty="uid") <selectKey keyProperty="uid" order="AFTER" resultType="int"> select LAST_INSERT_ID(); </selectKey> --> insert into `user`(uid,username,`password`,address) values(null,#{username},#{password},#{address}) </insert>
@Test public void test8() throws Exception { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setUsername("呵呵"); user.setPassword("123123"); user.setAddress("上海"); mapper.insertUser(user); //在插入成功后 获取 对象的 uid值 这里体现了 主键回填技术 System.out.println(user.getUid()); sqlSession.commit(); sqlSession.close(); }
3.3.1:ResultMap标签
作用1:如果数据库表的字段名和java实体属性名不一致就需要通过resultMap标签来手动映射<resultMap id="userResultMap" type="user"> <!--代表了当前表的 主键 column:代表的数据库表的字段名 property: 代表的是java类中的属性名 javaType: 是java类型的全路径名 jdbcType: 数据库的数据类型 ,必须大写字母 --> <id column="uid" property="id" javaType="java.lang.Integer" jdbcType="INTEGER"></id> <!--其他字段--> <result column="username" property="name"></result> <result column="password" property="pwd"></result> </resultMap>
<select id="getUserByUserNameAndPassword" resultMap="userResultMap"> select <include refid="userColumns"></include> from `user` <where> <if test="username != null and username != ''"> and username =#{username} </if> <if test="password != null and password != ''"> and password = #{password} </if> </where> </select>
作用2:级联查询(表关联查询)
一对一查询:
mapper接口:public interface CardMapper { public Card getUserByCode(String code)throws Exception; }
CardMapper.xml:
<resultMap id="cardResultMap" type="card"> <id column="cid" property="cid"></id> <result column="number" property="number"></result> <result column="uid" property="uid"></result> <!--user 跟car但是 一对一 property属性代表 Card实体类中的 user属性名 column代表card表的 外键字段 select 去另一个空间做另一个表的查询操作,好处解耦 --> <association property="user" column="uid" select="com.oracle.mapper.UserMapper.getUserByUid"> </association> </resultMap> <!--如果你不会写多表查询的时候 --> <select id="getUserByCode" resultMap="cardResultMap"> select cid,number,uid from card where number = #{number} </select>
UserMapper.xml:
<mapper namespace="com.oracle.mapper.UserMapper"> <!--这个标签 是为了 级联查询的 --> <select id="getUserByUid" resultMap="userResultMap"> select * from `user` where uid = #{uid} </select> </mapper>
单元测试:
@Test public void test() throws Exception { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); CardMapper mapper = sqlSession.getMapper(CardMapper.class); Card card = mapper.getUserByCode("110"); System.out.println(card); User user = card.getUser(); System.out.println(user); }
一对多级联查询:
UserMapper://根据用户id 查询订单 public User getOrdersByUid(Integer uid)throws Exception;
UserMapper.xml
<mapper namespace="com.oracle.mapper.UserMapper"> <resultMap id="userResultMap" type="user"> <!--代表了当前表的 主键 column:代表的数据库表的字段名 property: 代表的是java类中的属性名 javaType: 是java类型的全路径名 jdbcType: 数据库的数据类型 ,必须大写字母 --> <id column="uid" property="id" javaType="java.lang.Integer" jdbcType="INTEGER"></id> <!--其他字段--> <result column="username" property="name"></result> <result column="password" property="pwd"></result> <!--多方 orders propertyL: user实体类中的 orders 属性名 column: 当前uid主键 是 order表的外键 ofType: User实体类中集合的泛型 order类型 --> <collection property="orders" column="uid" ofType="order" select="com.oracle.mapper.OrderMapper.getOrdersByUid"> </collection> </resultMap> <!-- 根据 用户 uid 查询所有 订单 --> <select id="getOrdersByUid" resultMap="userResultMap"> select * from `user` where uid = #{uid} </select> </mapper>
OrderMapper.xml
<select id="getOrdersByUid" resultType="order"> select * from `order` where uid = #{uid} </select>
测试类:
@Test public void test9() throws Exception { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.getOrdersByUid(14); List<Order> orders = user.getOrders(); for (Order order : orders) { System.out.println(order); } }
根据订单编号找人:
OrderMapper接口:public interface OrderMapper { //根据订单找人 public Order getUserByCode(String code)throws Exception; }
OrderMapper.xml
<mapper namespace="com.oracle.mapper.OrderMapper"> <resultMap id="orderResultMap" type="order"> <!--user 的 一方--> <association property="user" column="uid" select="com.oracle.mapper.UserMapper.getUserByUid"> </association> </resultMap> <select id="getOrdersByUid" resultType="order"> select * from `order` where uid = #{uid} </select> </mapper>
UserMapper.xml
<mapper namespace="com.oracle.mapper.UserMapper"> <!--这个标签 是为了 级联查询的 --> <select id="getUserByUid" resultMap="userResultMap"> select * from `user` where uid = #{uid} </select> </mapper>
测试类:
@Test public void test1() throws Exception { 1 SqlSession sqlSession = SqlSessionUtil.getSqlSession(); OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); Order order = orderMapper.getUserByCode("DFJ23"); User user = order.getUser(); System.out.println(user); }
多对多:
OrderMapper.java//根据订单编号查询商品 public Order getProductByCode(String code)throws Exception;
OrderMapper.xml
<mapper namespace="com.oracle.mapper.OrderMapper"> <resultMap id="OrderResultMapper" type="order"> <id column="oid" property="oid"></id> <association property="user" column="uid" select="com.oracle.mapper.UserMapper.getUserByUid"> </association> <collection property="products" column="oid" ofType="product" select="com.oracle.mapper.ProductMapper.getProductByOid"> </collection> </resultMap> //根据订单编号查询订单oid 再根据多表itms查对应的pid <select id="getUserByCode" resultMap="OrderResultMapper"> select * from `order` where code =#{code} </select> //根据多个oid找多个订单 <select id="getOrderByPid" resultMap="OrderResultMapper"> select * from order_product_item opi inner join `order` o on opi.oid = o.oid where opi.pid =#{pid} </select> </mapper>
ProductMapper.java
//跟据商品名字查订单 public Product getOrderByProductName(String productName)throws Exception;
ProductMapper.xml
<mapper namespace="com.oracle.mapper.ProductMapper"> <resultMap id="ProductResultMap" type="product"> <id property="pid" column="pid"></id> <collection property="orders" column="pid" ofType="order" select="com.oracle.mapper.OrderMapper.getOrderByPid"></collection> </resultMap> //根据多个pid找多个商品 <select id="getProductByOid" resultMap="ProductResultMap"> select * from order_product_item opi inner join product p on opi.pid = p.pid where oid=#{oid} </select> //根据商品名称查询订单pid 再根据多表itms查对应的oid <select id="getOrderByProductName" resultMap="ProductResultMap"> select * from `product` where produceName=#{productName} </select> </mapper>
3.3 注解开发(不太推荐,耦合度高)
public interface UserMapper { @Select("select * from `user` where username =#{username} and password = #{password}") public User getUserByUserNameAndPassword(@Param("username") String username, @Param("password") String password)throws Exception; @Insert("insert into user(uid,username,password,address) values(null,#{username},#{password},#{address})") @SelectKey(statement = "select LAST_INSERT_ID()",keyProperty="nameId", before=true, resultType=int.class) public void insertUser(User user)throws Exception; }
3.4日志
mybatis的日志有两种形式,输出mybatis的执行过成,包括sql语句的执行
1.使用mybatis默认的日志框架:不需要导入jar包<!-- 运行参数 --> <settings> <!-- mybatis 默认的日志 --> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
2.使用LOG4J日志框架,需要导入jar包和log4j.properties日志文件
<!-- 运行参数 --> <settings> <!-- mybatis 默认的日志 --> <setting name="logImpl" value="LOG4J"/> </settings>
LOG4J文件,放在src目录上:
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码 log4j.rootLogger=DEBUG,console,file #控制台输出的相关设置 log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.Target = System.out log4j.appender.console.Threshold=DEBUG log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=[%c]-%m%n #文件输出的相关设置 log4j.appender.file = org.apache.log4j.RollingFileAppender log4j.appender.file.File=./log/shun.log log4j.appender.file.MaxFileSize=10mb log4j.appender.file.Threshold=DEBUG log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n #日志输出级别 log4j.logger.org.mybatis=DEBUG log4j.logger.java.sql=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.ResultSet=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG
3.5 延迟加载(按需加载)
<settings> <!-- mybatis 默认的日志 --> <setting name="logImpl" value="LOG4J"/> <!-- 设置延迟加载吗 设置 true--> <setting name="lazyLoadingEnabled" value="true"/> <!-- 积极加载吗 不滴--> <setting name="aggressiveLazyLoading" value="false"/> <setting name="lazyLoadTriggerMethods" value=","/> </settings>
3.6mybatis的分页插件:
mybatis采用分页插件时,sql不需要写limit分页了,但是需要导入jar包
1.pagehelpher-5.1.1.jar
2.jsqlparser-1.0.jar<?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> <!--插件 --> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- 指定数据库版本名 是什么 --> <property name="helpDialect" value="mysql"/> <!-- 合理化 true: 如果pageNum < 1 ,他给你返回第一页 ,如果pageNum > totalPage 返回最后一页 合理化 false: 如果pageNum < 1 ,返回 空 ,如果pageNum> totalPage 返回 空 --> <property name="seasonable" value="true"/> </plugin> </plugins> </configuration>
@Test public void test10() throws Exception { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); //分页插件对象 Integer pageNum = 1; Integer pageSize = 5; PageHelper.startPage(pageNum,pageSize); List<User> list = mapper.getAll(); //sql 语句中 没有 limit 关键字 PageInfo pageInfo = new PageInfo<>(list); System.out.println("当前页: "+pageInfo.getPageNum()); System.out.println("页大小: "+pageInfo.getPageSize()); System.out.println("总记录数: "+pageInfo.getTotal()); System.out.println("总页数: "+pageInfo.getPages()); //从PageInfo对象中获取的数据 List users = pageInfo.getList(); for (Object user : users) { System.out.println(user); } }
3.7 mybatis的缓存
一级缓存:mybatis默认的就是一级缓存,默认开启的,是SqlSession会话级别的缓存,所有sqlSession共享,在执行同一个sql语句时,如果缓存去没有数据,那么就回数据库查询,第二次来,发现缓存区有数据就直接从遗迹缓存中获取数据的,也就是说执行了一次sql语句,出现了两次结果。如果执行了insert、update、delete会清空一级缓存,避免出现脏读。[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection [org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 1426329391. [com.oracle.mapper.UserMapper.getOrdersByUid]-==> Preparing: select * from `user` where uid = ? [com.oracle.mapper.UserMapper.getOrdersByUid]-==> Parameters: 14(Integer) [com.oracle.mapper.UserMapper.getOrdersByUid]-<== Total: 1 User{uid=14, name='kakakaka', pwd='123123', address='12312312312'} User{uid=14, name='kakakaka', pwd='123123', address='12312312312'} 执行一次sql语句,出现两次结果
二级缓存:
二级缓存时namespace级别的,也就是mapper级别的缓存,多个mapper级别的缓存不共享,但是可以使用cache-ref namespace="公共空间"的这个标签让其共享,我们在开启二级缓存时,需要在全局配置文件中添加<settings> <!-- 开启二级缓存的全局开关 --> <setting name="cacheEnabled" value="true"/> <settings>
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
测试结果:
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection [org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 1256440269. [com.oracle.mapper.UserMapper.getOrdersByUid]-==> Preparing: select * from `user` where uid = ? [com.oracle.mapper.UserMapper.getOrdersByUid]-==> Parameters: 14(Integer) [com.oracle.mapper.UserMapper.getOrdersByUid]-<== Total: 1 User{uid=14, name='kakakaka', pwd='123123', address='12312312312'} [com.oracle.mapper.UserMapper]-Cache Hit Ratio [com.oracle.mapper.UserMapper]: 0.0 User{uid=14, name='kakakaka', pwd='123123', address='12312312312'}
总结:mybatis的缓存加载顺序是,二级缓存优先加载,如果没有在加载一级缓存,mybatis的缓存在分布式架构中不可用,容易出现脏读,实战中使用redis最好
-
Mybatis的逆向工程
<generatorConfiguration> <context id="testTables" targetRuntime="MyBatis3"> <!-- JavaBean 实现 序列化 接口 --> <plugin type="org.mybatis.generator.plugins.SerializablePlugin"> </plugin> <!-- genenat entity时,生成toString --> <plugin type="org.mybatis.generator.plugins.ToStringPlugin" /> <!-- 自定义物理分页 可生成支持Mysql数据的limit 不支持Oracle --> <plugin type="org.mybatis.generator.plugins.page.PaginationPlugin" /> <!-- 自定义查询指定字段 --> <plugin type="org.mybatis.generator.plugins.field.FieldsPlugin" /> <!-- 此处是将Example改名为Criteria 当然 想改成什么都行~ --> <plugin type="org.mybatis.generator.plugins.RenameExampleClassPlugin"> <property name="searchString" value="Example$" /> <!-- 替换后 <property name="replaceString" value="Criteria" /> --> <property name="replaceString" value="Query" /> </plugin> <!-- 此处是将UserMapper.xml改名为UserDao.xml 当然 想改成什么都行~ --> <plugin type="org.mybatis.generator.plugins.rename.RenameSqlMapperPlugin"> <property name="searchString" value="Mapper" /> <property name="replaceString" value="Mapper" /> </plugin> <!-- 此处是将UserMapper改名为UserDao 接口 当然 想改成什么都行~ --> <plugin type="org.mybatis.generator.plugins.rename.RenameJavaMapperPlugin"> <property name="searchString" value="Mapper$" /> <property name="replaceString" value="Mapper" /> </plugin> <commentGenerator type="org.mybatis.generator.plugins.comment.MyCommentGenerator"> <!-- 是否去除自动生成的注释 true:是 : false:否 <property name="suppressAllComments" value="true" /> --> </commentGenerator> <!--数据库连接的信息:驱动类、连接地址、用户名、密码 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root" password="root"> </jdbcConnection> <!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" userId="yycg" password="yycg"> </jdbcConnection> --> <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal --> <javaTypeResolver> <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!-- targetProject:生成POJO类的位置 --> <javaModelGenerator targetPackage="com.oracle.pojo" targetProject=".\src"> <!-- enableSubPackages:是否让schema作为包的后缀 --> <property name="enableSubPackages" value="false" /> <!-- 从数据库返回的值被清理前后的空格 --> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- targetProject:mapper映射文件生成的位置 --> <sqlMapGenerator targetPackage="com.oracle.mapper" targetProject=".\src"> <!-- enableSubPackages:是否让schema作为包的后缀 --> <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <!-- targetPackage:mapper接口生成的位置 --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.oracle.mapper" targetProject=".\src"> <!-- enableSubPackages:是否让schema作为包的后缀 --> <property name="enableSubPackages" value="true" /> </javaClientGenerator> <!-- 指定数据库表 --> <!-- 用户模块表 --> <table schema="" tableName="user" domainObjectName="User"> </table> <table schema="" tableName="card" domainObjectName="Card"/> <table schema="" tableName="order" domainObjectName="Order"/> <table schema="" tableName="product" domainObjectName="Product"/> </context> </generatorConfiguration>
service层:
public interface UserService { public User login(String username,String password); public void insertUser(User user); public void deleteUserById(Integer uid); public void deletesUsersByUid(int[] ids); public void updateUserByUid(User user); public List<User> getAll(); public List<User> getUserByLikeWithLimit(String like ,Integer paegNo,Integer pageSize); }
serviceImpl实现类:
public class UserServiceImpl implements UserService { @Override public User login(String username, String password) { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); UserQuery example = new UserQuery(); //参数赋值 Criteria c = example.createCriteria(); c.andUsernameEqualTo(username); c.andPasswordEqualTo(password); List<User> list = mapper.selectByExample(example); return list.get(0); } @Override public void insertUser(User user) { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int a = mapper.insertSelective(user); sqlSession.commit(); sqlSession.close(); } @Override public void deleteUserById(Integer uid) { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int a = mapper.deleteByPrimaryKey(uid); } @Override public void deletesUsersByUid(int[] ids) { } @Override public void updateUserByUid(User user) { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.updateByPrimaryKeySelective(user); } @Override public List<User> getAll() { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); UserQuery example = new UserQuery(); List<User> list = mapper.selectByExample(example); return list; } @Override public List<User> getUserByLikeWithLimit(String like, Integer pageNo, Integer pageSize) { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); UserQuery example = new UserQuery(); //赋值页码 和 页大小即可 example.setPageNo(pageNo); example.setPageSize(pageSize); //设置条件 Criteria c = example.createCriteria(); c.andUsernameLike("%" + like +"%"); List<User> list = mapper.selectByExample(example); return list; } }
单元测试:
public class TestUser { UserService userService = new UserServiceImpl(); @Test public void test7(){ String like = "呵"; Integer pageNo = 1; Integer pageSize = 5; List<User> list = userService.getUserByLikeWithLimit(like, pageNo, pageSize); for (User user : list) { System.out.println(user); } } @Test public void test6(){ List<User> list = userService.getAll(); for (User user : list) { System.out.println(user); } } @Test public void test5(){ User user =new User(); user.setUid(102); user.setAddress("小草屋"); userService.updateUserByUid(user); } @Test public void test4(){ userService.deleteUserById(15); } @Test public void test2(){ User user = new User(); user.setUsername("诸葛亮"); user.setPassword("111"); userService.insertUser(user); } @Test public void test1(){ User user = userService.login("关羽", "123"); System.out.println(user); } }